Merge pull request #1557 from ychin/mmtabs-vim-colorscheme-fixes

Tabs: Use TabLineFill fg, fix colorscheme w/ transparent/inverse highlights
This commit is contained in:
Yee Cheng Chin
2025-02-14 21:44:21 -08:00
committed by GitHub
8 changed files with 141 additions and 84 deletions
+3 -3
View File
@@ -4,7 +4,7 @@
" Maintainer: Maxim Kim <habamax@gmail.com>, ported from gruvbox8 of Lifepillar <lifepillar@lifepillar.me>
" Website: https://www.github.com/vim/colorschemes
" License: Vim License (see `:help license`)
" Last Change: 2025 Jan 07
" Last Change: 2025 Feb 15
" Generated by Colortemplate v2.2.3
@@ -150,7 +150,7 @@ else
hi StatusLine guifg=#bdae93 guibg=#3c3836 gui=bold,reverse cterm=bold,reverse
hi StatusLineNC guifg=#ebdbb2 guibg=#3c3836 gui=reverse cterm=reverse
hi TabLine guifg=#665c54 guibg=#ebdbb2 gui=NONE cterm=NONE
hi TabLineFill guifg=#ebdbb2 guibg=#ebdbb2 gui=NONE cterm=NONE
hi TabLineFill guifg=#3c3836 guibg=#ebdbb2 gui=NONE cterm=NONE
hi TabLineSel guifg=#282828 guibg=#fbf1c7 gui=bold cterm=bold
hi ToolbarButton guifg=#282828 guibg=#bdae93 gui=bold cterm=bold
hi ToolbarLine guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE
@@ -332,7 +332,7 @@ if s:t_Co >= 256
hi StatusLine ctermfg=144 ctermbg=237 cterm=bold,reverse
hi StatusLineNC ctermfg=187 ctermbg=237 cterm=reverse
hi TabLine ctermfg=59 ctermbg=187 cterm=NONE
hi TabLineFill ctermfg=187 ctermbg=187 cterm=NONE
hi TabLineFill ctermfg=237 ctermbg=187 cterm=NONE
hi TabLineSel ctermfg=235 ctermbg=230 cterm=bold
hi ToolbarButton ctermfg=235 ctermbg=144 cterm=bold
hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
+9 -7
View File
@@ -20,13 +20,15 @@
@property (nonatomic, readonly) NSInteger numberOfTabs;
@property (nonatomic, retain, readonly) MMHoverButton *addTabButton;
@property (nonatomic, retain) NSColor *tablineBgColor;
@property (nonatomic, retain) NSColor *tablineFgColor;
@property (nonatomic, retain) NSColor *tablineSelBgColor;
@property (nonatomic, retain) NSColor *tablineSelFgColor;
@property (nonatomic, retain) NSColor *tablineFillFgColor;
// Main colors
@property (nonatomic, readonly) NSColor *tablineBgColor;
@property (nonatomic, readonly) NSColor *tablineFgColor;
@property (nonatomic, readonly) NSColor *tablineSelBgColor;
@property (nonatomic, readonly) NSColor *tablineSelFgColor;
@property (nonatomic, readonly) NSColor *tablineFillBgColor;
@property (nonatomic, readonly) NSColor *tablineFillFgColor;
// Derived colors that cannot be set directly
// Derived colors from the main ones
@property (nonatomic, readonly) NSColor *tablineUnfocusedFgColor;
@property (nonatomic, readonly) NSColor *tablineUnfocusedSelFgColor;
@property (nonatomic, readonly) NSColor *tablineStrokeColor;
@@ -69,7 +71,7 @@
/// colors based on the system light/dark modes.
- (void)setColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
selBg:(NSColor *)selBg selFg:(NSColor *)selFg
fill:(NSColor *)fill;
fillBg:(NSColor *)fill fillFg:(NSColor *)fillFg;
/// Lets the tabline calculate best colors to use based on background and
/// foreground colors of the selected tab. The colors cannot be nil.
+12 -42
View File
@@ -67,7 +67,7 @@ static CGFloat calculateBrightness(NSColor *color) {
@synthesize tablineFgColor = _tablineFgColor;
@synthesize tablineSelBgColor = _tablineSelBgColor;
@synthesize tablineSelFgColor = _tablineSelFgColor;
@synthesize tablineFillFgColor = _tablineFillFgColor;
@synthesize tablineFillBgColor = _tablineFillBgColor;
@synthesize tablineUnfocusedFgColor = _tablineUnfocusedFgColor;
@synthesize tablineUnfocusedSelFgColor = _tablineUnfocusedSelFgColor;
@@ -150,7 +150,7 @@ static CGFloat calculateBrightness(NSColor *color) {
- (void)updateLayer
{
self.layer.backgroundColor = self.tablineFillFgColor.CGColor;
self.layer.backgroundColor = self.tablineFillBgColor.CGColor;
}
- (void)viewDidChangeEffectiveAppearance
@@ -253,24 +253,11 @@ static CGFloat calculateBrightness(NSColor *color) {
}
}
- (void)setTablineBgColor:(NSColor *)color
{
_tablineBgColor = color;
[self updateTabStates];
}
- (NSColor *)tablineFgColor
{
return _tablineFgColor ?: NSColor.secondaryLabelColor;
}
- (void)setTablineFgColor:(NSColor *)color
{
_tablineFgColor = color;
_tablineUnfocusedFgColor = nil;
[self updateTabStates];
}
- (NSColor *)tablineSelBgColor
{
return _tablineSelBgColor ?: (_appearance == AppearanceLight || _appearance == AppearanceLightHighContrast)
@@ -278,38 +265,21 @@ static CGFloat calculateBrightness(NSColor *color) {
: [NSColor colorWithWhite:0.4 alpha:1];
}
- (void)setTablineSelBgColor:(NSColor *)color
{
_tablineSelBgColor = color;
[self updateTabStates];
}
- (NSColor *)tablineSelFgColor
{
return _tablineSelFgColor ?: NSColor.controlTextColor;
}
- (void)setTablineSelFgColor:(NSColor *)color
- (NSColor *)tablineFillBgColor
{
_tablineSelFgColor = color;
_tablineUnfocusedSelFgColor = nil;
_addTabButton.fgColor = color;
_backwardScrollButton.fgColor = color;
_forwardScrollButton.fgColor = color;
[self updateTabStates];
}
- (NSColor *)tablineFillFgColor
{
return _tablineFillFgColor ?: (_appearance == AppearanceLight || _appearance == AppearanceLightHighContrast)
return _tablineFillBgColor ?: (_appearance == AppearanceLight || _appearance == AppearanceLightHighContrast)
? [NSColor colorWithWhite:0.85 alpha:1]
: [NSColor colorWithWhite:0.23 alpha:1];
}
- (void)setTablineFillFgColor:(NSColor *)color
- (NSColor *)tablineFillFgColor
{
_tablineFillFgColor = color;
self.needsDisplay = YES;
return _addTabButton.fgColor;
}
- (NSColor *)tablineUnfocusedFgColor
@@ -570,7 +540,7 @@ static CGFloat calculateBrightness(NSColor *color) {
- (void)setColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
selBg:(NSColor *)selBg selFg:(NSColor *)selFg
fill:(NSColor *)fill
fillBg:(NSColor *)fillBg fillFg:(NSColor *)fillFg
{
// Don't use the property mutators as we just want to update the states in
// one go at the end.
@@ -578,14 +548,14 @@ static CGFloat calculateBrightness(NSColor *color) {
_tablineSelFgColor = selFg;
_tablineBgColor = tabBg;
_tablineFgColor = tabFg;
_tablineFillFgColor = fill;
_tablineFillBgColor = fillBg;
_tablineUnfocusedFgColor = [_tablineFgColor blendedColorWithFraction:0.4 ofColor:_tablineBgColor];
_tablineUnfocusedSelFgColor = [_tablineSelFgColor blendedColorWithFraction:0.38 ofColor:_tablineSelBgColor];
_addTabButton.fgColor = _tablineSelFgColor;
_backwardScrollButton.fgColor = _tablineSelFgColor;
_forwardScrollButton.fgColor = _tablineSelFgColor;
_addTabButton.fgColor = fillFg;
_backwardScrollButton.fgColor = fillFg;
_forwardScrollButton.fgColor = fillFg;
[self updateTabStates];
self.needsDisplay = YES;
@@ -615,7 +585,7 @@ static CGFloat calculateBrightness(NSColor *color) {
_tablineUnfocusedFgColor = [_tablineFgColor blendedColorWithFraction:0.4 ofColor:_tablineBgColor];
_tablineUnfocusedSelFgColor = [_tablineSelFgColor blendedColorWithFraction:0.38 ofColor:_tablineSelBgColor];
_tablineFillFgColor = (brightness > 0.5)
_tablineFillBgColor = (brightness > 0.5)
? [back blendedColorWithFraction:0.25 ofColor:NSColor.blackColor]
: [back blendedColorWithFraction:0.18 ofColor:NSColor.whiteColor];
+22 -11
View File
@@ -40,7 +40,8 @@ typedef enum: NSInteger {
MMTabColorTypeTabFg,
MMTabColorTypeSelBg,
MMTabColorTypeSelFg,
MMTabColorTypeFill,
MMTabColorTypeFillBg,
MMTabColorTypeFillFg,
MMTabColorTypeCount
} MMTabColorType;
@@ -377,7 +378,7 @@ typedef enum: NSInteger {
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
tabline.showsTabScrollButtons = [ud boolForKey:MMShowTabScrollButtonsKey];
[self updateTablineColors];
[self updateTablineColors:MMTabColorsModeCount];
}
- (void)createScrollbarWithIdentifier:(int32_t)ident type:(int)type
@@ -469,25 +470,35 @@ typedef enum: NSInteger {
}
}
- (void)updateTablineColors
- (void)updateTablineColors:(MMTabColorsMode)mode
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
MMTabColorsMode tabColorsMode = [ud integerForKey:MMTabColorsModeKey];
if (tabColorsMode >= MMTabColorsModeCount || tabColorsMode < 0) {
// Catch-all for invalid values, which could be useful if we add new
// modes and a user goes back and uses an old version of MacVim.
tabColorsMode = MMTabColorsModeAutomatic;
}
if (mode != MMTabColorsModeCount && mode != tabColorsMode) {
// Early out to avoid unnecessary updates if this is not relevant.
return;
}
if (tabColorsMode == MMTabColorsModeDefaultColors) {
[tabline setColorsTabBg:nil
tabFg:nil
selBg:nil
selFg:nil
fill:nil];
fillBg:nil
fillFg:nil];
} else if (tabColorsMode == MMTabColorsModeVimColorscheme) {
[tabline setColorsTabBg:tabColors[MMTabColorTypeTabBg]
tabFg:tabColors[MMTabColorTypeTabFg]
selBg:tabColors[MMTabColorTypeSelBg]
selFg:tabColors[MMTabColorTypeSelFg]
fill:tabColors[MMTabColorTypeFill]];
fillBg:tabColors[MMTabColorTypeFillBg]
fillFg:tabColors[MMTabColorTypeFillFg]];
} else {
// tabColorsMode == MMTabColorsModeAutomatic, but catch-all in case it's
// set to an out-of-range number.
// tabColorsMode == MMTabColorsModeAutomatic
NSColor *back = [[self textView] defaultBackgroundColor];
NSColor *fore = [[self textView] defaultForegroundColor];
[tabline setAutoColorsSelBg:back fg:fore];
@@ -498,7 +509,7 @@ typedef enum: NSInteger {
- (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore
{
[textView setDefaultColorsBackground:back foreground:fore];
[self updateTablineColors];
[self updateTablineColors:MMTabColorsModeAutomatic];
CALayer *backedLayer = [self layer];
if (backedLayer) {
@@ -527,9 +538,9 @@ typedef enum: NSInteger {
tabColors[MMTabColorTypeTabFg] = [tabFg retain];
tabColors[MMTabColorTypeSelBg] = [selBg retain];
tabColors[MMTabColorTypeSelFg] = [selFg retain];
tabColors[MMTabColorTypeFill] = [fillBg retain];
(void)fillFg; // We don't use fillFg as we don't draw anything in the empty area
[self updateTablineColors];
tabColors[MMTabColorTypeFillBg] = [fillBg retain];
tabColors[MMTabColorTypeFillFg] = [fillFg retain];
[self updateTablineColors:MMTabColorsModeVimColorscheme];
}
+1 -1
View File
@@ -743,7 +743,7 @@
- (void)setWindowColorToTablineColor
{
NSColor *defaultBg = vimView.textView.defaultBackgroundColor;
NSColor *tablineColor = vimView.tabline.tablineFillFgColor;
NSColor *tablineColor = vimView.tabline.tablineFillBgColor;
if (defaultBg.alphaComponent == 1.0) {
[self setWindowBackgroundColor:tablineColor];
} else {
+61
View File
@@ -33,6 +33,10 @@
- (void)handleMessage:(int)msgid data:(NSData *)data;
@end
@interface MMVimView (Tests)
- (void)updateTablineColors:(MMTabColorsMode)mode;
@end
// Test harness
@implementation MMAppController (Tests)
- (NSMutableArray*)vimControllers {
@@ -954,6 +958,63 @@ do { \
XCTAssertFalse(win.isRenderBlocked);
}
#pragma mark Tabs tests
- (void)testTabColors {
[self createTestVimWindow];
MMAppController *app = MMAppController.sharedInstance;
MMVimView *vimView = [[[app keyVimController] windowController] vimView];
MMTabline *tabline = [vimView tabline];
// Test Vim colorscheme mode
[self setDefault:MMTabColorsModeKey toValue:@(MMTabColorsModeVimColorscheme)];
[self sendStringToVim:@":hi Normal guifg=#ff0000 guibg=#00ff00\n" withMods:0];
[self waitForVimProcess];
[self sendStringToVim:@":hi TabLineSel guifg=#010203 guibg=#040506\n" withMods:0];
[self sendStringToVim:@":hi clear TabLineFill\n" withMods:0];
[self sendStringToVim:@":hi TabLine guifg=#111213 guibg=NONE gui=inverse\n" withMods:0];
[self waitForEventHandlingAndVimProcess];
// Normal highlight groups
XCTAssertEqualObjects(tabline.tablineSelBgColor, [NSColor colorWithRgbInt:0x040506]);
XCTAssertEqualObjects(tabline.tablineSelFgColor, [NSColor colorWithRgbInt:0x010203]);
// Cleared highlight group should be transparent and fall through to Normal group
XCTAssertEqualObjects(tabline.tablineFillBgColor, [NSColor colorWithRgbInt:0x00ff00]);
XCTAssertEqualObjects(tabline.tablineFillFgColor, [NSColor colorWithRgbInt:0xff0000]);
// One color is transparent, and inversed fg/bg
XCTAssertEqualObjects(tabline.tablineBgColor, [NSColor colorWithRgbInt:0x111213]);
XCTAssertEqualObjects(tabline.tablineFgColor, [NSColor colorWithRgbInt:0x00ff00]);
// Cleared highlight group with inversed fg/bg
[self sendStringToVim:@":hi TabLineFill gui=inverse\n" withMods:0];
[self waitForEventHandlingAndVimProcess];
XCTAssertEqualObjects(tabline.tablineFillBgColor, [NSColor colorWithRgbInt:0xff0000]);
XCTAssertEqualObjects(tabline.tablineFillFgColor, [NSColor colorWithRgbInt:0x00ff00]);
// Test automatic colors mode
// Selected tab should have the exact same background as Normal colors
[self setDefault:MMTabColorsModeKey toValue:@(MMTabColorsModeAutomatic)];
[vimView updateTablineColors:MMTabColorsModeAutomatic];
XCTAssertEqualObjects(tabline.tablineSelBgColor, [NSColor colorWithRgbInt:0x00ff00]);
// Test default colors mode
// We just verify that the colors changed, rather than asserting the exact
// colors to make it easy to update tuning on them in the future.
[self setDefault:MMTabColorsModeKey toValue:@(MMTabColorsModeDefaultColors)];
[vimView updateTablineColors:MMTabColorsModeDefaultColors];
vimView.window.appearance = [NSAppearance appearanceNamed: NSAppearanceNameAqua];
[self waitForEventHandling];
XCTAssertEqual(tabline.tablineFillBgColor.colorSpace.colorSpaceModel, NSColorSpaceModelGray);
XCTAssertGreaterThan(tabline.tablineFillBgColor.whiteComponent, 0.5);
vimView.window.appearance = [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua];
[self waitForEventHandling];
XCTAssertLessThan(tabline.tablineFillBgColor.whiteComponent, 0.5);
}
#pragma mark Full screen tests
- (void)waitForNativeFullscreenEnter {
+1
View File
@@ -110,6 +110,7 @@ typedef enum : NSInteger {
MMTabColorsModeDefaultColors = 0, ///< Use default colors based on macOS light/dark modes
MMTabColorsModeAutomatic, ///< Automatically derive tab colors based on foreground/background colors
MMTabColorsModeVimColorscheme, ///< Use Vim colorscheme TabLine/TabLineSel/TabLineFill colors
MMTabColorsModeCount
} MMTabColorsMode;
enum {
+32 -20
View File
@@ -656,32 +656,44 @@ gui_mch_update_highlight(void)
gui_mch_fuopt_update();
// Update the GUI with tab colors
// We can cache the tabline syn IDs because they will never change.
static int tablineSynIds[3] = { 0 };
char *tablineSynNames[3] = {"TabLine", "TabLineFill", "TabLineSel"};
BOOL hasTablineColors = YES;
// Highlight attributes for TabLine, TabLineFill, TabLineSel
const int attrs[3] = { HL_ATTR(HLF_TP), HL_ATTR(HLF_TPF), HL_ATTR(HLF_TPS) };
int tablineColors[6] = { 0 };
for (int i = 0; i < 3; i++) {
if (tablineSynIds[i] <= 0)
tablineSynIds[i] = syn_name2id((char_u *)tablineSynNames[i]);
if (tablineSynIds[i] > 0) {
guicolor_T bg, fg;
syn_id2colors(tablineSynIds[i], &fg, &bg);
tablineColors[i*2] = (int)bg;
tablineColors[i*2+1] = (int)fg;
guicolor_T bg = INVALCOLOR, fg = INVALCOLOR;
BOOL reverse = NO;
if (attrs[i] > HL_ALL) {
attrentry_T *aep = syn_gui_attr2entry(attrs[i]);
if (aep != NULL) {
bg = aep->ae_u.gui.bg_color;
fg = aep->ae_u.gui.fg_color;
reverse = (aep->ae_attr & HL_INVERSE) != 0;
}
} else {
hasTablineColors = NO;
reverse = (attrs[i] & HL_INVERSE) != 0;
}
if (bg == INVALCOLOR)
bg = gui.def_back_pixel;
if (fg == INVALCOLOR)
fg = gui.def_norm_pixel;
if (reverse) {
guicolor_T temp = fg;
fg = bg;
bg = temp;
}
tablineColors[i*2] = (int)bg;
tablineColors[i*2+1] = (int)fg;
}
if (hasTablineColors) {
// Cache the old colors just so we don't spam the IPC channel if the
// colors didn't actually change.
static int oldTablineColors[6] = { 0 };
if (memcmp(oldTablineColors, tablineColors, sizeof(oldTablineColors)) != 0) {
memcpy(oldTablineColors, tablineColors, sizeof(oldTablineColors));
[[MMBackend sharedInstance] setTablineColors:tablineColors];
}
// Cache the old colors just so we don't spam the IPC channel if the
// colors didn't actually change.
static int oldTablineColors[6] = { 0 };
if (memcmp(oldTablineColors, tablineColors, sizeof(oldTablineColors)) != 0) {
memcpy(oldTablineColors, tablineColors, sizeof(oldTablineColors));
[[MMBackend sharedInstance] setTablineColors:tablineColors];
}
}