Skip to content

Commit b5f102b

Browse files
committed
MMTabs: Use TabLineFill fg, fix colorscheme w/ transparent/inverse highlights
When using Vim colorscheme mode, fix the fill foreground colors (used for add tab and scroll buttons) to use the colorscheme's TabLineFill's guifg colors. Previously they were automatically calculated based on the other foreground colors which worked for automatic colors but not when we are using a colorscheme where it may not match. Just use the one specified in color scheme. Colorschemes like everforest and koehler should have visible buttons now. Also, fix the previous broken logic for parsing the colorscheme colors. It was not accounting for transparent colors where missing colors or cleared highlight groups should fall through to default bg/fg colors (e.g. delek and catppuccin do this for TabLineSel). It also wasn't respecting the `gui=reverse` flag (which means bg/fg colors should be flipped) that some colorschemes (e.g. Solarized) uses.
1 parent 961c252 commit b5f102b

File tree

7 files changed

+139
-82
lines changed

7 files changed

+139
-82
lines changed

src/MacVim/MMTabline/MMTabline.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
@property (nonatomic, readonly) NSInteger numberOfTabs;
2121
@property (nonatomic, retain, readonly) MMHoverButton *addTabButton;
2222

23-
@property (nonatomic, retain) NSColor *tablineBgColor;
24-
@property (nonatomic, retain) NSColor *tablineFgColor;
25-
@property (nonatomic, retain) NSColor *tablineSelBgColor;
26-
@property (nonatomic, retain) NSColor *tablineSelFgColor;
27-
@property (nonatomic, retain) NSColor *tablineFillFgColor;
28-
29-
// Derived colors that cannot be set directly
23+
// Main colors
24+
@property (nonatomic, readonly) NSColor *tablineBgColor;
25+
@property (nonatomic, readonly) NSColor *tablineFgColor;
26+
@property (nonatomic, readonly) NSColor *tablineSelBgColor;
27+
@property (nonatomic, readonly) NSColor *tablineSelFgColor;
28+
@property (nonatomic, readonly) NSColor *tablineFillBgColor;
29+
@property (nonatomic, readonly) NSColor *tablineFillFgColor;
30+
31+
// Derived colors from the main ones
3032
@property (nonatomic, readonly) NSColor *tablineUnfocusedFgColor;
3133
@property (nonatomic, readonly) NSColor *tablineUnfocusedSelFgColor;
3234
@property (nonatomic, readonly) NSColor *tablineStrokeColor;
@@ -69,7 +71,7 @@
6971
/// colors based on the system light/dark modes.
7072
- (void)setColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
7173
selBg:(NSColor *)selBg selFg:(NSColor *)selFg
72-
fill:(NSColor *)fill;
74+
fillBg:(NSColor *)fill fillFg:(NSColor *)fillFg;
7375

7476
/// Lets the tabline calculate best colors to use based on background and
7577
/// foreground colors of the selected tab. The colors cannot be nil.

src/MacVim/MMTabline/MMTabline.m

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ @implementation MMTabline
6767
@synthesize tablineFgColor = _tablineFgColor;
6868
@synthesize tablineSelBgColor = _tablineSelBgColor;
6969
@synthesize tablineSelFgColor = _tablineSelFgColor;
70-
@synthesize tablineFillFgColor = _tablineFillFgColor;
70+
@synthesize tablineFillBgColor = _tablineFillBgColor;
7171
@synthesize tablineUnfocusedFgColor = _tablineUnfocusedFgColor;
7272
@synthesize tablineUnfocusedSelFgColor = _tablineUnfocusedSelFgColor;
7373

@@ -150,7 +150,7 @@ - (BOOL)wantsUpdateLayer { return YES; }
150150

151151
- (void)updateLayer
152152
{
153-
self.layer.backgroundColor = self.tablineFillFgColor.CGColor;
153+
self.layer.backgroundColor = self.tablineFillBgColor.CGColor;
154154
}
155155

156156
- (void)viewDidChangeEffectiveAppearance
@@ -253,63 +253,33 @@ - (NSColor *)tablineBgColor
253253
}
254254
}
255255

256-
- (void)setTablineBgColor:(NSColor *)color
257-
{
258-
_tablineBgColor = color;
259-
[self updateTabStates];
260-
}
261-
262256
- (NSColor *)tablineFgColor
263257
{
264258
return _tablineFgColor ?: NSColor.secondaryLabelColor;
265259
}
266260

