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.
This commit is contained in:
Yee Cheng Chin
2023-10-26 09:44:38 -07:00
parent b0ba0b90c5
commit fa83ca5cb1
15 changed files with 223 additions and 85 deletions
+4
View File
@@ -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
@@ -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\ 教本\ (チュートリアル)
@@ -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教程
@@ -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教程
+6 -2
View File
@@ -160,7 +160,9 @@ enddef
" File menu
if has("gui_macvim")
an <silent> 10.290 &File.New\ Window <Nop>
an <silent> 10.290 &File.New\ Window <Nop>
an <silent> 10.291 &File.New\ Clean\ Window <Nop>
an <silent> 10.292 &File.New\ Clean\ Window\ (No\ Defaults) <Nop>
an 10.295 &File.New\ Tab :tabnew<CR>
tln 10.295 &File.New\ Tab <C-W>:tabnew<CR>
an <silent> 10.310 &File.Open<Nop>
@@ -1267,6 +1269,8 @@ if has("gui_macvim")
" action message is specified here via the :macmenu command.
"
macm File.New\ Window key=<D-n> action=newWindow:
macm File.New\ Clean\ Window key=<D-N> action=newWindowClean:
macm File.New\ Clean\ Window\ (No\ Defaults) key=<D-M-N> action=newWindowCleanNoDefaults: alt=YES
macm File.New\ Tab key=<D-t>
macm File.Openkey=<D-o> action=fileOpen:
macm File.Open\ Tab\.\.\.<Tab>:tabnew key=<D-T>
@@ -1417,4 +1421,4 @@ if has("touchbar")
endif
endif
" vim: set sw=2 :
" vim: set sw=2 tabstop=8 :
+10 -6
View File
@@ -36,6 +36,10 @@
<string></string>
<key>newWindow:</key>
<string></string>
<key>newWindowClean:</key>
<string></string>
<key>newWindowCleanNoDefaults:</key>
<string></string>
<key>openWebsite:</key>
<string></string>
<key>showWhatsNew:</key>
@@ -86,11 +90,11 @@
<string></string>
<key>stayLevelNormal:</key>
<string></string>
<key>_removeWindowFromStageManagerSet:</key>
<string></string>
<key>joinAllStageManagerSets:</key>
<string></string>
<key>unjoinAllStageManagerSets:</key>
<string></string>
<key>_removeWindowFromStageManagerSet:</key>
<string></string>
<key>joinAllStageManagerSets:</key>
<string></string>
<key>unjoinAllStageManagerSets:</key>
<string></string>
</dict>
</plist>
+17
View File
@@ -81,6 +81,17 @@
<action selector="newWindow:" target="235" id="251"/>
</connections>
</menuItem>
<menuItem title="New Clean Window" keyEquivalent="N" id="6vC-1c-PzC" userLabel="New Clean Window">
<connections>
<action selector="newWindowCleanAndActivate:" target="-1" id="0IK-4B-mIA"/>
</connections>
</menuItem>
<menuItem title="New Clean Window (No Defaults)" alternate="YES" keyEquivalent="N" id="I52-K0-dKN" userLabel="New Clean Window (No Defaults)">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="newWindowCleanNoDefaultsAndActivate:" target="-1" id="nAy-O6-DrK"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="261">
<connections>
<action selector="fileOpen:" target="235" id="277"/>
@@ -205,6 +216,12 @@
<action selector="newWindowAndActivate:" target="235" id="350"/>
</connections>
</menuItem>
<menuItem title="New Clean Window" id="pDQ-Dc-v9a" userLabel="New Clean Window">
<attributedString key="attributedTitle"/>
<connections>
<action selector="newWindowCleanAndActivate:" target="-1" id="p1b-M2-0zQ"/>
</connections>
</menuItem>
</items>
<point key="canvasLocation" x="139" y="67"/>
</menu>
+18
View File
@@ -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<NSString *> *)localizedTitlesForItem:(id)item;
- (void)searchForItemsWithSearchString:(NSString *)searchString
resultLimit:(NSInteger)resultLimit
+132 -74
View File
@@ -166,6 +166,95 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
@implementation MMAppController
/// 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
{
int tabMinWidthKey;
int tabMaxWidthKey;
int tabOptimumWidthKey;
if (shouldUseYosemiteTabBarStyle()) {
tabMinWidthKey = 120;
tabMaxWidthKey = 0;
tabOptimumWidthKey = 0;
} else {
tabMinWidthKey = 64;
tabMaxWidthKey = 6*64;
tabOptimumWidthKey = 132;
}
NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;
NSDictionary *macvimDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], MMNoWindowKey,
[NSNumber numberWithInt:tabMinWidthKey],
MMTabMinWidthKey,
[NSNumber numberWithInt:tabMaxWidthKey],
MMTabMaxWidthKey,
[NSNumber numberWithInt:tabOptimumWidthKey],
MMTabOptimumWidthKey,
[NSNumber numberWithBool:YES], MMShowAddTabButtonKey,
[NSNumber numberWithInt:2], MMTextInsetLeftKey,
[NSNumber numberWithInt:1], MMTextInsetRightKey,
[NSNumber numberWithInt:1], MMTextInsetTopKey,
[NSNumber numberWithInt:1], MMTextInsetBottomKey,
@"MMTypesetter", MMTypesetterKey,
[NSNumber numberWithFloat:1], MMCellWidthMultiplierKey,
[NSNumber numberWithFloat:-1], MMBaselineOffsetKey,
[NSNumber numberWithBool:YES], MMTranslateCtrlClickKey,
[NSNumber numberWithInt:0], MMOpenInCurrentWindowKey,
[NSNumber numberWithBool:NO], MMNoFontSubstitutionKey,
[NSNumber numberWithBool:YES], MMFontPreserveLineSpacingKey,
[NSNumber numberWithBool:YES], MMLoginShellKey,
[NSNumber numberWithInt:MMRendererCoreText],
MMRendererKey,
[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,
[NSNumber numberWithBool:YES], MMDialogsTrackPwdKey,
[NSNumber numberWithInt:3], MMOpenLayoutKey,
[NSNumber numberWithBool:NO], MMVerticalSplitKey,
[NSNumber numberWithInt:0], MMPreloadCacheSizeKey,
[NSNumber numberWithInt:0], MMLastWindowClosedBehaviorKey,
#ifdef INCLUDE_OLD_IM_CODE
[NSNumber numberWithBool:YES], MMUseInlineImKey,
#endif // INCLUDE_OLD_IM_CODE
[NSNumber numberWithBool:NO], MMSuppressTerminationAlertKey,
[NSNumber numberWithBool:YES], MMNativeFullScreenKey,
[NSNumber numberWithDouble:0.0], MMFullScreenFadeTimeKey,
[NSNumber numberWithBool:NO], MMNonNativeFullScreenShowMenuKey,
[NSNumber numberWithInt:0], MMNonNativeFullScreenSafeAreaBehaviorKey,
[NSNumber numberWithBool:YES], MMShareFindPboardKey,
[NSNumber numberWithBool:NO], MMSmoothResizeKey,
[NSNumber numberWithBool:NO], MMCmdLineAlignBottomKey,
[NSNumber numberWithBool:NO], MMRendererClipToRowKey,
[NSNumber numberWithBool:YES], MMAllowForceClickLookUpKey,
[NSNumber numberWithBool:NO], MMUpdaterPrereleaseChannelKey,
@"", MMLastUsedBundleVersionKey,
[NSNumber numberWithBool:YES], MMShowWhatsNewOnStartupKey,
[NSNumber numberWithBool:0], MMScrollOneDirectionOnlyKey,
nil];
[ud registerDefaults:macvimDefaults];
NSArray<NSString *> *arguments = NSProcessInfo.processInfo.arguments;
if ([arguments containsObject:@"-IgnoreUserDefaults"]) {
NSDictionary<NSString *, id> *argDefaults = [ud volatileDomainForName:NSArgumentDomain];
NSMutableDictionary<NSString *, id> *combinedDefaults = [NSMutableDictionary dictionaryWithCapacity: macvimDefaults.count];
[combinedDefaults setDictionary:macvimDefaults];
[combinedDefaults addEntriesFromDictionary:argDefaults];
[ud setVolatileDomain:combinedDefaults forName:NSArgumentDomain];
}
}
+ (void)initialize
{
static BOOL initDone = NO;
@@ -176,7 +265,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
// 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
// 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.)
@@ -205,73 +294,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
[NSWindow setAllowsAutomaticWindowTabbing:NO];
}
int tabMinWidthKey;
int tabMaxWidthKey;
int tabOptimumWidthKey;
if (shouldUseYosemiteTabBarStyle()) {
tabMinWidthKey = 120;
tabMaxWidthKey = 0;
tabOptimumWidthKey = 0;
} else {
tabMinWidthKey = 64;
tabMaxWidthKey = 6*64;
tabOptimumWidthKey = 132;
}
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], MMNoWindowKey,
[NSNumber numberWithInt:tabMinWidthKey],
MMTabMinWidthKey,
[NSNumber numberWithInt:tabMaxWidthKey],
MMTabMaxWidthKey,
[NSNumber numberWithInt:tabOptimumWidthKey],
MMTabOptimumWidthKey,
[NSNumber numberWithBool:YES], MMShowAddTabButtonKey,
[NSNumber numberWithInt:2], MMTextInsetLeftKey,
[NSNumber numberWithInt:1], MMTextInsetRightKey,
[NSNumber numberWithInt:1], MMTextInsetTopKey,
[NSNumber numberWithInt:1], MMTextInsetBottomKey,
@"MMTypesetter", MMTypesetterKey,
[NSNumber numberWithFloat:1], MMCellWidthMultiplierKey,
[NSNumber numberWithFloat:-1], MMBaselineOffsetKey,
[NSNumber numberWithBool:YES], MMTranslateCtrlClickKey,
[NSNumber numberWithInt:0], MMOpenInCurrentWindowKey,
[NSNumber numberWithBool:NO], MMNoFontSubstitutionKey,
[NSNumber numberWithBool:YES], MMFontPreserveLineSpacingKey,
[NSNumber numberWithBool:YES], MMLoginShellKey,
[NSNumber numberWithInt:MMRendererCoreText],
MMRendererKey,
[NSNumber numberWithInt:MMUntitledWindowAlways],
MMUntitledWindowKey,
[NSNumber numberWithBool:NO], MMNoWindowShadowKey,
[NSNumber numberWithBool:NO], MMZoomBothKey,
@"", MMLoginShellCommandKey,
@"", MMLoginShellArgumentKey,
[NSNumber numberWithBool:YES], MMDialogsTrackPwdKey,
[NSNumber numberWithInt:3], MMOpenLayoutKey,
[NSNumber numberWithBool:NO], MMVerticalSplitKey,
[NSNumber numberWithInt:0], MMPreloadCacheSizeKey,
[NSNumber numberWithInt:0], MMLastWindowClosedBehaviorKey,
#ifdef INCLUDE_OLD_IM_CODE
[NSNumber numberWithBool:YES], MMUseInlineImKey,
#endif // INCLUDE_OLD_IM_CODE
[NSNumber numberWithBool:NO], MMSuppressTerminationAlertKey,
[NSNumber numberWithBool:YES], MMNativeFullScreenKey,
[NSNumber numberWithDouble:0.0], MMFullScreenFadeTimeKey,
[NSNumber numberWithBool:NO], MMNonNativeFullScreenShowMenuKey,
[NSNumber numberWithInt:0], MMNonNativeFullScreenSafeAreaBehaviorKey,
[NSNumber numberWithBool:YES], MMShareFindPboardKey,
[NSNumber numberWithBool:NO], MMSmoothResizeKey,
[NSNumber numberWithBool:NO], MMCmdLineAlignBottomKey,
[NSNumber numberWithBool:NO], MMRendererClipToRowKey,
[NSNumber numberWithBool:YES], MMAllowForceClickLookUpKey,
[NSNumber numberWithBool:NO], MMUpdaterPrereleaseChannelKey,
@"", MMLastUsedBundleVersionKey,
[NSNumber numberWithBool:YES], MMShowWhatsNewOnStartupKey,
[NSNumber numberWithBool:0], MMScrollOneDirectionOnlyKey,
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
[MMAppController registerDefaults];
NSArray *types = [NSArray arrayWithObject:NSPasteboardTypeString];
[NSApp registerServicesMenuSendTypes:types returnTypes:types];
@@ -1296,25 +1319,60 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
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
+1 -1
View File
@@ -232,7 +232,7 @@
// This makes windows animate when opened
if ([win respondsToSelector:@selector(setAnimationBehavior:)]) {
if (![[NSUserDefaults standardUserDefaults]
boolForKey:MMDisableLaunchAnimation]) {
boolForKey:MMDisableLaunchAnimationKey]) {
[win setAnimationBehavior:NSWindowAnimationBehaviorDocumentWindow];
}
}
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -34,7 +34,7 @@ NSString *MMAppearanceModeSelectionKey = @"MMAppearanceModeSelection";
NSString *MMNoTitleBarWindowKey = @"MMNoTitleBarWindow";
NSString *MMTitlebarAppearsTransparentKey = @"MMTitlebarAppearsTransparent";
NSString *MMNoWindowShadowKey = @"MMNoWindowShadow";
NSString *MMDisableLaunchAnimation = @"MMDisableLaunchAnimation";
NSString *MMDisableLaunchAnimationKey = @"MMDisableLaunchAnimation";
NSString *MMLoginShellKey = @"MMLoginShell";
NSString *MMUntitledWindowKey = @"MMUntitledWindow";
NSString *MMZoomBothKey = @"MMZoomBoth";
+9
View File
@@ -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"; */
@@ -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"; */
@@ -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"; */