aboutsummaryrefslogtreecommitdiffstats
path: root/Source/CMTextView.m
diff options
context:
space:
mode:
authorBibiko <bibiko@eva.mpg.de>2009-05-24 20:26:28 +0000
committerBibiko <bibiko@eva.mpg.de>2009-05-24 20:26:28 +0000
commit6df5d2147ef4ac72760a8ab776ab8a4d489aebe9 (patch)
tree3cef97edd3846b76ad49522e16716da83b561eb4 /Source/CMTextView.m
parent99e4d0223293aee1acd6b4196263385a9e6a7ecc (diff)
downloadsequelpro-6df5d2147ef4ac72760a8ab776ab8a4d489aebe9.tar.gz
sequelpro-6df5d2147ef4ac72760a8ab776ab8a4d489aebe9.tar.bz2
sequelpro-6df5d2147ef4ac72760a8ab776ab8a4d489aebe9.zip
• improved narrow-down completion
- added support for "in-quote completion" based on suggestions of the spell checker dict and the current used words in the textView - still bound to F5
Diffstat (limited to 'Source/CMTextView.m')
-rw-r--r--Source/CMTextView.m56
1 files changed, 43 insertions, 13 deletions
diff --git a/Source/CMTextView.m b/Source/CMTextView.m
index 7ab696db..f2b80a16 100644
--- a/Source/CMTextView.m
+++ b/Source/CMTextView.m
@@ -108,7 +108,21 @@ YY_BUFFER_STATE yy_scan_string (const char *);
mySQLmajorVersion = majorVersion;
}
-- (NSArray *)suggestionsForSQLCompletionWith:(NSString *)currentWord
+/*
+ * Sort function (mainly used to sort the words in the textView)
+ */
+NSInteger alphabeticSort(id string1, id string2, void *reverse)
+{
+ return [string1 localizedCaseInsensitiveCompare:string2];
+}
+
+/*
+ * Return an array of NSDictionary containing the sorted strings representing
+ * the set of unique words, SQL keywords, user-defined funcs/procs, tables etc.
+ * NSDic key "display" := the displayed and to be inserted word
+ * NSDic key "image" := an image to be shown left from "display" (optional)
+ */
+- (NSArray *)suggestionsForSQLCompletionWith:(NSString *)currentWord dictMode:(BOOL)isDictMode
{
NSMutableArray *compl = [[NSMutableArray alloc] initWithCapacity:32];
NSMutableArray *possibleCompletions = [[NSMutableArray alloc] initWithCapacity:32];
@@ -116,7 +130,7 @@ YY_BUFFER_STATE yy_scan_string (const char *);
unsigned i, insindex;
insindex = 0;
- if([mySQLConnection isConnected])
+ if([mySQLConnection isConnected] && !isDictMode)
{
// Add table names to completions list
MCPResult *queryResult = [mySQLConnection listTables];
@@ -164,24 +178,36 @@ YY_BUFFER_STATE yy_scan_string (const char *);
}
}
+
// If caret is not inside backticks add keywords and all words coming from the view.
if([[self string] length] && ![[[self textStorage] attribute:kBTQuote atIndex:[self selectedRange].location-1 effectiveRange:nil] isEqualToString:kBTQuoteValue] )
{
// Only parse for words if text size is less than 6MB
if([[self string] length]<6000000)
{
- NSCharacterSet *separators = [NSCharacterSet characterSetWithCharactersInString:@" \t\r\n,()\"'`-!;=+|?:~@"];
+ NSCharacterSet *separators = [NSCharacterSet characterSetWithCharactersInString:@" \t\r\n,()[]{}\"'`-!;=+|?:~@"];
NSArray *textViewWords = [[self string] componentsSeparatedByCharactersInSet:separators];
- [possibleCompletions addObjectsFromArray:textViewWords];
+ NSMutableArray *uniqueArray = [NSMutableArray array];
+ NSString *s;
+ enumerate(textViewWords, s)
+ if(![uniqueArray containsObject:s])
+ [uniqueArray addObject:s];
+
+ int reverseSort = NO;
+ NSArray *sortedArray = [[[uniqueArray mutableCopy] autorelease] sortedArrayUsingFunction:alphabeticSort context:&reverseSort];
+ [possibleCompletions addObjectsFromArray:sortedArray];
}
- [possibleCompletions addObjectsFromArray:[self keywords]];
}
+
+ // Add predefined keywords
+ if(!isDictMode)
+ [possibleCompletions addObjectsFromArray:[self keywords]];
// Remove the current word
[possibleCompletions removeObject:currentWord];
- // Build array of dictionaries as in:
- // as in: [NSDictionary dictionaryWithObjectsAndKeys:@"foo", @"display", @"`foo`", @"insert", @"func-small", @"image", nil]
+ // Build array of dictionaries as e.g.:
+ // [NSDictionary dictionaryWithObjectsAndKeys:@"foo", @"display", @"`foo`", @"insert", @"func-small", @"image", nil]
NSString* candidate;
enumerate(possibleCompletions, candidate)
{
@@ -197,7 +223,7 @@ YY_BUFFER_STATE yy_scan_string (const char *);
- (void)doCompletion
{
- // No completion for a selection
+ // No completion for a selection (yet?)
if ([self selectedRange].length > 0) return;
// Refresh quote attributes
@@ -206,22 +232,22 @@ YY_BUFFER_STATE yy_scan_string (const char *);
// Check if the caret is inside quotes "" or ''; if so
// return the normal word suggestion due to the spelling's settings
- // if([[[self textStorage] attribute:kQuote atIndex:charRange.location effectiveRange:nil] isEqualToString:kQuoteValue] )
- // return [[NSSpellChecker sharedSpellChecker] completionsForPartialWordRange:NSMakeRange(0,charRange.length) inString:[[self string] substringWithRange:charRange] language:nil inSpellDocumentWithTag:0];
+ // plus all unique words used in the textView
+ BOOL isDictMode = ([[[self textStorage] attribute:kQuote atIndex:[self getRangeForCurrentWord].location effectiveRange:nil] isEqualToString:kQuoteValue] );
NSString* filter = [[self string] substringWithRange:[self getRangeForCurrentWord]];
NSString* prefix = @"";
- NSString* allow = @" ";
+ NSString* allow = @" _."; // additional chars which not close the popup
BOOL caseInsensitive = YES;
- SPNarrowDownCompletion* completionPopUp = [[SPNarrowDownCompletion alloc] initWithItems:[self suggestionsForSQLCompletionWith:filter]
+ SPNarrowDownCompletion* completionPopUp = [[SPNarrowDownCompletion alloc] initWithItems:[self suggestionsForSQLCompletionWith:filter dictMode:isDictMode]
alreadyTyped:filter
staticPrefix:prefix
additionalWordCharacters:allow
caseSensitive:!caseInsensitive
charRange:[self getRangeForCurrentWord]
inView:self
- dictMode:NO];
+ dictMode:isDictMode];
//Get the NSPoint of the first character of the current word
NSRange range = NSMakeRange([self getRangeForCurrentWord].location,0);
@@ -231,6 +257,7 @@ YY_BUFFER_STATE yy_scan_string (const char *);
NSPoint pos = [[self window] convertBaseToScreen: NSMakePoint(boundingRect.origin.x + boundingRect.size.width,boundingRect.origin.y + boundingRect.size.height)];
NSFont* font = [self font];
+ // TODO: check if needed
// if(filter)
// pos.x -= [filter sizeWithAttributes:[NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]].width;
@@ -2293,9 +2320,12 @@ YY_BUFFER_STATE yy_scan_string (const char *);
- (void)changeColor:(id)sender
{
[self setInsertionPointColor:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:@"CustomQueryEditorCaretColor"]]];
+ // Remember the old selected range
NSRange oldRange = [self selectedRange];
+ // Invoke syntax highlighting
[self setSelectedRange:NSMakeRange(oldRange.location,0)];
[self insertText:@""];
+ // Reset old selected range
[self setSelectedRange:oldRange];
}