Skip to content

Commit cf2c1e7

Browse files
authored
Merge pull request #1511 from ychin/dark-mode-tests-clearer-docs
Dark mode improve docs for v:os_appearance and add tests
2 parents 52550fc + 6ecd752 commit cf2c1e7

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

runtime/doc/eval.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,9 +2439,12 @@ v:operator The last operator given in Normal mode. This is a single
24392439
Read-only.
24402440

24412441
*v:os_appearance* *os-appearance-variable*
2442-
v:os_appearance The current OS appearance mode. Useful if you want to change
2442+
v:os_appearance The current OS appearance mode. Useful if you want to change
24432443
options |background| or |colorscheme| according to the
2444-
appearance of the GUI frontend. See also |OSAppearanceChanged|.
2444+
appearance of the GUI frontend. See also
2445+
|OSAppearanceChanged|. If the "Dark mode selection" setting
2446+
is not set to "Automatic", then this value will reflect that
2447+
setting instead.
24452448
value description ~
24462449
0 Light Mode (always 0 on unsupported platforms)
24472450
1 Dark Mode

src/MacVim/MacVimTests/MacVimTests.m

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,83 @@ - (void) testGuifontSystemMonospace {
458458
[self waitForVimClose];
459459
}
460460

461+
/// Test that dark mode settings work and the corresponding Vim bindings are functional.
462+
///
463+
/// Note that `v:os_appearance` and OSAppearanceChanged respond to the view's appearance
464+
/// rather than the OS setting. When using manual light/dark or "use background" settings,
465+
/// they do not reflect the current OS dark mode setting.
466+
- (void) testDarkMode {
467+
NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;
468+
469+
MMAppController *app = MMAppController.sharedInstance;
470+
471+
[app openNewWindow:NewWindowClean activate:YES];
472+
[self waitForVimOpenAndMessages];
473+
474+
MMVimView *vimView = [[[app keyVimController] windowController] vimView];
475+
476+
// We just use the system appearance to determine the initial state. Otherwise
477+
// we have to change the system appearance to light mode first which we don't
478+
// have permission to do.
479+
const BOOL systemUsingDarkMode = [[ud stringForKey:@"AppleInterfaceStyle"] isEqualToString:@"Dark"];
480+
const NSAppearance *systemAppearance = systemUsingDarkMode ?
481+
[NSAppearance appearanceNamed: NSAppearanceNameDarkAqua] : [NSAppearance appearanceNamed: NSAppearanceNameAqua];
482+
483+
// Default setting uses system appearance
484+
XCTAssertEqualObjects(vimView.effectiveAppearance, systemAppearance);
485+
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], systemUsingDarkMode ? @"1" : @"0");
486+
487+
// Cache original settings / set up setting overrides
488+
NSDictionary<NSString *, id> *defaults = [ud volatileDomainForName:NSArgumentDomain];
489+
NSMutableDictionary<NSString *, id> *newDefaults = [defaults mutableCopy];
490+
491+
// Manual Light / Dark mode setting
492+
newDefaults[MMAppearanceModeSelectionKey] = [NSNumber numberWithInt:MMAppearanceModeSelectionLight];
493+
[ud setVolatileDomain:newDefaults forName:NSArgumentDomain];
494+
[app refreshAllAppearances];
495+
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameAqua]);
496+
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"0");
497+
498+
// Set up a listener for OSAppearanceChanged event to make sure it's called
499+
// when the view appearance changes.
500+
[self sendStringToVim:@":let g:os_appearance_changed_called=0\n" withMods:0];
501+
[self sendStringToVim:@":autocmd OSAppearanceChanged * let g:os_appearance_changed_called+=1\n" withMods:0];
502+
[self waitForEventHandlingAndVimProcess];
503+
504+
newDefaults[MMAppearanceModeSelectionKey] = [NSNumber numberWithInt:MMAppearanceModeSelectionDark];
505+
[ud setVolatileDomain:newDefaults forName:NSArgumentDomain];
506+
[app refreshAllAppearances];
507+
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua]);
508+
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"1");
509+
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"g:os_appearance_changed_called"], @"1");
510+
511+
// "Use background" setting
512+
[self sendStringToVim:@":set background=dark\n" withMods:0];
513+
[self waitForEventHandlingAndVimProcess];
514+
515+
newDefaults[MMAppearanceModeSelectionKey] = [NSNumber numberWithInt:MMAppearanceModeSelectionBackgroundOption];
516+
[NSUserDefaults.standardUserDefaults setVolatileDomain:newDefaults forName:NSArgumentDomain];
517+
[app refreshAllAppearances];
518+
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua]);
519+
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"1");
520+
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"g:os_appearance_changed_called"], @"1"); // we stayed in dark mode, so OSAppearnceChanged didn't trigger
521+
522+
[self sendStringToVim:@":set background=light\n" withMods:0];
523+
[self waitForEventHandlingAndVimProcess];
524+
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameAqua]);
525+
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"0");
526+
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"g:os_appearance_changed_called"], @"2");
527+
528+
// Restore original settings and make sure it's reset
529+
[NSUserDefaults.standardUserDefaults setVolatileDomain:defaults forName:NSArgumentDomain];
530+
[app refreshAllAppearances];
531+
XCTAssertEqualObjects(vimView.effectiveAppearance, systemAppearance);
532+
533+
// Clean up
534+
[[app keyVimController] sendMessage:VimShouldCloseMsgID data:nil];
535+
[self waitForVimClose];
536+
}
537+
461538
/// Test that document icon is shown in title bar when enabled.
462539
- (void) testTitlebarDocumentIcon {
463540
MMAppController *app = MMAppController.sharedInstance;

0 commit comments

Comments
 (0)