diff --git a/runtime/colors/retrobox.vim b/runtime/colors/retrobox.vim index e848d5aabb..9042f00604 100644 --- a/runtime/colors/retrobox.vim +++ b/runtime/colors/retrobox.vim @@ -4,7 +4,7 @@ " Maintainer: Maxim Kim , ported from gruvbox8 of Lifepillar " 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 diff --git a/src/MacVim/MMTabline/MMTabline.h b/src/MacVim/MMTabline/MMTabline.h index 98bef13bdf..250f034fbd 100644 --- a/src/MacVim/MMTabline/MMTabline.h +++ b/src/MacVim/MMTabline/MMTabline.h @@ -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; - -// Derived colors that cannot be set directly +// 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 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. diff --git a/src/MacVim/MMTabline/MMTabline.m b/src/MacVim/MMTabline/MMTabline.m index 605aa6b1f4..5935933e02 100644 --- a/src/MacVim/MMTabline/MMTabline.m +++ b/src/MacVim/MMTabline/MMTabline.m @@ -67,7 +67,7 @@ @implementation MMTabline @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 @@ - (BOOL)wantsUpdateLayer { return YES; } - (void)updateLayer { - self.layer.backgroundColor = self.tablineFillFgColor.CGColor; + self.layer.backgroundColor = self.tablineFillBgColor.CGColor; } - (void)viewDidChangeEffectiveAppearance @@ -253,24 +253,11 @@ - (NSColor *)tablineBgColor } } -- (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 @@ - (NSColor *)tablineSelBgColor : [NSColor colorWithWhite:0.4 alpha:1]; } -- (void)setTablineSelBgColor:(NSColor *)color -{ - _tablineSelBgColor = color; - [self updateTabStates]; -} - - (NSColor *)tablineSelFgColor { return _tablineSelFgColor ?: NSColor.controlTextColor; } -- (void)setTablineSelFgColor:(NSColor *)color -{ - _tablineSelFgColor = color; - _tablineUnfocusedSelFgColor = nil; - _addTabButton.fgColor = color; - _backwardScrollButton.fgColor = color; - _forwardScrollButton.fgColor = color; - [self updateTabStates]; -} - -- (NSColor *)tablineFillFgColor +- (NSColor *)tablineFillBgColor { - 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 @@ - (MMTab *)tabAtIndex:(NSInteger)index - (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 @@ - (void)setColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg _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 @@ - (void)setAutoColorsSelBg:(NSColor *)back fg:(NSColor *)fore; _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]; diff --git a/src/MacVim/MMVimView.m b/src/MacVim/MMVimView.m index c9840471ed..6f8f4a3ded 100644 --- a/src/MacVim/MMVimView.m +++ b/src/MacVim/MMVimView.m @@ -40,7 +40,8 @@ MMTabColorTypeTabFg, MMTabColorTypeSelBg, MMTabColorTypeSelFg, - MMTabColorTypeFill, + MMTabColorTypeFillBg, + MMTabColorTypeFillFg, MMTabColorTypeCount } MMTabColorType; @@ -377,7 +378,7 @@ - (void)refreshTabProperties { 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 @@ - (void)finishPlaceScrollbars } } -- (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 @@ - (void)updateTablineColors - (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 @@ - (void)setTablineColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg 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]; } diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m index c6cb16605f..d8faf9e75f 100644 --- a/src/MacVim/MMWindowController.m +++ b/src/MacVim/MMWindowController.m @@ -743,7 +743,7 @@ - (void)setTablineColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg - (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 { diff --git a/src/MacVim/MacVimTests/MacVimTests.m b/src/MacVim/MacVimTests/MacVimTests.m index dca00c29f1..c7c371e527 100644 --- a/src/MacVim/MacVimTests/MacVimTests.m +++ b/src/MacVim/MacVimTests/MacVimTests.m @@ -33,6 +33,10 @@ @interface MMVimController (Private) - (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 @@ - (void) testResizeVimView { 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 { diff --git a/src/MacVim/Miscellaneous.h b/src/MacVim/Miscellaneous.h index a247b3f647..d36d2f1f4a 100644 --- a/src/MacVim/Miscellaneous.h +++ b/src/MacVim/Miscellaneous.h @@ -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 { diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m index 2526f37b64..d1d04514f5 100644 --- a/src/MacVim/gui_macvim.m +++ b/src/MacVim/gui_macvim.m @@ -656,32 +656,44 @@ 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 (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]; + + 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; + } + // 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]; } }