Skip to content

Commit 109e14a

Browse files
committed
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.
1 parent b0ba0b9 commit 109e14a

8 files changed

+135
-54
lines changed

runtime/doc/gui_mac.txt

+4
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,10 @@ Vim options (see |macvim-options|). These settings are stored in the user
264264
defaults database and can be accessed via the "MacVim.Settings…"
265265
("MacVim.Preferences…" in macOS 12 Monterey and older) menu item.
266266

267+
If you want to open MacVim with its default settings, you can open it by
268+
passing `-IgnoreUserDefaults 1` to the launch arguments (see the man page on
269+
the "open" for how to do so).
270+
267271
*macvim-user-defaults*
268272
Not all entries in the user defaults database are exposed via the settings
269273
panel, usually because they should not be changed by the user under normal
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
menutrans New\ Clean\ Window 新規クリーンウインドウ
2+
menutrans New\ Clean\ Window\ (No\ Defaults) 新規クリーンウインドウ\ (デフォルトなし)
13
menutrans MacVim\ Help MacVim\ ヘルプ
24
menutrans MacVim\ Website MacVim\ Webサイト
35
menutrans Vim\ Tutor Vim\ 教本\ (チュートリアル)
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
menutrans New\ Clean\ Window 新建干净窗口
2+
menutrans New\ Clean\ Window\ (No\ Defaults) 新建干净窗口(不用\ Defaults)
13
menutrans MacVim\ Help MacVim帮助
24
menutrans MacVim\ Website MacVim网站
35
menutrans Vim\ Tutor Vim教程
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
menutrans New\ Clean\ Window 新增乾淨視窗
2+
menutrans New\ Clean\ Window\ (No\ Defaults) 新增乾淨視窗(不用\ Defaults)
13
menutrans MacVim\ Help MacVim輔助說明
24
menutrans MacVim\ Website MacVim網站
35
menutrans Vim\ Tutor Vim教程

runtime/menu.vim

+6-2
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ enddef
160160

161161
" File menu
162162
if has("gui_macvim")
163-
an <silent> 10.290 &File.New\ Window <Nop>
163+
an <silent> 10.290 &File.New\ Window <Nop>
164+
an <silent> 10.291 &File.New\ Clean\ Window <Nop>
165+
an <silent> 10.292 &File.New\ Clean\ Window\ (No\ Defaults) <Nop>
164166
an 10.295 &File.New\ Tab :tabnew<CR>
165167
tln 10.295 &File.New\ Tab <C-W>:tabnew<CR>
166168
an <silent> 10.310 &File.Open… <Nop>
@@ -1267,6 +1269,8 @@ if has("gui_macvim")
12671269
" action message is specified here via the :macmenu command.
12681270
"
12691271
macm File.New\ Window key=<D-n> action=newWindow:
1272+
macm File.New\ Clean\ Window key=<D-N> action=newWindowClean:
1273+
macm File.New\ Clean\ Window\ (No\ Defaults) key=<D-M-N> action=newWindowCleanNoDefaults: alt=YES
12701274
macm File.New\ Tab key=<D-t>
12711275
macm File.Open… key=<D-o> action=fileOpen:
12721276
macm File.Open\ Tab\.\.\.<Tab>:tabnew key=<D-T>
@@ -1417,4 +1421,4 @@ if has("touchbar")
14171421
endif
14181422
endif
14191423

1420-
" vim: set sw=2 :
1424+
" vim: set sw=2 tabstop=8 :

src/MacVim/Actions.plist

+10-6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
<string></string>
3737
<key>newWindow:</key>
3838
<string></string>
39+
<key>newWindowClean:</key>
40+
<string></string>
41+
<key>newWindowCleanNoDefaults:</key>
42+
<string></string>
3943
<key>openWebsite:</key>
4044
<string></string>
4145
<key>showWhatsNew:</key>
@@ -86,11 +90,11 @@
8690
<string></string>
8791
<key>stayLevelNormal:</key>
8892
<string></string>
89-
<key>_removeWindowFromStageManagerSet:</key>
90-
<string></string>
91-
<key>joinAllStageManagerSets:</key>
92-
<string></string>
93-
<key>unjoinAllStageManagerSets:</key>
94-
<string></string>
93+
<key>_removeWindowFromStageManagerSet:</key>
94+
<string></string>
95+
<key>joinAllStageManagerSets:</key>
96+
<string></string>
97+
<key>unjoinAllStageManagerSets:</key>
98+
<string></string>
9599
</dict>
96100
</plist>

src/MacVim/MMAppController.h