267-
- (void)setTablineFgColor:(NSColor *)color
268-
{
269-
_tablineFgColor = color;
270-
_tablineUnfocusedFgColor = nil;
271-
[self updateTabStates];
272-
}
273-
274261
- (NSColor *)tablineSelBgColor
275262
{
276263
return _tablineSelBgColor ?: (_appearance == AppearanceLight || _appearance == AppearanceLightHighContrast)
277264
? [NSColor colorWithWhite:0.95 alpha:1]
278265
: [NSColor colorWithWhite:0.4 alpha:1];
279266
}
280267

281-
- (void)setTablineSelBgColor:(NSColor *)color
282-
{
283-
_tablineSelBgColor = color;
284-
[self updateTabStates];
285-
}
286-
287268
- (NSColor *)tablineSelFgColor
288269
{
289270
return _tablineSelFgColor ?: NSColor.controlTextColor;
290271
}
291272

292-
- (void)setTablineSelFgColor:(NSColor *)color
293-
{
294-
_tablineSelFgColor = color;
295-
_tablineUnfocusedSelFgColor = nil;
296-
_addTabButton.fgColor = color;
297-
_backwardScrollButton.fgColor = color;
298-
_forwardScrollButton.fgColor = color;
299-
[self updateTabStates];
300-
}
301-
302-
- (NSColor *)tablineFillFgColor
273+
- (NSColor *)tablineFillBgColor
303274
{
304-
return _tablineFillFgColor ?: (_appearance == AppearanceLight || _appearance == AppearanceLightHighContrast)
275+
return _tablineFillBgColor ?: (_appearance == AppearanceLight || _appearance == AppearanceLightHighContrast)
305276
? [NSColor colorWithWhite:0.85 alpha:1]
306277
: [NSColor colorWithWhite:0.23 alpha:1];
307278
}
308279

309-
- (void)setTablineFillFgColor:(NSColor *)color
280+
- (NSColor *)tablineFillFgColor
310281
{
311-
_tablineFillFgColor = color;
312-
self.needsDisplay = YES;
282+
return _addTabButton.fgColor;
313283
}
314284

315285
- (NSColor *)tablineUnfocusedFgColor
@@ -570,22 +540,22 @@ - (MMTab *)tabAtIndex:(NSInteger)index
570540

571541
- (void)setColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
572542
selBg:(NSColor *)selBg selFg:(NSColor *)selFg
573-
fill:(NSColor *)fill
543+
fillBg:(NSColor *)fillBg fillFg:(NSColor *)fillFg
574544
{
575545
// Don't use the property mutators as we just want to update the states in
576546
// one go at the end.
577547
_tablineSelBgColor = selBg;
578548
_tablineSelFgColor = selFg;
579549
_tablineBgColor = tabBg;
580550
_tablineFgColor = tabFg;
581-
_tablineFillFgColor = fill;
551+
_tablineFillBgColor = fillBg;
582552

583553
_tablineUnfocusedFgColor = [_tablineFgColor blendedColorWithFraction:0.4 ofColor:_tablineBgColor];
584554
_tablineUnfocusedSelFgColor = [_tablineSelFgColor blendedColorWithFraction:0.38 ofColor:_tablineSelBgColor];
585555

586-
_addTabButton.fgColor = _tablineSelFgColor;
587-
_backwardScrollButton.fgColor = _tablineSelFgColor;
588-
_forwardScrollButton.fgColor = _tablineSelFgColor;
556+
_addTabButton.fgColor = fillFg;
557+
_backwardScrollButton.fgColor = fillFg;
558+
_forwardScrollButton.fgColor = fillFg;
589559

590560
[self updateTabStates];
591561
self.needsDisplay = YES;
@@ -615,7 +585,7 @@ - (void)setAutoColorsSelBg:(NSColor *)back fg:(NSColor *)fore;
615585
_tablineUnfocusedFgColor = [_tablineFgColor blendedColorWithFraction:0.4 ofColor:_tablineBgColor];
616586
_tablineUnfocusedSelFgColor = [_tablineSelFgColor blendedColorWithFraction:0.38 ofColor:_tablineSelBgColor];
617587

618-
_tablineFillFgColor = (brightness > 0.5)
588+
_tablineFillBgColor = (brightness > 0.5)
619589
? [back blendedColorWithFraction:0.25 ofColor:NSColor.blackColor]
620590
: [back blendedColorWithFraction:0.18 ofColor:NSColor.whiteColor];
621591

src/MacVim/MMVimView.m

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
MMTabColorTypeTabFg,
4141
MMTabColorTypeSelBg,
4242
MMTabColorTypeSelFg,
43-
MMTabColorTypeFill,
43+
MMTabColorTypeFillBg,
44+
MMTabColorTypeFillFg,
4445
MMTabColorTypeCount
4546
} MMTabColorType;
4647

