aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBibiko <bibiko@eva.mpg.de>2010-01-21 10:15:31 +0000
committerBibiko <bibiko@eva.mpg.de>2010-01-21 10:15:31 +0000
commitbc01bc7bcfe8b332ffa638c0f89adb8f2e5f748a (patch)
tree31d2fa5a23313578b7bcd5bde47591c4fc0d01de /Source
parentce340132e43b5f0d90286704d1232f77f6ffbc8a (diff)
downloadsequelpro-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.m13
-rw-r--r--Source/SPNarrowDownCompletion.h1
-rw-r--r--Source/SPNarrowDownCompletion.m106
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