Skip to content

Commit

Permalink
Allow launching MacVim in clean defaults, add menu to open clean Vim
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ychin committed Oct 26, 2023
1 parent b0ba0b9 commit 53cfec9
Show file tree
Hide file tree
Showing 15 changed files with 197 additions and 59 deletions.
4 changes: 4 additions & 0 deletions runtime/doc/gui_mac.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions runtime/lang/macvim_menu/menu_ja_jp.utf-8.custom.vim
Original file line number Diff line number Diff line change
@@ -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\ 教本\ (チュートリアル)
2 changes: 2 additions & 0 deletions runtime/lang/macvim_menu/menu_zh_cn.utf-8.custom.vim
Original file line number Diff line number Diff line change
@@ -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教程
2 changes: 2 additions & 0 deletions runtime/lang/macvim_menu/menu_zh_tw.utf-8.custom.vim
Original file line number Diff line number Diff line change
@@ -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教程
8 changes: 6 additions & 2 deletions runtime/menu.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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.Open… key=<D-o> action=fileOpen:
macm File.Open\ Tab\.\.\.<Tab>:tabnew key=<D-T>
Expand Down Expand Up @@ -1417,4 +1421,4 @@ if has("touchbar")
endif
endif

" vim: set sw=2 :
" vim: set sw=2 tabstop=8 :
16 changes: 10 additions & 6 deletions src/MacVim/Actions.plist
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
21 changes: 19 additions & 2 deletions src/MacVim/Base.lproj/MainMenu.xib
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17156" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment version="1090" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17156"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
Expand Down Expand Up @@ -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"/>
Expand Down Expand Up @@ -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>
Expand Down
18 changes: 18 additions & 0 deletions src/MacVim/MMAppController.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
, NSMenuItemValidation
#endif
> {
enum NewWindowMode {
NewWindowNormal = 0,
NewWindowClean,
NewWindowCleanNoDefaults,
};

NSConnection *connection;
NSMutableArray *vimControllers;
NSString *openSelectionString;
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down
150 changes: 104 additions & 46 deletions src/MacVim/MMAppController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -271,7 +243,58 @@ + (void)initialize
[NSNumber numberWithBool:0], MMScrollOneDirectionOnlyKey,
nil];

[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
[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;
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];
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/MacVim/MMWindowController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/MacVim/Miscellaneous.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/MacVim/Miscellaneous.m
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Loading

0 comments on commit 53cfec9

Please sign in to comment.