+16
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232
, NSMenuItemValidation
3333
#endif
3434
> {
35+
enum NewWindowMode {
36+
NewWindowNormal = 0,
37+
NewWindowClean,
38+
NewWindowCleanNoDefaults,
39+
};
40+
3541
NSConnection *connection;
3642
NSMutableArray *vimControllers;
3743
NSString *openSelectionString;
@@ -82,12 +88,19 @@
8288
- (void)refreshAllResizeConstraints;
8389
- (void)refreshAllTextViews;
8490

91+
- (void)openNewWindow:(enum NewWindowMode)mode activate:(BOOL)activate;
92+
8593
//
8694
// NSMenuItemValidation
8795
//
8896
- (BOOL)validateMenuItem:(NSMenuItem *)item;
8997

98+
//
99+
// Actions exposed to Vim
100+
//
90101
- (IBAction)newWindow:(id)sender;
102+
- (IBAction)newWindowClean:(id)sender;
103+
- (IBAction)newWindowCleanNoDefaults:(id)sender;
91104
- (IBAction)newWindowAndActivate:(id)sender;
92105
- (IBAction)fileOpen:(id)sender;
93106
- (IBAction)selectNextWindow:(id)sender;
@@ -105,6 +118,9 @@
105118
- (IBAction)stayInBack:(id)sender;
106119
- (IBAction)stayLevelNormal:(id)sender;
107120

121+
//
122+
// NSUserInterfaceItemSearching
123+
//
108124
- (NSArray<NSString *> *)localizedTitlesForItem:(id)item;
109125
- (void)searchForItemsWithSearchString:(NSString *)searchString
110126
resultLimit:(NSInteger)resultLimit

src/MacVim/MMAppController.m

+93-46
Original file line numberDiff line numberDiff line change
@@ -166,45 +166,11 @@ - (void)inputSourceChanged:(NSNotification *)notification;
166166

167167
@implementation MMAppController
168168

169-
+ (void)initialize
169+
/// Register the default settings for MacVim. Supports an optional
170+
/// "-IgnoreUserDefaults 1" command-line argument, which will override
171+
/// persisted user settings to have a clean environment.
172+
+ (void)registerDefaults
170173
{
171-
static BOOL initDone = NO;
172-
if (initDone) return;
173-
initDone = YES;
174-
175-
ASLInit();
176-
177-
// HACK! The following user default must be reset, else Ctrl-q (or
178-
// whichever key is specified by the default) will be blocked by the input
179-
// manager (interpretKeyEvents: swallows that key). (We can't use
180-
// NSUserDefaults since it only allows us to write to the registration
181-
// domain and this preference has "higher precedence" than that so such a
182-
// change would have no effect.)
183-
CFPreferencesSetAppValue(CFSTR("NSQuotedKeystrokeBinding"),
184-
CFSTR(""),
185-
kCFPreferencesCurrentApplication);
186-
187-
// Also disable NSRepeatCountBinding -- it is not enabled by default, but
188-
// it does not make much sense to support it since Vim has its own way of
189-
// dealing with repeat counts.
190-
CFPreferencesSetAppValue(CFSTR("NSRepeatCountBinding"),
191-
CFSTR(""),
192-
kCFPreferencesCurrentApplication);
193-
194-
if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)]) {
195-
// Disable automatic tabbing on 10.12+. MacVim already has its own
196-
// tabbing interface, so we don't want multiple hierarchy of tabs mixing
197-
// native and Vim tabs. MacVim also doesn't work well with native tabs
198-
// right now since it doesn't respond well to the size change, and it
199-
// doesn't show the native menu items (e.g. move tab to new window) in
200-
// all the tabs.
201-
//
202-
// Note: MacVim cannot use macOS native tabs for Vim tabs because Vim
203-
// assumes only one tab can be shown at a time, and it would be hard to
204-
// handle native tab's "move tab to a new window" functionality.
205-
[NSWindow setAllowsAutomaticWindowTabbing:NO];
206-
}
207-
208174
int tabMinWidthKey;
209175
int tabMaxWidthKey;
210176
int tabOptimumWidthKey;
@@ -218,7 +184,9 @@ + (void)initialize
218184
tabOptimumWidthKey = 132;
219185
}
220186

221-
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
187+
NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;
188+
189+
NSDictionary *macvimDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
222190
[NSNumber numberWithBool:NO], MMNoWindowKey,
223191
[NSNumber numberWithInt:tabMinWidthKey],
224192
MMTabMinWidthKey,
@@ -244,6 +212,9 @@ + (void)initialize
244212
[NSNumber numberWithInt:MMUntitledWindowAlways],
245213
MMUntitledWindowKey,
246214
[NSNumber numberWithBool:NO], MMNoWindowShadowKey,
215+
[NSNumber numberWithInt:0], MMAppearanceModeSelectionKey,
216+
[NSNumber numberWithBool:NO], MMNoTitleBarWindowKey,
217+
[NSNumber numberWithBool:NO], MMTitlebarAppearsTransparentKey,
247218
[NSNumber numberWithBool:NO], MMZoomBothKey,
248219
@"", MMLoginShellCommandKey,
249220
@"", MMLoginShellArgumentKey,
@@ -271,7 +242,58 @@ + (void)initialize
271242
[NSNumber numberWithBool:0], MMScrollOneDirectionOnlyKey,
272243
nil];
273244

