From d2db0a95f5954ab8bf54b740d1b1c48ae2842adf Mon Sep 17 00:00:00 2001 From: Bjorn Winckler Date: Sun, 25 May 2008 19:22:12 +0200 Subject: [PATCH] Open and save dialogs track the Vim pwd Open and save dialogs will open up at the present working directory of the key Vim process. This can be disabled by setting the user default "MMDialogsTrackPwd" to 0. If disabled, these dialogs always open up at the last location browsed to (which is the default OS X behaviour). --- runtime/doc/gui_mac.txt | 3 ++- src/MacVim/MMAppController.m | 12 ++++++++++-- src/MacVim/MMBackend.m | 23 ++++++++++++++++++++++- src/MacVim/MMVimController.h | 2 ++ src/MacVim/MMVimController.m | 20 ++++++++++++++++++++ src/MacVim/MacVim.h | 10 ++++++++++ src/MacVim/MacVim.m | 25 +++++++++++++++++++++++++ 7 files changed, 91 insertions(+), 4 deletions(-) diff --git a/runtime/doc/gui_mac.txt b/runtime/doc/gui_mac.txt index a55e4522..afa7cba8 100644 --- a/runtime/doc/gui_mac.txt +++ b/runtime/doc/gui_mac.txt @@ -1,4 +1,4 @@ -*gui_mac.txt* For Vim version 7.1. Last change: 2008 May 19 +*gui_mac.txt* For Vim version 7.1. Last change: 2008 May 25 VIM REFERENCE MANUAL by Bjorn Winckler @@ -227,6 +227,7 @@ Here is a list of relevant dictionary entries: KEY VALUE ~ MMAtsuiRenderer enable ATSUI renderer [bool] MMCellWidthMultiplier width of a normal glyph in em units [float] +MMDialogsTrackPwd open/save dialogs track the Vim pwd [bool] MMLoginShellArgument login shell parameter [string] MMLoginShellCommand which shell to use to launch Vim [string] MMNoFontSubstitution disable automatic font substitution [bool] diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index 002bec6b..5a301cad 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -124,6 +124,7 @@ static int executeInLoginShell(NSString *path, NSArray *args); [NSNumber numberWithBool:NO], MMZoomBothKey, @"", MMLoginShellCommandKey, @"", MMLoginShellArgumentKey, + [NSNumber numberWithBool:YES], MMDialogsTrackPwdKey, nil]; [[NSUserDefaults standardUserDefaults] registerDefaults:dict]; @@ -554,10 +555,17 @@ static int executeInLoginShell(NSString *path, NSArray *args); - (IBAction)fileOpen:(id)sender { + NSString *dir = nil; + BOOL trackPwd = [[NSUserDefaults standardUserDefaults] + boolForKey:MMDialogsTrackPwdKey]; + if (trackPwd) { + MMVimController *vc = [self keyVimController]; + if (vc) dir = [[vc vimState] objectForKey:@"pwd"]; + } + NSOpenPanel *panel = [NSOpenPanel openPanel]; [panel setAllowsMultipleSelection:YES]; - - int result = [panel runModalForTypes:nil]; + int result = [panel runModalForDirectory:dir file:nil types:nil]; if (NSOKButton == result) [self application:NSApp openFiles:[panel filenames]]; } diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index aa87096a..608388bd 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -77,6 +77,7 @@ static NSString *MMSymlinkWarningString = @interface MMBackend (Private) +- (void)queueVimStateMessage; - (void)processInputQueue; - (void)handleInputEvent:(int)msgid data:(NSData *)data; + (NSDictionary *)specialKeys; @@ -462,7 +463,12 @@ static NSString *MMSymlinkWarningString = [drawData setLength:0]; } - if ([outputQueue count] > 0) { + if ([outputQueue count] > 0 || force) { + // When 'force' is set we always update the Vim state to ensure that + // MacVim has a copy of the latest state (since 'force' is typically + // set just before Vim takes a nap whilst waiting for input). + [self queueVimStateMessage]; + @try { [frontendProxy processCommandQueue:outputQueue]; } @@ -1555,6 +1561,21 @@ static NSString *MMSymlinkWarningString = @implementation MMBackend (Private) +- (void)queueVimStateMessage +{ + // NOTE: This is the place to add Vim state that needs to be accessed from + // MacVim. Do not add state that could potentially require lots of memory + // since this message gets sent each time the output queue is forcibly + // flushed (e.g. storing the currently selected text would be a bad idea). + // We take this approach of "pushing" the state to MacVim to avoid having + // to make synchronous calls from MacVim to Vim in order to get state. + NSDictionary *vimState = [NSDictionary dictionaryWithObjectsAndKeys: + [[NSFileManager defaultManager] currentDirectoryPath], @"pwd", + nil]; + + [self queueMessage:SetVimStateMsgID data:[vimState dictionaryAsData]]; +} + - (void)processInputQueue { // NOTE: One of the input events may cause this method to be called diff --git a/src/MacVim/MMVimController.h b/src/MacVim/MMVimController.h index 59bd4dd3..74ef1069 100644 --- a/src/MacVim/MMVimController.h +++ b/src/MacVim/MMVimController.h @@ -42,6 +42,7 @@ NSMenu *lastMenuSearched; NSMenuItem *recentFilesMenuItem; NSMenuItem *recentFilesDummy; + NSDictionary *vimState; } - (id)initWithBackend:(id)backend pid:(int)processIdentifier @@ -51,6 +52,7 @@ - (void)setServerName:(NSString *)name; - (NSString *)serverName; - (MMWindowController *)windowController; +- (NSDictionary *)vimState; - (void)cleanup; - (void)dropFiles:(NSArray *)filenames forceOpen:(BOOL)force; - (void)dropString:(NSString *)string; diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index 4385ac7d..498a6554 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -152,6 +152,11 @@ static NSTimeInterval MMResendInterval = 0.5; return windowController; } +- (NSDictionary *)vimState +{ + return vimState; +} + - (void)setServerName:(NSString *)name { if (name != serverName) { @@ -391,6 +396,15 @@ static NSTimeInterval MMResendInterval = 0.5; { if (!isInitialized) return; + if (!dir) { + // 'dir == nil' means: set dir to the pwd of the Vim process, or let + // open dialog decide (depending on the below user default). + BOOL trackPwd = [[NSUserDefaults standardUserDefaults] + boolForKey:MMDialogsTrackPwdKey]; + if (trackPwd) + dir = [vimState objectForKey:@"pwd"]; + } + if (saving) { [[NSSavePanel savePanel] beginSheetForDirectory:dir file:nil modalForWindow:[windowController window] @@ -916,6 +930,12 @@ static NSTimeInterval MMResendInterval = 0.5; [[[windowController vimView] textView] setAntialias:YES]; } else if (DisableAntialiasMsgID == msgid) { [[[windowController vimView] textView] setAntialias:NO]; + } else if (SetVimStateMsgID == msgid) { + NSDictionary *dict = [NSDictionary dictionaryWithData:data]; + if (dict) { + [vimState release]; + vimState = [dict retain]; + } } else { NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid); } diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index ffc94016..eb94dd9c 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -162,6 +162,7 @@ enum { LiveResizeMsgID, EnableAntialiasMsgID, DisableAntialiasMsgID, + SetVimStateMsgID, }; @@ -226,6 +227,7 @@ extern NSString *MMZoomBothKey; extern NSString *MMCurrentPreferencePaneKey; extern NSString *MMLoginShellCommandKey; extern NSString *MMLoginShellArgumentKey; +extern NSString *MMDialogsTrackPwdKey; // Enum for MMUntitledWindowKey enum { @@ -283,6 +285,14 @@ NSString *buildSearchTextCommand(NSString *searchText); +@interface NSDictionary (MMExtras) ++ (id)dictionaryWithData:(NSData *)data; +- (NSData *)dictionaryAsData; +@end + + + + // ODB Editor Suite Constants (taken from ODBEditorSuite.h) #define keyFileSender 'FSnd' #define keyFileSenderToken 'FTok' diff --git a/src/MacVim/MacVim.m b/src/MacVim/MacVim.m index 9c249523..d8b1c470 100644 --- a/src/MacVim/MacVim.m +++ b/src/MacVim/MacVim.m @@ -75,6 +75,7 @@ char *MessageStrings[] = "LiveResizeMsgID", "EnableAntialiasMsgID", "DisableAntialiasMsgID", + "SetVimStateMsgID", }; @@ -106,6 +107,7 @@ NSString *MMZoomBothKey = @"MMZoomBoth"; NSString *MMCurrentPreferencePaneKey = @"MMCurrentPreferencePane"; NSString *MMLoginShellCommandKey = @"MMLoginShellCommand"; NSString *MMLoginShellArgumentKey = @"MMLoginShellArgument"; +NSString *MMDialogsTrackPwdKey = @"MMDialogsTrackPwd"; @@ -307,3 +309,26 @@ buildSearchTextCommand(NSString *searchText) @end // NSDocumentController (MMExtras) + + + +@implementation NSDictionary (MMExtras) + ++ (id)dictionaryWithData:(NSData *)data +{ + id plist = [NSPropertyListSerialization + propertyListFromData:data + mutabilityOption:NSPropertyListImmutable + format:NULL + errorDescription:NULL]; + + return [plist isKindOfClass:[NSDictionary class]] ? plist : nil; +} + +- (NSData *)dictionaryAsData +{ + return [NSPropertyListSerialization dataFromPropertyList:self + format:NSPropertyListBinaryFormat_v1_0 errorDescription:NULL]; +} + +@end -- 2.11.4.GIT