Pass arguments to Vim on command line

Do not pass arguments via DO since some options only work if the files
to open were passed on the command line (e.g. "%" flag in 'viminfo').
Also, if a file is encrypted and opened from Spotlight the Spotlight
search text is passed as input and it ends up being used as password for
the encryption key, so the file opens up encrypted.

The above problems still persist if Quickstart is enabled.
This commit is contained in:
Bjorn Winckler
2010-02-15 21:43:08 +01:00
parent 23cd926331
commit edefdc97f2
+109 -20
View File
@@ -117,7 +117,6 @@ typedef struct
#endif
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
replyEvent:(NSAppleEventDescriptor *)reply;
- (int)findLaunchingProcessWithoutArguments;
- (MMVimController *)findUnusedEditor;
- (NSMutableDictionary *)extractArgumentsFromOdocEvent:
(NSAppleEventDescriptor *)desc;
@@ -139,6 +138,8 @@ typedef struct
- (void)reapChildProcesses:(id)sender;
- (void)processInputQueues:(id)sender;
- (void)addVimController:(MMVimController *)vc;
- (NSDictionary *)convertVimControllerArguments:(NSDictionary *)args
toCommandLine:(NSArray **)cmdline;
- (NSScreen *)screenContainingPoint:(NSPoint)pt;
#ifdef MM_ENABLE_PLUGINS
@@ -1715,16 +1716,6 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
}
}
- (int)findLaunchingProcessWithoutArguments
{
NSArray *keys = [pidArguments allKeysForObject:[NSNull null]];
if ([keys count] > 0)
return [[keys objectAtIndex:0] intValue];
return -1;
}
- (MMVimController *)findUnusedEditor
{
NSEnumerator *e = [vimControllers objectEnumerator];
@@ -2021,6 +2012,9 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
MMVimController *vc = [self findUnusedEditor];
if (vc) {
// Open files in an already open window.
// TODO: If the file is encrypted (with -x) then opening in an unused
// window will fail if there are more arguments than just the filename
// (the same goes with cached Vim controllers).
[[[vc windowController] window] makeKeyAndOrderFront:self];
[vc passArguments:arguments];
} else if ((vc = [self takeVimControllerFromCache])) {
@@ -2030,15 +2024,12 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
[vc passArguments:arguments];
[[vc backendProxy] acknowledgeConnection];
} else {
// Open files in a launching Vim process or start a new process. This
// may take 1-2 seconds so there will be a visible delay before the
// window appears on screen.
int pid = [self findLaunchingProcessWithoutArguments];
if (-1 == pid) {
pid = [self launchVimProcessWithArguments:nil];
if (-1 == pid)
return NO;
}
NSArray *cmdline = nil;
arguments = [self convertVimControllerArguments:arguments
toCommandLine:&cmdline];
int pid = [self launchVimProcessWithArguments:cmdline];
if (-1 == pid)
return NO;
// TODO: If the Vim process fails to start, or if it changes PID,
// then the memory allocated for these parameters will leak.
@@ -2385,6 +2376,104 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
}
}
- (NSDictionary *)convertVimControllerArguments:(NSDictionary *)args
toCommandLine:(NSArray **)cmdline
{
// Take all arguments out of 'args' and put them on an array suitable to
// pass as arguments to launchVimProcessWithArguments:. The untouched
// dictionary items are returned in a new autoreleased dictionary.
if (cmdline)
*cmdline = nil;
NSArray *filenames = [args objectForKey:@"filenames"];
int numFiles = filenames ? [filenames count] : 0;
BOOL openFiles = ![[args objectForKey:@"dontOpen"] boolValue];
if (numFiles <= 0 || !openFiles)
return args;
NSMutableArray *a = [NSMutableArray array];
NSMutableDictionary *d = [[args mutableCopy] autorelease];
// Search for text using "+/text".
NSString *searchText = [args objectForKey:@"searchText"];
if (searchText) {
// TODO: If the search pattern is not found an error is shown when
// starting. Figure out a way to get rid of this message (The help
// says to use ':silent exe "normal /pat\<CR>"' but this does not
// work.)
[a addObject:[NSString stringWithFormat:@"+/%@", searchText]];
[d removeObjectForKey:@"searchText"];
}
// Position cursor using "+line" or "-c :cal cursor(line,column)".
NSString *lineString = [args objectForKey:@"cursorLine"];
if (lineString && [lineString intValue] > 0) {
NSString *columnString = [args objectForKey:@"cursorColumn"];
if (columnString && [columnString intValue] > 0) {
[a addObject:@"-c"];
[a addObject:[NSString stringWithFormat:@":cal cursor(%@,%@)",
lineString, columnString]];
[d removeObjectForKey:@"cursorColumn"];
} else {
[a addObject:[NSString stringWithFormat:@"+%@", lineString]];
}
[d removeObjectForKey:@"cursorLine"];
}
// Set selection using normal mode commands.
NSString *rangeString = [args objectForKey:@"selectionRange"];
if (rangeString) {
NSRange r = NSRangeFromString(rangeString);
[a addObject:@"-c"];
if (r.length > 0) {
// Select given range.
[a addObject:[NSString stringWithFormat:@"norm %dGV%dGz.0",
NSMaxRange(r), r.location]];
} else {
// Position cursor on start of range.
[a addObject:[NSString stringWithFormat:@"norm %dGz.0",
r.location]];
}
[d removeObjectForKey:@"selectionRange"];
}
// Choose file layout using "-[o|O|p]".
int layout = [[args objectForKey:@"layout"] intValue];
switch (layout) {
case MMLayoutHorizontalSplit: [a addObject:@"-o"]; break;
case MMLayoutVerticalSplit: [a addObject:@"-O"]; break;
case MMLayoutTabs: [a addObject:@"-p"]; break;
}
[d removeObjectForKey:@"layout"];
// Last of all add the names of all files to open (DO NOT add more args
// after this point).
[a addObjectsFromArray:filenames];
if ([args objectForKey:@"remoteID"]) {
// These files should be edited remotely so keep the filenames on the
// argument list -- they will need to be passed back to Vim when it
// checks in. Also set the 'dontOpen' flag or the files will be
// opened twice.
[d setObject:[NSNumber numberWithBool:YES] forKey:@"dontOpen"];
} else {
[d removeObjectForKey:@"dontOpen"];
[d removeObjectForKey:@"filenames"];
}
if (cmdline)
*cmdline = a;
return d;
}
- (NSScreen *)screenContainingPoint:(NSPoint)pt
{
NSArray *screens = [NSScreen screens];