From fa83ca5cb1dd14f5b7b0dc88f779d11e86e2fa8c Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Thu, 26 Oct 2023 09:44:38 -0700 Subject: [PATCH] Allow launching MacVim in clean defaults, add menu to open clean Vim Now support a `-IgnoreUserDefaults 1` flag that can be passed to MacVim at launch, which would cause MacVim to open with the default settings instead of whatever the user has previously set. This only works by overriding the MacVim-specific application defaults, and won't affect Sparkle settings and other macOS native ones. Also add a new menu item / macaction to open a new Vim window in clean mode (which would prevent loading in vimrc and plugins). It works by launching Vim using a `--clean` flag. The alt menu would open a clean Vim window without using defaults.vim as well for the most vanilla Vim. Currently only added Chinese/Japanese translations for the menu items. Users who want other languages to be localized will need to file a pull request themselves. This feature is useful for users, but the main reason is to serve as a pre-requisite for adding XCTest test cases to MacVim and needing a way to launch it in a clean and predictable way. --- runtime/doc/gui_mac.txt | 4 + .../macvim_menu/menu_ja_jp.utf-8.custom.vim | 2 + .../macvim_menu/menu_zh_cn.utf-8.custom.vim | 2 + .../macvim_menu/menu_zh_tw.utf-8.custom.vim | 2 + runtime/menu.vim | 8 +- src/MacVim/Actions.plist | 16 +- src/MacVim/Base.lproj/MainMenu.xib | 17 ++ src/MacVim/MMAppController.h | 18 +++ src/MacVim/MMAppController.m | 150 ++++++++++++------ src/MacVim/MMWindowController.m | 2 +- src/MacVim/Miscellaneous.h | 2 +- src/MacVim/Miscellaneous.m | 2 +- src/MacVim/ja.lproj/MainMenu.strings | 9 ++ src/MacVim/zh-Hans.lproj/MainMenu.strings | 9 ++ src/MacVim/zh-Hant.lproj/MainMenu.strings | 9 ++ 15 files changed, 195 insertions(+), 57 deletions(-) diff --git a/runtime/doc/gui_mac.txt b/runtime/doc/gui_mac.txt index ec1efe3256..869cec0f26 100644 --- a/runtime/doc/gui_mac.txt +++ b/runtime/doc/gui_mac.txt @@ -264,6 +264,10 @@ Vim options (see |macvim-options|). These settings are stored in the user defaults database and can be accessed via the "MacVim.Settings…" ("MacVim.Preferences…" in macOS 12 Monterey and older) menu item. +If you want to open MacVim with its default settings, you can open it by +passing `-IgnoreUserDefaults 1` to the launch arguments (see the man page on +the "open" for how to do so). + *macvim-user-defaults* Not all entries in the user defaults database are exposed via the settings panel, usually because they should not be changed by the user under normal diff --git a/runtime/lang/macvim_menu/menu_ja_jp.utf-8.custom.vim b/runtime/lang/macvim_menu/menu_ja_jp.utf-8.custom.vim index 49b9ed2cbe..ba87efcd8d 100644 --- a/runtime/lang/macvim_menu/menu_ja_jp.utf-8.custom.vim +++ b/runtime/lang/macvim_menu/menu_ja_jp.utf-8.custom.vim @@ -1,3 +1,5 @@ +menutrans New\ Clean\ Window 新規クリーンウインドウ +menutrans New\ Clean\ Window\ (No\ Defaults) 新規クリーンウインドウ\ (デフォルトなし) menutrans MacVim\ Help MacVim\ ヘルプ menutrans MacVim\ Website MacVim\ Webサイト menutrans Vim\ Tutor Vim\ 教本\ (チュートリアル) diff --git a/runtime/lang/macvim_menu/menu_zh_cn.utf-8.custom.vim b/runtime/lang/macvim_menu/menu_zh_cn.utf-8.custom.vim index dcca701a8f..a999c724e9 100644 --- a/runtime/lang/macvim_menu/menu_zh_cn.utf-8.custom.vim +++ b/runtime/lang/macvim_menu/menu_zh_cn.utf-8.custom.vim @@ -1,3 +1,5 @@ +menutrans New\ Clean\ Window 新建干净窗口 +menutrans New\ Clean\ Window\ (No\ Defaults) 新建干净窗口(不用\ Defaults) menutrans MacVim\ Help MacVim帮助 menutrans MacVim\ Website MacVim网站 menutrans Vim\ Tutor Vim教程 diff --git a/runtime/lang/macvim_menu/menu_zh_tw.utf-8.custom.vim b/runtime/lang/macvim_menu/menu_zh_tw.utf-8.custom.vim index 3b10abd73b..0ff7fd7339 100644 --- a/runtime/lang/macvim_menu/menu_zh_tw.utf-8.custom.vim +++ b/runtime/lang/macvim_menu/menu_zh_tw.utf-8.custom.vim @@ -1,3 +1,5 @@ +menutrans New\ Clean\ Window 新增乾淨視窗 +menutrans New\ Clean\ Window\ (No\ Defaults) 新增乾淨視窗(不用\ Defaults) menutrans MacVim\ Help MacVim輔助說明 menutrans MacVim\ Website MacVim網站 menutrans Vim\ Tutor Vim教程 diff --git a/runtime/menu.vim b/runtime/menu.vim index 0d5ee96b3e..00e9acfcd9 100644 --- a/runtime/menu.vim +++ b/runtime/menu.vim @@ -160,7 +160,9 @@ enddef " File menu if has("gui_macvim") - an 10.290 &File.New\ Window + an 10.290 &File.New\ Window + an 10.291 &File.New\ Clean\ Window + an 10.292 &File.New\ Clean\ Window\ (No\ Defaults) an 10.295 &File.New\ Tab :tabnew tln 10.295 &File.New\ Tab :tabnew an 10.310 &File.Open… @@ -1267,6 +1269,8 @@ if has("gui_macvim") " action message is specified here via the :macmenu command. " macm File.New\ Window key= action=newWindow: + macm File.New\ Clean\ Window key= action=newWindowClean: + macm File.New\ Clean\ Window\ (No\ Defaults) key= action=newWindowCleanNoDefaults: alt=YES macm File.New\ Tab key= macm File.Open… key= action=fileOpen: macm File.Open\ Tab\.\.\.:tabnew key= @@ -1417,4 +1421,4 @@ if has("touchbar") endif endif -" vim: set sw=2 : +" vim: set sw=2 tabstop=8 : diff --git a/src/MacVim/Actions.plist b/src/MacVim/Actions.plist index ced98af89e..99d32b8def 100644 --- a/src/MacVim/Actions.plist +++ b/src/MacVim/Actions.plist @@ -36,6 +36,10 @@ newWindow: + newWindowClean: + + newWindowCleanNoDefaults: + openWebsite: showWhatsNew: @@ -86,11 +90,11 @@ stayLevelNormal: - _removeWindowFromStageManagerSet: - - joinAllStageManagerSets: - - unjoinAllStageManagerSets: - + _removeWindowFromStageManagerSet: + + joinAllStageManagerSets: + + unjoinAllStageManagerSets: + diff --git a/src/MacVim/Base.lproj/MainMenu.xib b/src/MacVim/Base.lproj/MainMenu.xib index f878ddc7e7..cc9f0eb65f 100644 --- a/src/MacVim/Base.lproj/MainMenu.xib +++ b/src/MacVim/Base.lproj/MainMenu.xib @@ -81,6 +81,17 @@ + + + + + + + + + + + @@ -205,6 +216,12 @@ + + + + + + diff --git a/src/MacVim/MMAppController.h b/src/MacVim/MMAppController.h index cbf1fb89e6..bc61377a53 100644 --- a/src/MacVim/MMAppController.h +++ b/src/MacVim/MMAppController.h @@ -32,6 +32,12 @@ , NSMenuItemValidation #endif > { + enum NewWindowMode { + NewWindowNormal = 0, + NewWindowClean, + NewWindowCleanNoDefaults, + }; + NSConnection *connection; NSMutableArray *vimControllers; NSString *openSelectionString; @@ -82,13 +88,22 @@ - (void)refreshAllResizeConstraints; - (void)refreshAllTextViews; +- (void)openNewWindow:(enum NewWindowMode)mode activate:(BOOL)activate; + // // NSMenuItemValidation // - (BOOL)validateMenuItem:(NSMenuItem *)item; +// +// Actions exposed to Vim +// - (IBAction)newWindow:(id)sender; +- (IBAction)newWindowClean:(id)sender; +- (IBAction)newWindowCleanNoDefaults:(id)sender; - (IBAction)newWindowAndActivate:(id)sender; +- (IBAction)newWindowCleanAndActivate:(id)sender; +- (IBAction)newWindowCleanNoDefaultsAndActivate:(id)sender; - (IBAction)fileOpen:(id)sender; - (IBAction)selectNextWindow:(id)sender; - (IBAction)selectPreviousWindow:(id)sender; @@ -105,6 +120,9 @@ - (IBAction)stayInBack:(id)sender; - (IBAction)stayLevelNormal:(id)sender; +// +// NSUserInterfaceItemSearching +// - (NSArray *)localizedTitlesForItem:(id)item; - (void)searchForItemsWithSearchString:(NSString *)searchString resultLimit:(NSInteger)resultLimit diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index f33fcaca19..79c4996b93 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -166,45 +166,11 @@ - (void)inputSourceChanged:(NSNotification *)notification; @implementation MMAppController -+ (void)initialize +/// Register the default settings for MacVim. Supports an optional +/// "-IgnoreUserDefaults 1" command-line argument, which will override +/// persisted user settings to have a clean environment. ++ (void)registerDefaults { - static BOOL initDone = NO; - if (initDone) return; - initDone = YES; - - ASLInit(); - - // HACK! The following user default must be reset, else Ctrl-q (or - // whichever key is specified by the default) will be blocked by the input - // manager (interpretKeyEvents: swallows that key). (We can't use - // NSUserDefaults since it only allows us to write to the registration - // domain and this preference has "higher precedence" than that so such a - // change would have no effect.) - CFPreferencesSetAppValue(CFSTR("NSQuotedKeystrokeBinding"), - CFSTR(""), - kCFPreferencesCurrentApplication); - - // Also disable NSRepeatCountBinding -- it is not enabled by default, but - // it does not make much sense to support it since Vim has its own way of - // dealing with repeat counts. - CFPreferencesSetAppValue(CFSTR("NSRepeatCountBinding"), - CFSTR(""), - kCFPreferencesCurrentApplication); - - if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)]) { - // Disable automatic tabbing on 10.12+. MacVim already has its own - // tabbing interface, so we don't want multiple hierarchy of tabs mixing - // native and Vim tabs. MacVim also doesn't work well with native tabs - // right now since it doesn't respond well to the size change, and it - // doesn't show the native menu items (e.g. move tab to new window) in - // all the tabs. - // - // Note: MacVim cannot use macOS native tabs for Vim tabs because Vim - // assumes only one tab can be shown at a time, and it would be hard to - // handle native tab's "move tab to a new window" functionality. - [NSWindow setAllowsAutomaticWindowTabbing:NO]; - } - int tabMinWidthKey; int tabMaxWidthKey; int tabOptimumWidthKey; @@ -218,7 +184,9 @@ + (void)initialize tabOptimumWidthKey = 132; } - NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: + NSUserDefaults *ud = NSUserDefaults.standardUserDefaults; + + NSDictionary *macvimDefaults = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], MMNoWindowKey, [NSNumber numberWithInt:tabMinWidthKey], MMTabMinWidthKey, @@ -244,6 +212,10 @@ + (void)initialize [NSNumber numberWithInt:MMUntitledWindowAlways], MMUntitledWindowKey, [NSNumber numberWithBool:NO], MMNoWindowShadowKey, + [NSNumber numberWithBool:NO], MMDisableLaunchAnimationKey, + [NSNumber numberWithInt:0], MMAppearanceModeSelectionKey, + [NSNumber numberWithBool:NO], MMNoTitleBarWindowKey, + [NSNumber numberWithBool:NO], MMTitlebarAppearsTransparentKey, [NSNumber numberWithBool:NO], MMZoomBothKey, @"", MMLoginShellCommandKey, @"", MMLoginShellArgumentKey, @@ -271,7 +243,58 @@ + (void)initialize [NSNumber numberWithBool:0], MMScrollOneDirectionOnlyKey, nil]; - [[NSUserDefaults standardUserDefaults] registerDefaults:dict]; + [ud registerDefaults:macvimDefaults]; + + NSArray *arguments = NSProcessInfo.processInfo.arguments; + if ([arguments containsObject:@"-IgnoreUserDefaults"]) { + NSDictionary *argDefaults = [ud volatileDomainForName:NSArgumentDomain]; + NSMutableDictionary *combinedDefaults = [NSMutableDictionary dictionaryWithCapacity: macvimDefaults.count]; + [combinedDefaults setDictionary:macvimDefaults]; + [combinedDefaults addEntriesFromDictionary:argDefaults]; + [ud setVolatileDomain:combinedDefaults forName:NSArgumentDomain]; + } +} + ++ (void)initialize +{ + static BOOL initDone = NO; + if (initDone) return; + initDone = YES; + + ASLInit(); + + // HACK! The following user default must be reset, else Ctrl-q (or + // whichever key is specified by the default) will be blocked by the input + // manager (interpreargumenttKeyEvents: swallows that key). (We can't use + // NSUserDefaults since it only allows us to write to the registration + // domain and this preference has "higher precedence" than that so such a + // change would have no effect.) + CFPreferencesSetAppValue(CFSTR("NSQuotedKeystrokeBinding"), + CFSTR(""), + kCFPreferencesCurrentApplication); + + // Also disable NSRepeatCountBinding -- it is not enabled by default, but + // it does not make much sense to support it since Vim has its own way of + // dealing with repeat counts. + CFPreferencesSetAppValue(CFSTR("NSRepeatCountBinding"), + CFSTR(""), + kCFPreferencesCurrentApplication); + + if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)]) { + // Disable automatic tabbing on 10.12+. MacVim already has its own + // tabbing interface, so we don't want multiple hierarchy of tabs mixing + // native and Vim tabs. MacVim also doesn't work well with native tabs + // right now since it doesn't respond well to the size change, and it + // doesn't show the native menu items (e.g. move tab to new window) in + // all the tabs. + // + // Note: MacVim cannot use macOS native tabs for Vim tabs because Vim + // assumes only one tab can be shown at a time, and it would be hard to + // handle native tab's "move tab to a new window" functionality. + [NSWindow setAllowsAutomaticWindowTabbing:NO]; + } + + [MMAppController registerDefaults]; NSArray *types = [NSArray arrayWithObject:NSPasteboardTypeString]; [NSApp registerServicesMenuSendTypes:types returnTypes:types]; @@ -1296,25 +1319,60 @@ - (BOOL)validateMenuItem:(NSMenuItem *)item return YES; } -- (IBAction)newWindow:(id)sender +/// Open a new Vim window, potentially taking from cached (if preload is used). +/// +/// @param mode Determine whether to use clean mode or not. Preload will only +/// be used if using normal mode. +/// +/// @param activate Activate the window after it's opened. +- (void)openNewWindow:(enum NewWindowMode)mode activate:(BOOL)activate { - ASLogDebug(@"Open new window"); + if (activate) + [self activateWhenNextWindowOpens]; // A cached controller requires no loading times and results in the new // window popping up instantaneously. If the cache is empty it may take // 1-2 seconds to start a new Vim process. - MMVimController *vc = [self takeVimControllerFromCache]; + MMVimController *vc = (mode == NewWindowNormal) ? [self takeVimControllerFromCache] : nil; if (vc) { [[vc backendProxy] acknowledgeConnection]; } else { - [self launchVimProcessWithArguments:nil workingDirectory:nil]; + NSArray *args = (mode == NewWindowNormal) ? nil + : (mode == NewWindowClean ? @[@"--clean"] + : @[@"--clean", @"-u", @"NONE"]); + [self launchVimProcessWithArguments:args workingDirectory:nil]; } } +- (IBAction)newWindow:(id)sender +{ + ASLogDebug(@"Open new window"); + [self openNewWindow:NewWindowNormal activate:NO]; +} + +- (IBAction)newWindowClean:(id)sender +{ + [self openNewWindow:NewWindowClean activate:NO]; +} + +- (IBAction)newWindowCleanNoDefaults:(id)sender +{ + [self openNewWindow:NewWindowCleanNoDefaults activate:NO]; +} + - (IBAction)newWindowAndActivate:(id)sender { - [self activateWhenNextWindowOpens]; - [self newWindow:sender]; + [self openNewWindow:NewWindowNormal activate:YES]; +} + +- (IBAction)newWindowCleanAndActivate:(id)sender +{ + [self openNewWindow:NewWindowClean activate:YES]; +} + +- (IBAction)newWindowCleanNoDefaultsAndActivate:(id)sender +{ + [self openNewWindow:NewWindowCleanNoDefaults activate:YES]; } - (IBAction)fileOpen:(id)sender diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m index 9f7789fb74..52bedd708d 100644 --- a/src/MacVim/MMWindowController.m +++ b/src/MacVim/MMWindowController.m @@ -232,7 +232,7 @@ - (id)initWithVimController:(MMVimController *)controller // This makes windows animate when opened if ([win respondsToSelector:@selector(setAnimationBehavior:)]) { if (![[NSUserDefaults standardUserDefaults] - boolForKey:MMDisableLaunchAnimation]) { + boolForKey:MMDisableLaunchAnimationKey]) { [win setAnimationBehavior:NSWindowAnimationBehaviorDocumentWindow]; } } diff --git a/src/MacVim/Miscellaneous.h b/src/MacVim/Miscellaneous.h index 0e00adf94f..e8b1607232 100644 --- a/src/MacVim/Miscellaneous.h +++ b/src/MacVim/Miscellaneous.h @@ -38,7 +38,7 @@ extern NSString *MMAppearanceModeSelectionKey; extern NSString *MMNoTitleBarWindowKey; extern NSString *MMTitlebarAppearsTransparentKey; extern NSString *MMNoWindowShadowKey; -extern NSString *MMDisableLaunchAnimation; +extern NSString *MMDisableLaunchAnimationKey; extern NSString *MMLoginShellKey; extern NSString *MMUntitledWindowKey; extern NSString *MMZoomBothKey; diff --git a/src/MacVim/Miscellaneous.m b/src/MacVim/Miscellaneous.m index f889fd74e8..acc5e0ab21 100644 --- a/src/MacVim/Miscellaneous.m +++ b/src/MacVim/Miscellaneous.m @@ -34,7 +34,7 @@ NSString *MMNoTitleBarWindowKey = @"MMNoTitleBarWindow"; NSString *MMTitlebarAppearsTransparentKey = @"MMTitlebarAppearsTransparent"; NSString *MMNoWindowShadowKey = @"MMNoWindowShadow"; -NSString *MMDisableLaunchAnimation = @"MMDisableLaunchAnimation"; +NSString *MMDisableLaunchAnimationKey = @"MMDisableLaunchAnimation"; NSString *MMLoginShellKey = @"MMLoginShell"; NSString *MMUntitledWindowKey = @"MMUntitledWindow"; NSString *MMZoomBothKey = @"MMZoomBoth"; diff --git a/src/MacVim/ja.lproj/MainMenu.strings b/src/MacVim/ja.lproj/MainMenu.strings index 5308de93d4..2ea81c3402 100644 --- a/src/MacVim/ja.lproj/MainMenu.strings +++ b/src/MacVim/ja.lproj/MainMenu.strings @@ -16,6 +16,15 @@ /* Class = "NSMenuItem"; title = "MacVim Help"; ObjectID = "275"; */ "275.title" = "MacVim ヘルプ"; +/* Class = "NSMenuItem"; title = "New Clean Window"; ObjectID = "6vC-1c-PzC"; */ +"6vC-1c-PzC.title" = "新規クリーンウインドウ"; + +/* Class = "NSMenuItem"; title = "New Clean Window (No Defaults)"; ObjectID = "I52-K0-dKN"; */ +"I52-K0-dKN.title" = "新規クリーンウインドウ (デフォルトなし)"; + +/* Class = "NSMenuItem"; title = "New Clean Window"; ObjectID = "pDQ-Dc-v9a"; */ +"pDQ-Dc-v9a.title" = "新規クリーンウインドウ"; + // The strings below are untranslated /* Class = "NSMenu"; title = "MainMenu"; ObjectID = "29"; */ diff --git a/src/MacVim/zh-Hans.lproj/MainMenu.strings b/src/MacVim/zh-Hans.lproj/MainMenu.strings index 2452bc2b0e..6487f4c126 100644 --- a/src/MacVim/zh-Hans.lproj/MainMenu.strings +++ b/src/MacVim/zh-Hans.lproj/MainMenu.strings @@ -16,6 +16,15 @@ /* Class = "NSMenuItem"; title = "MacVim Help"; ObjectID = "275"; */ "275.title" = "MacVim帮助"; +/* Class = "NSMenuItem"; title = "New Clean Window"; ObjectID = "6vC-1c-PzC"; */ +"6vC-1c-PzC.title" = "新建干净窗口"; + +/* Class = "NSMenuItem"; title = "New Clean Window (No Defaults)"; ObjectID = "I52-K0-dKN"; */ +"I52-K0-dKN.title" = "新建干净窗口(不用 Defaults)"; + +/* Class = "NSMenuItem"; title = "New Clean Window"; ObjectID = "pDQ-Dc-v9a"; */ +"pDQ-Dc-v9a.title" = "新建干净窗口"; + // The strings below are untranslated /* Class = "NSMenu"; title = "MainMenu"; ObjectID = "29"; */ diff --git a/src/MacVim/zh-Hant.lproj/MainMenu.strings b/src/MacVim/zh-Hant.lproj/MainMenu.strings index 71cf51633d..3d9021c71f 100644 --- a/src/MacVim/zh-Hant.lproj/MainMenu.strings +++ b/src/MacVim/zh-Hant.lproj/MainMenu.strings @@ -16,6 +16,15 @@ /* Class = "NSMenuItem"; title = "MacVim Help"; ObjectID = "275"; */ "275.title" = "MacVim輔助說明"; +/* Class = "NSMenuItem"; title = "New Clean Window"; ObjectID = "6vC-1c-PzC"; */ +"6vC-1c-PzC.title" = "新增乾淨視窗"; + +/* Class = "NSMenuItem"; title = "New Clean Window (No Defaults)"; ObjectID = "I52-K0-dKN"; */ +"I52-K0-dKN.title" = "新增乾淨視窗(不用 Defaults)"; + +/* Class = "NSMenuItem"; title = "New Clean Window"; ObjectID = "pDQ-Dc-v9a"; */ +"pDQ-Dc-v9a.title" = "新增乾淨視窗"; + // The strings below are untranslated /* Class = "NSMenu"; title = "MainMenu"; ObjectID = "29"; */