aboutsummaryrefslogtreecommitdiffstats
path: root/Source/CMTextView.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CMTextView.m')
-rw-r--r--Source/CMTextView.m94
1 files changed, 50 insertions, 44 deletions
diff --git a/Source/CMTextView.m b/Source/CMTextView.m
index fae2554a..efe18042 100644
--- a/Source/CMTextView.m
+++ b/Source/CMTextView.m
@@ -129,8 +129,10 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
textBufferSizeIncreased = NO;
snippetControlCounter = -1;
mirroredCounter = -1;
+ completionPopup = nil;
completionIsOpen = NO;
isProcessingMirroredSnippets = NO;
+ completionWasRefreshed = NO;
lineNumberView = [[NoodleLineNumberView alloc] initWithScrollView:scrollView];
[scrollView setVerticalRulerView:lineNumberView];
@@ -517,7 +519,6 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
- (void) doAutoCompletion
{
-
if(completionIsOpen || !self || ![self delegate]) return;
// Cancel autocompletion trigger
@@ -532,16 +533,27 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
if(![self delegate] || ![[self delegate] isKindOfClass:[CustomQuery class]] || r.length || snippetControlCounter > -1) return;
if(r.location) {
- if([[[self textStorage] attribute:kQuote atIndex:r.location-1 effectiveRange:nil] isEqualToString:kQuoteValue])
- return;
- if(![[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:[[self string] characterAtIndex:r.location-1]])
- // Suppress auto-completion if window isn't active anymore
- if([[NSApp keyWindow] firstResponder] == self)
- [self doCompletionByUsingSpellChecker:NO fuzzyMode:NO autoCompleteMode:YES];
+ NSCharacterSet *ignoreCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"\"'`;,()[]{}=+/<> \t\n\r"];
+
+ // Check the previous character and don't autocomplete if the character is whitespace or certain types of punctuation
+ if ([ignoreCharacterSet characterIsMember:[[self string] characterAtIndex:r.location - 1]]) return;
+
+ // Suppress auto-completion if the window isn't active anymore
+ if ([[NSApp keyWindow] firstResponder] != self) return;
+
+ // Trigger the completion
+ [self doCompletionByUsingSpellChecker:NO fuzzyMode:NO autoCompleteMode:YES];
}
}
+- (void) refreshCompletion
+{
+ if(completionWasRefreshed) return;
+ completionWasRefreshed = YES;
+ [self doCompletionByUsingSpellChecker:NO fuzzyMode:completionFuzzyMode autoCompleteMode:NO];
+}
+
- (void) doCompletionByUsingSpellChecker:(BOOL)isDictMode fuzzyMode:(BOOL)fuzzySearch autoCompleteMode:(BOOL)autoCompleteMode
{
@@ -557,6 +569,9 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
[self breakUndoCoalescing];
+ // Remember state for refreshCompletion
+ completionFuzzyMode = fuzzySearch;
+
NSUInteger caretPos = NSMaxRange([self selectedRange]);
BOOL caretMovedLeft = NO;
@@ -734,15 +749,15 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
filter = [NSString stringWithString:currentWord];
}
- completionIsOpen = YES;
-
// Cancel autocompletion trigger again if user typed something in while parsing
if([prefs boolForKey:SPCustomQueryAutoComplete])
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(doAutoCompletion)
object:nil];
- SPNarrowDownCompletion* completionPopUp = [[SPNarrowDownCompletion alloc] initWithItems:[self suggestionsForSQLCompletionWith:currentWord dictMode:isDictMode browseMode:dbBrowseMode withTableName:tableName withDbName:dbName]
+ if (completionIsOpen) [completionPopup close], completionPopup = nil;
+ completionIsOpen = YES;
+ completionPopup = [[SPNarrowDownCompletion alloc] initWithItems:[self suggestionsForSQLCompletionWith:currentWord dictMode:isDictMode browseMode:dbBrowseMode withTableName:tableName withDbName:dbName]
alreadyTyped:filter
staticPrefix:prefix
additionalWordCharacters:allow
@@ -778,10 +793,9 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
// Adjust list location to be under the current word or insertion point
pos.y -= [[self font] pointSize]*1.25;
- [completionPopUp setCaretPos:pos];
- [completionPopUp orderFront:self];
- if(!autoCompleteMode)
- [completionPopUp insertCommonPrefix];
+ [completionPopup setCaretPos:pos];
+ [completionPopup orderFront:self];
+ [completionPopup insertCommonPrefix];
}
@@ -1290,9 +1304,10 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
return;
}
+ if (completionIsOpen) [completionPopup close], completionPopup = nil;
completionIsOpen = YES;
- SPNarrowDownCompletion* completionPopUp = [[SPNarrowDownCompletion alloc] initWithItems:possibleCompletions
+ completionPopup = [[SPNarrowDownCompletion alloc] initWithItems:possibleCompletions
alreadyTyped:@""
staticPrefix:@""
additionalWordCharacters:@"_."
@@ -1320,8 +1335,8 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
NSPoint pos = [[self window] convertBaseToScreen: NSMakePoint(boundingRect.origin.x + boundingRect.size.width,boundingRect.origin.y + boundingRect.size.height)];
// Adjust list location to be under the current word or insertion point
pos.y -= [[self font] pointSize]*1.25;
- [completionPopUp setCaretPos:pos];
- [completionPopUp orderFront:self];
+ [completionPopup setCaretPos:pos];
+ [completionPopup orderFront:self];
}
@@ -1336,15 +1351,6 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
NSInteger i, j, k, deltaLength;
NSRange mirroredRange;
- id aCompletionList;
-
- // Get the completion list pointer if open
- if(completionIsOpen)
- for(id w in [NSApp windows])
- if([w isKindOfClass:[SPNarrowDownCompletion class]]) {
- aCompletionList = w;
- break;
- }
// Go through each defined mirrored snippet and update it
for(i=0; i<=mirroredCounter; i++) {
@@ -1375,7 +1381,7 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
// If a completion list is open adjust the theCharRange and theParseRange if a mirrored snippet
// was updated which is located before the initial position
if(completionIsOpen && snippetMirroredControlArray[i][1] < completionParseRangeLocation)
- [aCompletionList adjustWorkingRangeByDelta:deltaLength];
+ [completionPopup adjustWorkingRangeByDelta:deltaLength];
// Adjust all other snippets accordingly
for(j=0; j<=snippetControlMax; j++) {
@@ -1445,7 +1451,6 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
BOOL fuzzySearchMode = ([snip hasPrefix:@"¦¦"] && [snip hasSuffix:@"¦¦"]) ? YES : NO;
NSInteger offset = (fuzzySearchMode) ? 2 : 1;
NSRange insertRange = NSMakeRange(r2.location,0);
- SPNarrowDownCompletion* completionPopUp;
NSString *newSnip = [snip substringWithRange:NSMakeRange(1*offset,[snip length]-(2*offset))];
if([newSnip hasPrefix:@"$SP_ASLIST_"]) {
[self showCompletionListFor:newSnip atRange:NSMakeRange(r2.location, 0) fuzzySearch:fuzzySearchMode];
@@ -1456,9 +1461,10 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
for(id w in list)
[possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:w, @"display", @"dummy-small", @"image", nil]];
+ if (completionIsOpen) [completionPopup close], completionPopup = nil;
completionIsOpen = YES;
- completionPopUp = [[SPNarrowDownCompletion alloc] initWithItems:possibleCompletions
+ completionPopup = [[SPNarrowDownCompletion alloc] initWithItems:possibleCompletions
alreadyTyped:@""
staticPrefix:@""
additionalWordCharacters:@"_."
@@ -1478,6 +1484,7 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
autoComplete:NO
oneColumn:YES
isQueryingDBStructure:NO];
+
//Get the NSPoint of the first character of the current word
NSRange glyphRange = [[self layoutManager] glyphRangeForCharacterRange:NSMakeRange(r2.location,0) actualCharacterRange:NULL];
NSRect boundingRect = [[self layoutManager] boundingRectForGlyphRange:glyphRange inTextContainer:[self textContainer]];
@@ -1485,8 +1492,8 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
NSPoint pos = [[self window] convertBaseToScreen: NSMakePoint(boundingRect.origin.x + boundingRect.size.width,boundingRect.origin.y + boundingRect.size.height)];
// Adjust list location to be under the current word or insertion point
pos.y -= [[self font] pointSize]*1.25;
- [completionPopUp setCaretPos:pos];
- [completionPopUp orderFront:self];
+ [completionPopup setCaretPos:pos];
+ [completionPopup orderFront:self];
}
}
} else {
@@ -1538,7 +1545,11 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
targetRange = NSIntersectionRange(NSMakeRange(0,[[self string] length]), targetRange);
[snip setString:theSnippet];
- if(snip == nil || ![snip length]) return;
+ if (snip == nil) return;
+ if (![snip length]) {
+ [snip release];
+ return;
+ }
// Replace `${x:…}` by ${x:`…`} for convience
[snip replaceOccurrencesOfRegex:@"`(?s)(?<!\\\\)\\$\\{(1?\\d):(.{0}|.*?[^\\\\])\\}`" withString:@"${$1:`$2`}"];
@@ -1999,7 +2010,7 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
if ([theEvent keyCode] == 53 && [self isEditable]){ // ESC key for internal completion
[self setCompletionWasReinvokedAutomatically:NO];
-
+ completionWasRefreshed = NO;
// Cancel autocompletion trigger
if([prefs boolForKey:SPCustomQueryAutoComplete])
[NSObject cancelPreviousPerformRequestsWithTarget:self
@@ -2930,12 +2941,12 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
// Start autohelp only if the user really changed the text (not e.g. for setting a background color)
if([prefs boolForKey:SPCustomQueryUpdateAutoHelp] && editedMask != 1) {
- [self performSelector:@selector(autoHelp) withObject:nil afterDelay:[[[prefs valueForKey:SPCustomQueryAutoHelpDelay] retain] doubleValue]];
+ [self performSelector:@selector(autoHelp) withObject:nil afterDelay:[[prefs valueForKey:SPCustomQueryAutoHelpDelay] doubleValue]];
}
// Start autocompletion if enabled
if([[NSApp keyWindow] firstResponder] == self && [prefs boolForKey:SPCustomQueryAutoComplete] && !completionIsOpen && editedMask != 1 && [textStore editedRange].length)
- [self performSelector:@selector(doAutoCompletion) withObject:nil afterDelay:[[[prefs valueForKey:SPCustomQueryAutoCompleteDelay] retain] doubleValue]];
+ [self performSelector:@selector(doAutoCompletion) withObject:nil afterDelay:[[prefs valueForKey:SPCustomQueryAutoCompleteDelay] doubleValue]];
// Cancel calling doSyntaxHighlighting for large text
if([[self string] length] > SP_TEXT_SIZE_TRIGGER_FOR_PARTLY_PARSING)
@@ -3137,6 +3148,7 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
}
[self breakUndoCoalescing];
[self insertText:dragString];
+ if (draggedItems) [draggedItems release];
return YES;
}
@@ -3271,15 +3283,8 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
- (void) dealloc
{
- if([prefs boolForKey:SPCustomQueryUpdateAutoHelp])
- [NSObject cancelPreviousPerformRequestsWithTarget:self
- selector:@selector(autoHelp)
- object:nil];
-
- if([prefs boolForKey:SPCustomQueryAutoComplete])
- [NSObject cancelPreviousPerformRequestsWithTarget:self
- selector:@selector(doAutoCompletion)
- object:nil];
+ // Cancel any deferred calls
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
// Remove observers
[[NSNotificationCenter defaultCenter] removeObserver:self];
@@ -3297,6 +3302,7 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
[prefs removeObserver:self forKeyPath:SPCustomQueryEditorTabStopWidth];
[prefs removeObserver:self forKeyPath:SPCustomQueryAutoUppercaseKeywords];
+ if (completionIsOpen) [completionPopup close], completionIsOpen = NO;
[prefs release];
[lineNumberView release];
if(queryHiliteColor) [queryHiliteColor release];