@@ -377,7 +378,7 @@ - (void)refreshTabProperties
377378
{
378379
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
379380
tabline.showsTabScrollButtons = [ud boolForKey:MMShowTabScrollButtonsKey];
380-
[self updateTablineColors];
381+
[self updateTablineColors:MMTabColorsModeCount];
381382
}
382383

383384
- (void)createScrollbarWithIdentifier:(int32_t)ident type:(int)type
@@ -469,25 +470,35 @@ - (void)finishPlaceScrollbars
469470
}
470471
}
471472

472-
- (void)updateTablineColors
473+
- (void)updateTablineColors:(MMTabColorsMode)mode
473474
{
474475
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
475476
MMTabColorsMode tabColorsMode = [ud integerForKey:MMTabColorsModeKey];
477+
if (tabColorsMode >= MMTabColorsModeCount || tabColorsMode < 0) {
478+
// Catch-all for invalid values, which could be useful if we add new
479+
// modes and a user goes back and uses an old version of MacVim.
480+
tabColorsMode = MMTabColorsModeAutomatic;
481+
}
482+
if (mode != MMTabColorsModeCount && mode != tabColorsMode) {
483+
// Early out to avoid unnecessary updates if this is not relevant.
484+
return;
485+
}
476486
if (tabColorsMode == MMTabColorsModeDefaultColors) {
477487
[tabline setColorsTabBg:nil
478488
tabFg:nil
479489
selBg:nil
480490
selFg:nil
481-
fill:nil];
491+
fillBg:nil
492+
fillFg:nil];
482493
} else if (tabColorsMode == MMTabColorsModeVimColorscheme) {
483494
[tabline setColorsTabBg:tabColors[MMTabColorTypeTabBg]
484495
tabFg:tabColors[MMTabColorTypeTabFg]
485496
selBg:tabColors[MMTabColorTypeSelBg]
486497
selFg:tabColors[MMTabColorTypeSelFg]
487-
fill:tabColors[MMTabColorTypeFill]];
498+
fillBg:tabColors[MMTabColorTypeFillBg]
499+
fillFg:tabColors[MMTabColorTypeFillFg]];
488500
} else {
489-
// tabColorsMode == MMTabColorsModeAutomatic, but catch-all in case it's
490-
// set to an out-of-range number.
501+
// tabColorsMode == MMTabColorsModeAutomatic
491502
NSColor *back = [[self textView] defaultBackgroundColor];
492503
NSColor *fore = [[self textView] defaultForegroundColor];
493504
[tabline setAutoColorsSelBg:back fg:fore];
@@ -498,7 +509,7 @@ - (void)updateTablineColors
498509
- (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore
499510
{
500511
[textView setDefaultColorsBackground:back foreground:fore];
501-
[self updateTablineColors];
512+
[self updateTablineColors:MMTabColorsModeAutomatic];
502513

503514
CALayer *backedLayer = [self layer];
504515
if (backedLayer) {
@@ -527,9 +538,9 @@ - (void)setTablineColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
527538
tabColors[MMTabColorTypeTabFg] = [tabFg retain];
528539
tabColors[MMTabColorTypeSelBg] = [selBg retain];
529540
tabColors[MMTabColorTypeSelFg] = [selFg retain];
530-
tabColors[MMTabColorTypeFill] = [fillBg retain];
531-
(void)fillFg; // We don't use fillFg as we don't draw anything in the empty area
532-
[self updateTablineColors];
541+
tabColors[MMTabColorTypeFillBg] = [fillBg retain];
542+
tabColors[MMTabColorTypeFillFg] = [fillFg retain];
543+
[self updateTablineColors:MMTabColorsModeVimColorscheme];
533544
}
534545

535546

src/MacVim/MMWindowController.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ - (void)setTablineColorsTabBg:(NSColor *)tabBg tabFg:(NSColor *)tabFg
743743
- (void)setWindowColorToTablineColor
744744
{
745745
NSColor *defaultBg = vimView.textView.defaultBackgroundColor;
746-
NSColor *tablineColor = vimView.tabline.tablineFillFgColor;
746+
NSColor *tablineColor = vimView.tabline.tablineFillBgColor;
747747
if (defaultBg.alphaComponent == 1.0) {
748748
[self setWindowBackgroundColor:tablineColor];
749749
} else {

src/MacVim/MacVimTests/MacVimTests.m

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ @interface MMVimController (Private)
3333
- (void)handleMessage:(int)msgid data:(NSData *)data;
3434
@end
3535

36+
@interface MMVimView (Tests)
37+
- (void)updateTablineColors:(MMTabColorsMode)mode;
38+
@end
39+
3640
// Test harness
3741
@implementation MMAppController (Tests)
3842
- (NSMutableArray*)vimControllers {
@@ -954,6 +958,63 @@ - (void) testResizeVimView {
954958
XCTAssertFalse(win.isRenderBlocked);
955959
}
956960

961+
#pragma mark Tabs tests
962+
963+
- (void)testTabColors {
964+
[self createTestVimWindow];
965+
966+
MMAppController *app = MMAppController.sharedInstance;
967+
MMVimView *vimView = [[[app keyVimController] windowController] vimView];
968+
MMTabline *tabline = [vimView tabline];
969+
970+
// Test Vim colorscheme mode
971+
[self setDefault:MMTabColorsModeKey toValue:@(MMTabColorsModeVimColorscheme)];
972+
973+
[self sendStringToVim:@":hi Normal guifg=#ff0000 guibg=#00ff00\n" withMods:0];
974+
[self waitForVimProcess];
975+
[self sendStringToVim:@":hi TabLineSel guifg=#010203 guibg=#040506\n" withMods:0];
976+
[self sendStringToVim:@":hi clear TabLineFill\n" withMods:0];
977+
[self sendStringToVim:@":hi TabLine guifg=#111213 guibg=NONE gui=inverse\n" withMods:0];
978+
[self waitForEventHandlingAndVimProcess];
979+
980+
// Normal highlight groups
981+
XCTAssertEqualObjects(tabline.tablineSelBgColor, [NSColor colorWithRgbInt:0x040506]);
982+
XCTAssertEqualObjects(tabline.tablineSelFgColor, [NSColor colorWithRgbInt:0x010203]);
983+
// Cleared highlight group should be transparent and fall through to Normal group
984+
XCTAssertEqualObjects(tabline.tablineFillBgColor, [NSColor colorWithRgbInt:0x00ff00]);
985+
XCTAssertEqualObjects(tabline.tablineFillFgColor, [NSColor colorWithRgbInt:0xff0000]);
986+
// One color is transparent, and inversed fg/bg
987+
XCTAssertEqualObjects(tabline.tablineBgColor, [NSColor colorWithRgbInt:0x111213]);
988+
XCTAssertEqualObjects(tabline.tablineFgColor, [NSColor colorWithRgbInt:0x00ff00]);
989+
990+
// Cleared highlight group with inversed fg/bg
991+
[self sendStringToVim:@":hi TabLineFill gui=inverse\n" withMods:0];
992+
[self waitForEventHandlingAndVimProcess];
993+
XCTAssertEqualObjects(tabline.tablineFillBgColor, [NSColor colorWithRgbInt:0xff0000]);
994+
XCTAssertEqualObjects(tabline.tablineFillFgColor, [NSColor colorWithRgbInt:0x00ff00]);
995+
996+
// Test automatic colors mode
997+
// Selected tab should have the exact same background as Normal colors
998+
[self setDefault:MMTabColorsModeKey toValue:@(MMTabColorsModeAutomatic)];
999+
[vimView updateTablineColors:MMTabColorsModeAutomatic];
1000+
XCTAssertEqualObjects(tabline.tablineSelBgColor, [NSColor colorWithRgbInt:0x00ff00]);
1001+
1002+
// Test default colors mode
1003+
// We just verify that the colors changed, rather than asserting the exact
1004+
// colors to make it easy to update tuning on them in the future.
1005+
[self setDefault:MMTabColorsModeKey toValue:@(MMTabColorsModeDefaultColors)];
1006+
[vimView updateTablineColors:MMTabColorsModeDefaultColors];
1007+
1008+
vimView.window.appearance = [NSAppearance appearanceNamed: NSAppearanceNameAqua];
1009+
[self waitForEventHandling];
1010+
XCTAssertEqual(tabline.tablineFillBgColor.colorSpace.colorSpaceModel, NSColorSpaceModelGray);
1011+
XCTAssertGreaterThan(tabline.tablineFillBgColor.whiteComponent, 0.5);
1012+
1013+
vimView.window.appearance = [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua];
1014+
[self waitForEventHandling];
1015+
XCTAssertLessThan(tabline.tablineFillBgColor.whiteComponent, 0.5);
1016+
}
1017+
9571018
#pragma mark Full screen tests
9581019

9591020
- (void)waitForNativeFullscreenEnter {

src/MacVim/Miscellaneous.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ typedef enum : NSInteger {
110110
MMTabColorsModeDefaultColors = 0, ///< Use default colors based on macOS light/dark modes
111111
MMTabColorsModeAutomatic, ///< Automatically derive tab colors based on foreground/background colors
112112
MMTabColorsModeVimColorscheme, ///< Use Vim colorscheme TabLine/TabLineSel/TabLineFill colors
113+
MMTabColorsModeCount
113114
} MMTabColorsMode;
114115

115116
enum {

src/MacVim/gui_macvim.m

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -656,32 +656,44 @@
656656
gui_mch_fuopt_update();
657657

658658
// Update the GUI with tab colors
659-
// We can cache the tabline syn IDs because they will never change.
660-
static int tablineSynIds[3] = { 0 };
661-
char *tablineSynNames[3] = {"TabLine", "TabLineFill", "TabLineSel"};
662659

663-
BOOL hasTablineColors = YES;
660+
// Highlight attributes for TabLine, TabLineFill, TabLineSel
661+
const int attrs[3] = { HL_ATTR(HLF_TP), HL_ATTR(HLF_TPF), HL_ATTR(HLF_TPS) };
662+
664663
int tablineColors[6] = { 0 };
665664
for (int i = 0; i < 3; i++) {
666-
if (tablineSynIds[i] <= 0)
667-
tablineSynIds[i] = syn_name2id((char_u *)tablineSynNames[i]);
668-
if (tablineSynIds[i] > 0) {
669-
guicolor_T bg, fg;
670-
syn_id2colors(tablineSynIds[i], &fg, &bg);
671-
tablineColors[i*2] = (int)bg;
672-
tablineColors[i*2+1] = (int)fg;
665+
guicolor_T bg = INVALCOLOR, fg = INVALCOLOR;
666+
BOOL reverse = NO;
667+
if (attrs[i] > HL_ALL) {
668+
attrentry_T *aep = syn_gui_attr2entry(attrs[i]);
669+
if (aep != NULL) {
670+
bg = aep->ae_u.gui.bg_color;
671+
fg = aep->ae_u.gui.fg_color;
672+
reverse = (aep->ae_attr & HL_INVERSE) != 0;
673+
}
673674
} else {
674-
hasTablineColors = NO;
675+
reverse = (attrs[i] & HL_INVERSE) != 0;
675676
}
676-
}
677-
if (hasTablineColors) {
678-
// Cache the old colors just so we don't spam the IPC channel if the
679-
// colors didn't actually change.
680-
static int oldTablineColors[6] = { 0 };
681-
if (memcmp(oldTablineColors, tablineColors, sizeof(oldTablineColors)) != 0) {
682-
memcpy(oldTablineColors, tablineColors, sizeof(oldTablineColors));
683-
[[MMBackend sharedInstance] setTablineColors:tablineColors];
677+
678+
if (bg == INVALCOLOR)
679+
bg = gui.def_back_pixel;
680+
if (fg == INVALCOLOR)
681+
fg = gui.def_norm_pixel;
682+
683+
if (reverse) {
684+
guicolor_T temp = fg;
685+
fg = bg;
686+
bg = temp;
684687
}
688+
tablineColors[i*2] = (int)bg;
689+
tablineColors[i*2+1] = (int)fg;
690+
}
691+
// Cache the old colors just so we don't spam the IPC channel if the
692+
// colors didn't actually change.
693+
static int oldTablineColors[6] = { 0 };
694+
if (memcmp(oldTablineColors, tablineColors, sizeof(oldTablineColors)) != 0) {
695+
memcpy(oldTablineColors, tablineColors, sizeof(oldTablineColors));
696+
[[MMBackend sharedInstance] setTablineColors:tablineColors];
685697
}
686698
}
687699

0 commit comments

Comments
 (0)