diff options
author | Bibiko <bibiko@eva.mpg.de> | 2010-01-21 10:15:31 +0000 |
---|---|---|
committer | Bibiko <bibiko@eva.mpg.de> | 2010-01-21 10:15:31 +0000 |
commit | bc01bc7bcfe8b332ffa638c0f89adb8f2e5f748a (patch) | |
tree | 31d2fa5a23313578b7bcd5bde47591c4fc0d01de /Source | |
parent | ce340132e43b5f0d90286704d1232f77f6ffbc8a (diff) | |
download | sequelpro-bc01bc7bcfe8b332ffa638c0f89adb8f2e5f748a.tar.gz sequelpro-bc01bc7bcfe8b332ffa638c0f89adb8f2e5f748a.tar.bz2 sequelpro-bc01bc7bcfe8b332ffa638c0f89adb8f2e5f748a.zip |
• completion
- CTRL+ESC invokes the fuzzy search completion; eg:
i_s.pcss. will show all fields from `information_schema`.`PROCESSLIST`. if no other matches are found; the search is a regexp ".*?i.*?_.*?s.*?\. …" etc. by using RegexKitLite which is much more faster than NSPredicate and can handle long regexps
- improved type display: if a type definition contains a , split it to avoid splitting of the tokenFields
- while insertion of an item and holding down the CTRL key the list keeps open to allow to insert more suggestions separated by ", " from the current list (very useful if one wants to insert only selected fields from a table)
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMTextView.m | 13 | ||||
-rw-r--r-- | Source/SPNarrowDownCompletion.h | 1 | ||||
-rw-r--r-- | Source/SPNarrowDownCompletion.m | 106 |
3 files changed, 79 insertions, 41 deletions
diff --git a/Source/CMTextView.m b/Source/CMTextView.m index 1cceac97..7378253a 100644 --- a/Source/CMTextView.m +++ b/Source/CMTextView.m @@ -304,7 +304,9 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) for(id field in sortedFields) { if(![field hasPrefix:@" "]) { NSString *typ = [theTable objectForKey:field]; - if(typ && [typ hasPrefix:@"set("] || [typ hasPrefix:@"enum("]) { + // Check if type definition contains a , if so replace the bracket content by … and add + // the bracket content as "list" key to prevend the token field to split them by , + if(typ && [typ rangeOfString:@","].length) { NSString *t = [typ stringByReplacingOccurrencesOfRegex:@"\\(.*?\\)" withString:@"(…)"]; NSString *lst = [typ stringByMatching:@"\\(([^\\)]*?)\\)" capture:1L]; [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys: @@ -541,7 +543,6 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) if(fuzzySearch) { filter = [[NSString stringWithString:[[self string] substringWithRange:parseRange]] stringByReplacingOccurrencesOfString:@"`" withString:@""]; - if([filter length]>15) return; completionRange = parseRange; } @@ -814,10 +815,10 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) long curFlags = ([theEvent modifierFlags] & allFlags); if ([theEvent keyCode] == 53){ // ESC key for internal completion - // if(curFlags==(NSControlKeyMask)) - // [self doCompletionByUsingSpellChecker:NO fuzzyMode:YES]; - // else - [self doCompletionByUsingSpellChecker:NO fuzzyMode:NO]; + if(curFlags==(NSControlKeyMask)) + [self doCompletionByUsingSpellChecker:NO fuzzyMode:YES]; + else + [self doCompletionByUsingSpellChecker:NO fuzzyMode:NO]; // Remove that attribute to suppress auto-uppercasing of certain keyword combinations if(![self selectedRange].length && [self selectedRange].location) [[self textStorage] removeAttribute:kSQLkeyword range:[self getRangeForCurrentWord]]; diff --git a/Source/SPNarrowDownCompletion.h b/Source/SPNarrowDownCompletion.h index f8f12a83..1927b671 100644 --- a/Source/SPNarrowDownCompletion.h +++ b/Source/SPNarrowDownCompletion.h @@ -47,6 +47,7 @@ BOOL fuzzyMode; BOOL noFilterString; BOOL cursorMovedLeft; + BOOL commaInsertionMode; NSInteger backtickMode; NSFont *tableFont; NSRange theCharRange; diff --git a/Source/SPNarrowDownCompletion.m b/Source/SPNarrowDownCompletion.m index 80d8c20c..cc941924 100644 --- a/Source/SPNarrowDownCompletion.m +++ b/Source/SPNarrowDownCompletion.m @@ -33,6 +33,7 @@ #import "SPStringAdditions.h" #import "ImageAndTextCell.h" #import "SPConstants.h" +#import "RegexKitLite.h" #include <tgmath.h> @interface NSTableView (MovingSelectedRow) @@ -151,6 +152,7 @@ dbStructureMode = theDbMode; cursorMovedLeft = caretMovedLeft; backtickMode = theBackTickMode; + commaInsertionMode = NO; if(aStaticPrefix) staticPrefix = [aStaticPrefix retain]; @@ -299,6 +301,9 @@ [b setAltersStateOfSelectedItem:NO]; [b setControlSize:NSMiniControlSize]; NSMenu *m = [[NSMenu alloc] init]; + NSMenuItem *aMenuItem = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Type Declaration:", @"type declaration header") action:NULL keyEquivalent:@""] autorelease]; + [aMenuItem setEnabled:NO]; + [m addItem:aMenuItem]; [m addItemWithTitle:[[filtered objectAtIndex:rowIndex] objectForKey:@"list"] action:NULL keyEquivalent:@""]; [b setMenu:m]; [m release]; @@ -385,38 +390,45 @@ [newFiltered addObject:[NSDictionary dictionaryWithObjectsAndKeys:w, @"display", nil]]; } else { @try{ - NSPredicate* predicate; - if(fuzzyMode) { - NSMutableString *fuzzyRegexp = [[NSMutableString alloc] initWithCapacity:3]; - [fuzzyRegexp setString:@".*"]; - NSInteger i; - unichar c; - for(i=0; i<[[self filterString] length]; i++) { - if(i>20) break; - c = [[self filterString] characterAtIndex:i]; - if(c != '`') { - if(c == '.' || c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}') - [fuzzyRegexp appendString:[NSString stringWithFormat:@"\\%c.*",c]]; - else - [fuzzyRegexp appendString:[NSString stringWithFormat:@"%c.*",c]]; + if(fuzzyMode) { // eg filter = "inf" this regexp search will be performed: (?i).*?i.*?n.*?f + + NSMutableString *fuzzyRegexp = [[NSMutableString alloc] initWithCapacity:3]; + NSInteger i; + unichar c; + + if(!caseSensitive) + [fuzzyRegexp setString:@"(?i)"]; + + for(i=0; i<[[self filterString] length]; i++) { + c = [[self filterString] characterAtIndex:i]; + if(c != '`') { + if(c == '.' || c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}') + [fuzzyRegexp appendString:[NSString stringWithFormat:@".*?\\%c",c]]; + else + [fuzzyRegexp appendString:[NSString stringWithFormat:@".*?%c",c]]; + } } + + for(id s in suggestions) + if([[s objectForKey:@"display"] isMatchedByRegex:fuzzyRegexp] || [[s objectForKey:@"isRef"] isMatchedByRegex:fuzzyRegexp]) + [newFiltered addObject:s]; + + + [fuzzyRegexp release]; + + } else { + NSPredicate* predicate; + if(caseSensitive) + predicate = [NSPredicate predicateWithFormat:@"match BEGINSWITH %@ OR (match == NULL AND display BEGINSWITH %@)", [self filterString], [self filterString]]; + else + predicate = [NSPredicate predicateWithFormat:@"match BEGINSWITH[c] %@ OR (match == NULL AND display BEGINSWITH[c] %@)", [self filterString], [self filterString]]; + [newFiltered addObjectsFromArray:[suggestions filteredArrayUsingPredicate:predicate]]; } - // NSLog(@"re %@", fuzzyRegexp); - if(caseSensitive) - predicate = [NSPredicate predicateWithFormat:@"display MATCHES %@ OR isRef MATCHES %@", fuzzyRegexp, fuzzyRegexp]; - else - predicate = [NSPredicate predicateWithFormat:@"display MATCHES[c] %@ OR isRef MATCHES[c] %@", fuzzyRegexp, fuzzyRegexp]; - [fuzzyRegexp release]; - } else { - if(caseSensitive) - predicate = [NSPredicate predicateWithFormat:@"match BEGINSWITH %@ OR (match == NULL AND display BEGINSWITH %@)", [self filterString], [self filterString]]; - else - predicate = [NSPredicate predicateWithFormat:@"match BEGINSWITH[c] %@ OR (match == NULL AND display BEGINSWITH[c] %@)", [self filterString], [self filterString]]; - } - [newFiltered addObjectsFromArray:[suggestions filteredArrayUsingPredicate:predicate]]; } @catch(id ae) { + if(newFiltered) [newFiltered release]; NSLog(@"%@", @"Couldn't filter suggestion due to internal regexp error"); + closeMe = YES; } } @@ -513,19 +525,29 @@ if (([event modifierFlags] & (NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask)) == NSAlternateKeyMask || [[event characters] length] == 0) { [NSApp sendEvent: event]; + + if(commaInsertionMode) + break; + [mutablePrefix appendString:[event characters]]; theCharRange = NSMakeRange(theCharRange.location, theCharRange.length+[[event characters] length]); theParseRange = NSMakeRange(theParseRange.location, theParseRange.length+[[event characters] length]); [self filter]; } - else if((flags & NSControlKeyMask) || (flags & NSAlternateKeyMask) || (flags & NSCommandKeyMask)) + else if((flags & NSAlternateKeyMask) || (flags & NSCommandKeyMask)) { [NSApp sendEvent:event]; break; } else if([event keyCode] == 53) // escape { - break; + if(flags & NSControlKeyMask) { + fuzzyMode = YES; + [theTableView setBackgroundColor:[NSColor colorWithCalibratedRed:0.9f green:0.9f blue:0.9f alpha:1.0f]]; + [self filter]; + } else { + break; + } } else if(key == NSCarriageReturnCharacter || key == NSTabCharacter) { @@ -534,20 +556,24 @@ else if(key == NSBackspaceCharacter || key == NSDeleteCharacter) { [NSApp sendEvent:event]; - if([mutablePrefix length] == 0) + if([mutablePrefix length] == 0 || commaInsertionMode) break; [mutablePrefix deleteCharactersInRange:NSMakeRange([mutablePrefix length]-1, 1)]; - theCharRange = NSMakeRange(theCharRange.location, theCharRange.length-1); - theParseRange = NSMakeRange(theParseRange.location, theParseRange.length-1); + theCharRange.length--; + theParseRange.length--; [self filter]; } else if([textualInputCharacters characterIsMember:key]) { [NSApp sendEvent:event]; + + if(commaInsertionMode) + break; + [mutablePrefix appendString:[event characters]]; - theCharRange = NSMakeRange(theCharRange.location, theCharRange.length+1); - theParseRange = NSMakeRange(theParseRange.location, theParseRange.length+1); + theCharRange.length++; + theParseRange.length++; [self filter]; [self insertCommonPrefix]; } @@ -663,7 +689,17 @@ } } } - closeMe = YES; + + // Pressing CTRL while inserting an item the suggestion list keeps open + // to allow to add more field/table names comma separated + if([selectedItem objectForKey:@"isRef"] && [[NSApp currentEvent] modifierFlags] & (NSControlKeyMask)) { + [theView insertText:@", "]; + theCharRange = [theView selectedRange]; + theParseRange = [theView selectedRange]; + commaInsertionMode = YES; + } else { + closeMe = YES; + } } @end |