Skip to content

Commit

Permalink
Merge pull request #1511 from ychin/dark-mode-tests-clearer-docs
Browse files Browse the repository at this point in the history
Dark mode improve docs for v:os_appearance and add tests
  • Loading branch information
ychin authored Nov 4, 2024
2 parents 52550fc + 6ecd752 commit cf2c1e7
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 2 deletions.
7 changes: 5 additions & 2 deletions runtime/doc/eval.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2439,9 +2439,12 @@ v:operator The last operator given in Normal mode. This is a single
Read-only.

*v:os_appearance* *os-appearance-variable*
v:os_appearance The current OS appearance mode. Useful if you want to change
v:os_appearance The current OS appearance mode. Useful if you want to change
options |background| or |colorscheme| according to the
appearance of the GUI frontend. See also |OSAppearanceChanged|.
appearance of the GUI frontend. See also
|OSAppearanceChanged|. If the "Dark mode selection" setting
is not set to "Automatic", then this value will reflect that
setting instead.
value description ~
0 Light Mode (always 0 on unsupported platforms)
1 Dark Mode
Expand Down
77 changes: 77 additions & 0 deletions src/MacVim/MacVimTests/MacVimTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,83 @@ - (void) testGuifontSystemMonospace {
[self waitForVimClose];
}

/// Test that dark mode settings work and the corresponding Vim bindings are functional.
///
/// Note that `v:os_appearance` and OSAppearanceChanged respond to the view's appearance
/// rather than the OS setting. When using manual light/dark or "use background" settings,
/// they do not reflect the current OS dark mode setting.
- (void) testDarkMode {
NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;

MMAppController *app = MMAppController.sharedInstance;

[app openNewWindow:NewWindowClean activate:YES];
[self waitForVimOpenAndMessages];

MMVimView *vimView = [[[app keyVimController] windowController] vimView];

// We just use the system appearance to determine the initial state. Otherwise
// we have to change the system appearance to light mode first which we don't
// have permission to do.
const BOOL systemUsingDarkMode = [[ud stringForKey:@"AppleInterfaceStyle"] isEqualToString:@"Dark"];
const NSAppearance *systemAppearance = systemUsingDarkMode ?
[NSAppearance appearanceNamed: NSAppearanceNameDarkAqua] : [NSAppearance appearanceNamed: NSAppearanceNameAqua];

// Default setting uses system appearance
XCTAssertEqualObjects(vimView.effectiveAppearance, systemAppearance);
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], systemUsingDarkMode ? @"1" : @"0");

// Cache original settings / set up setting overrides
NSDictionary<NSString *, id> *defaults = [ud volatileDomainForName:NSArgumentDomain];
NSMutableDictionary<NSString *, id> *newDefaults = [defaults mutableCopy];

// Manual Light / Dark mode setting
newDefaults[MMAppearanceModeSelectionKey] = [NSNumber numberWithInt:MMAppearanceModeSelectionLight];
[ud setVolatileDomain:newDefaults forName:NSArgumentDomain];
[app refreshAllAppearances];
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameAqua]);
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"0");

// Set up a listener for OSAppearanceChanged event to make sure it's called
// when the view appearance changes.
[self sendStringToVim:@":let g:os_appearance_changed_called=0\n" withMods:0];
[self sendStringToVim:@":autocmd OSAppearanceChanged * let g:os_appearance_changed_called+=1\n" withMods:0];
[self waitForEventHandlingAndVimProcess];

newDefaults[MMAppearanceModeSelectionKey] = [NSNumber numberWithInt:MMAppearanceModeSelectionDark];
[ud setVolatileDomain:newDefaults forName:NSArgumentDomain];
[app refreshAllAppearances];
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua]);
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"1");
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"g:os_appearance_changed_called"], @"1");

// "Use background" setting
[self sendStringToVim:@":set background=dark\n" withMods:0];
[self waitForEventHandlingAndVimProcess];

newDefaults[MMAppearanceModeSelectionKey] = [NSNumber numberWithInt:MMAppearanceModeSelectionBackgroundOption];
[NSUserDefaults.standardUserDefaults setVolatileDomain:newDefaults forName:NSArgumentDomain];
[app refreshAllAppearances];
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua]);
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"1");
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"g:os_appearance_changed_called"], @"1"); // we stayed in dark mode, so OSAppearnceChanged didn't trigger

[self sendStringToVim:@":set background=light\n" withMods:0];
[self waitForEventHandlingAndVimProcess];
XCTAssertEqualObjects(vimView.effectiveAppearance, [NSAppearance appearanceNamed: NSAppearanceNameAqua]);
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"v:os_appearance"], @"0");
XCTAssertEqualObjects([[app keyVimController] evaluateVimExpression:@"g:os_appearance_changed_called"], @"2");

// Restore original settings and make sure it's reset
[NSUserDefaults.standardUserDefaults setVolatileDomain:defaults forName:NSArgumentDomain];
[app refreshAllAppearances];
XCTAssertEqualObjects(vimView.effectiveAppearance, systemAppearance);

// Clean up
[[app keyVimController] sendMessage:VimShouldCloseMsgID data:nil];
[self waitForVimClose];
}

/// Test that document icon is shown in title bar when enabled.
- (void) testTitlebarDocumentIcon {
MMAppController *app = MMAppController.sharedInstance;
Expand Down

0 comments on commit cf2c1e7

Please sign in to comment.