274-
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
245+
[ud registerDefaults:macvimDefaults];
246+
247+
NSArray<NSString *> *arguments = NSProcessInfo.processInfo.arguments;
248+
if ([arguments containsObject:@"-IgnoreUserDefaults"]) {
249+
NSDictionary<NSString *, id> *argDefaults = [ud volatileDomainForName:NSArgumentDomain];
250+
NSMutableDictionary<NSString *, id> *combinedDefaults = [NSMutableDictionary dictionaryWithCapacity: macvimDefaults.count];
251+
[combinedDefaults setDictionary:macvimDefaults];
252+
[combinedDefaults addEntriesFromDictionary:argDefaults];
253+
[ud setVolatileDomain:combinedDefaults forName:NSArgumentDomain];
254+
}
255+
}
256+
257+
+ (void)initialize
258+
{
259+
static BOOL initDone = NO;
260+
if (initDone) return;
261+
initDone = YES;
262+
263+
ASLInit();
264+
265+
// HACK! The following user default must be reset, else Ctrl-q (or
266+
// whichever key is specified by the default) will be blocked by the input
267+
// manager (interpreargumenttKeyEvents: swallows that key). (We can't use
268+
// NSUserDefaults since it only allows us to write to the registration
269+
// domain and this preference has "higher precedence" than that so such a
270+
// change would have no effect.)
271+
CFPreferencesSetAppValue(CFSTR("NSQuotedKeystrokeBinding"),
272+
CFSTR(""),
273+
kCFPreferencesCurrentApplication);
274+
275+
// Also disable NSRepeatCountBinding -- it is not enabled by default, but
276+
// it does not make much sense to support it since Vim has its own way of
277+
// dealing with repeat counts.
278+
CFPreferencesSetAppValue(CFSTR("NSRepeatCountBinding"),
279+
CFSTR(""),
280+
kCFPreferencesCurrentApplication);
281+
282+
if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)]) {
283+
// Disable automatic tabbing on 10.12+. MacVim already has its own
284+
// tabbing interface, so we don't want multiple hierarchy of tabs mixing
285+
// native and Vim tabs. MacVim also doesn't work well with native tabs
286+
// right now since it doesn't respond well to the size change, and it
287+
// doesn't show the native menu items (e.g. move tab to new window) in
288+
// all the tabs.
289+
//
290+
// Note: MacVim cannot use macOS native tabs for Vim tabs because Vim
291+
// assumes only one tab can be shown at a time, and it would be hard to
292+
// handle native tab's "move tab to a new window" functionality.
293+
[NSWindow setAllowsAutomaticWindowTabbing:NO];
294+
}
295+
296+
[MMAppController registerDefaults];
275297

276298
NSArray *types = [NSArray arrayWithObject:NSPasteboardTypeString];
277299
[NSApp registerServicesMenuSendTypes:types returnTypes:types];
@@ -1296,25 +1318,50 @@ - (BOOL)validateMenuItem:(NSMenuItem *)item
12961318
return YES;
12971319
}
12981320

1299-
- (IBAction)newWindow:(id)sender
1321+
/// Open a new Vim window, potentially taking from cached (if preload is used).
1322+
///
1323+
/// @param mode Determine whether to use clean mode or not. Preload will only
1324+
/// be used if using normal mode.
1325+
///
1326+
/// @param activate Activate the window after it's opened.
1327+
- (void)openNewWindow:(enum NewWindowMode)mode activate:(BOOL)activate
13001328
{
1301-
ASLogDebug(@"Open new window");
1329+
if (activate)
1330+
[self activateWhenNextWindowOpens];
13021331

13031332
// A cached controller requires no loading times and results in the new
13041333
// window popping up instantaneously. If the cache is empty it may take
13051334
// 1-2 seconds to start a new Vim process.
1306-
MMVimController *vc = [self takeVimControllerFromCache];
1335+
MMVimController *vc = (mode == NewWindowNormal) ? [self takeVimControllerFromCache] : nil;
13071336
if (vc) {
13081337
[[vc backendProxy] acknowledgeConnection];
13091338
} else {
1310-
[self launchVimProcessWithArguments:nil workingDirectory:nil];
1339+
NSArray *args = (mode == NewWindowNormal) ? nil
1340+
: (mode == NewWindowClean ? @[@"--clean"]
1341+
: @[@"--clean", @"-u", @"NONE"]);
1342+
[self launchVimProcessWithArguments:args workingDirectory:nil];
13111343
}
13121344
}
13131345

1346+
- (IBAction)newWindow:(id)sender
1347+
{
1348+
ASLogDebug(@"Open new window");
1349+
[self openNewWindow:NewWindowNormal activate:NO];
1350+
}
1351+
1352+
- (IBAction)newWindowClean:(id)sender
1353+
{
1354+
[self openNewWindow:NewWindowClean activate:NO];
1355+
}
1356+
1357+
- (IBAction)newWindowCleanNoDefaults:(id)sender
1358+
{
1359+
[self openNewWindow:NewWindowCleanNoDefaults activate:NO];
1360+
}
1361+
13141362
- (IBAction)newWindowAndActivate:(id)sender
13151363
{
1316-
[self activateWhenNextWindowOpens];
1317-
[self newWindow:sender];
1364+
[self openNewWindow:NewWindowNormal activate:YES];
13181365
}
13191366

13201367
- (IBAction)fileOpen:(id)sender

0 commit comments

Comments
 (0)