diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index 46781a6413..20c8b88d8a 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -1734,8 +1734,12 @@ fsEventCallback(ConstFSEventStreamRef streamRef, // 3. Extract Spotlight search text (if any) NSAppleEventDescriptor *spotlightdesc = [desc paramDescriptorForKeyword:keyAESearchText]; - if (spotlightdesc) - [dict setObject:[spotlightdesc stringValue] forKey:@"searchText"]; + if (spotlightdesc) { + NSString *s = [[spotlightdesc stringValue] + stringBySanitizingSpotlightSearch]; + if (s && [s length] > 0) + [dict setObject:s forKey:@"searchText"]; + } return dict; } @@ -2257,14 +2261,14 @@ fsEventCallback(ConstFSEventStreamRef streamRef, NSMutableArray *a = [NSMutableArray array]; NSMutableDictionary *d = [[args mutableCopy] autorelease]; - // Search for text using "+/text". + // Search for text and highlight it (this Vim script avoids warnings in + // case there is no match for the search 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\"' but this does not - // work.) - [a addObject:[NSString stringWithFormat:@"+/%@", searchText]]; + if (searchText && [searchText length] > 0) { + [a addObject:@"-c"]; + NSString *s = [NSString stringWithFormat:@"if search('\\V\\c%@','cW')" + "|let @/='\\V\\c%@'|set hls|endif", searchText, searchText]; + [a addObject:s]; [d removeObjectForKey:@"searchText"]; } diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index 8da90b5239..d0467f51d4 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -2814,8 +2814,11 @@ static void netbeansReadCallback(CFSocketRef s, NSString *searchText = [args objectForKey:@"searchText"]; if (searchText) { - [self addInput:[NSString stringWithFormat:@"gg/\\c%@/e", - searchText]]; + // NOTE: This command may be overkill to simply search for some text, + // but it is consistent with what is used in MMAppController. + [self addInput:[NSString stringWithFormat:@":if search(" + "'\\V\\c%@','cW')|let @/='\\V\\c%@'|set hls|endif", + searchText, searchText]]; } } diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index e457453b2e..37fc3fb7ef 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -263,6 +263,7 @@ extern NSString *VimFindPboardType; @interface NSString (MMExtras) - (NSString *)stringByEscapingSpecialFilenameCharacters; - (NSString *)stringByRemovingFindPatterns; +- (NSString *)stringBySanitizingSpotlightSearch; @end diff --git a/src/MacVim/MacVim.m b/src/MacVim/MacVim.m index b810529778..7dc1cd7595 100644 --- a/src/MacVim/MacVim.m +++ b/src/MacVim/MacVim.m @@ -233,6 +233,39 @@ debugStringForMessageQueue(NSArray *queue) return [string autorelease]; } +- (NSString *)stringBySanitizingSpotlightSearch +{ + // Limit length of search text + NSUInteger len = [self length]; + if (len > 1024) len = 1024; + else if (len == 0) return self; + + NSMutableString *string = [[[self substringToIndex:len] mutableCopy] + autorelease]; + + // Ignore strings with control characters + NSCharacterSet *controlChars = [NSCharacterSet controlCharacterSet]; + NSRange r = [string rangeOfCharacterFromSet:controlChars]; + if (r.location != NSNotFound) + return nil; + + // Replace ' with '' since it is used as a string delimeter in the command + // that we pass on to Vim to perform the search. + [string replaceOccurrencesOfString:@"'" + withString:@"''" + options:NSLiteralSearch + range:NSMakeRange(0, [string length])]; + + // Replace \ with \\ to avoid Vim interpreting it as the beginning of a + // character class. + [string replaceOccurrencesOfString:@"\\" + withString:@"\\\\" + options:NSLiteralSearch + range:NSMakeRange(0, [string length])]; + + return string; +} + @end // NSString (MMExtras)