aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPNarrowDownCompletion.m
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2010-11-30 02:24:42 +0000
committerrowanbeentje <rowan@beent.je>2010-11-30 02:24:42 +0000
commitb4a5f241c7a6adfdf1b8f4afb94f8d8c57a5c0a9 (patch)
treef1f58eb63be0f13a653b9ecd0174264e0707ffa6 /Source/SPNarrowDownCompletion.m
parentcc2e00c656a34d4c472a25f929282c8fc63d0174 (diff)
downloadsequelpro-b4a5f241c7a6adfdf1b8f4afb94f8d8c57a5c0a9.tar.gz
sequelpro-b4a5f241c7a6adfdf1b8f4afb94f8d8c57a5c0a9.tar.bz2
sequelpro-b4a5f241c7a6adfdf1b8f4afb94f8d8c57a5c0a9.zip
- Rework insertCommonPrefix to insertAutocompletePlaceholder, implementing a more Mac-like behaviour: insert a faded placeholder for the currently selected autocomplete item.
- Update the autocomplete placeholder when the autocomplete dropdown selection is changed - Clean up methods for removing placeholders, and ensure the placeholder is always removed (fixes issues with pasting with a placeholder visible, etc) - When the Help window is closed, switch off AutoHelp - this will aid in supporting those users who accidentally switch on AutoHelp and then can't figure out how to switch it off, resulting in returning windows.
Diffstat (limited to 'Source/SPNarrowDownCompletion.m')
-rw-r--r--Source/SPNarrowDownCompletion.m117
1 files changed, 69 insertions, 48 deletions
diff --git a/Source/SPNarrowDownCompletion.m b/Source/SPNarrowDownCompletion.m
index d83f78c5..a960e74a 100644
--- a/Source/SPNarrowDownCompletion.m
+++ b/Source/SPNarrowDownCompletion.m
@@ -35,6 +35,12 @@
#import "RegexKitLite.h"
#import "SPTextView.h"
+#pragma mark -
+#pragma mark attribute definition
+
+#define kSPAutoCompletePlaceholderName @"Placeholder"
+#define kSPAutoCompletePlaceholderVal @"placholder"
+
@interface NSTableView (MovingSelectedRow)
- (BOOL)SP_NarrowDownCompletion_canHandleEvent:(NSEvent*)anEvent;
@@ -47,7 +53,7 @@
- (NSString*)filterString;
- (void)setupInterface;
- (void)filter;
-- (void)insertCommonPrefix;
+- (void)insertAutocompletePlaceholder;
- (void)completeAndInsertSnippet;
@end
@@ -86,6 +92,7 @@
[self selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
}
[self scrollRowToVisible:row];
+ [[self delegate] insertAutocompletePlaceholder];
return YES;
}
}
@@ -115,7 +122,7 @@
currentSyncImage = 0;
staticPrefix = nil;
suggestions = nil;
- commonPrefixWasInsertedByAutoComplete = NO;
+ autocompletePlaceholderWasInserted = NO;
prefs = [NSUserDefaults standardUserDefaults];
originalFilterString = [[NSMutableString alloc] init];
[originalFilterString setString:@""];
@@ -794,14 +801,11 @@
if (([event modifierFlags] & (NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask)) == NSAlternateKeyMask || [[event characters] length] == 0)
{
if(autoCompletionMode) {
- if(commonPrefixWasInsertedByAutoComplete) {
- [theView setSelectedRange:theCharRange];
- [theView insertText:originalFilterString];
- [theView setCompletionIsOpen:NO];
- [self close];
- [NSApp sendEvent:event];
- break;
- }
+ if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholder];
+ [theView setCompletionIsOpen:NO];
+ [self close];
+ [NSApp sendEvent:event];
+ break;
}
[NSApp sendEvent: event];
@@ -826,10 +830,7 @@
[self filter];
} else {
if(autoCompletionMode) {
- if(commonPrefixWasInsertedByAutoComplete) {
- [theView setSelectedRange:theCharRange];
- [theView insertText:originalFilterString];
- }
+ if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholder];
[theView setCompletionIsOpen:NO];
[self close];
break;
@@ -845,10 +846,7 @@
else if(key == NSBackspaceCharacter || key == NSDeleteCharacter)
{
if(autoCompletionMode) {
- if(commonPrefixWasInsertedByAutoComplete) {
- [theView setSelectedRange:theCharRange];
- [theView insertText:originalFilterString];
- }
+ if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholder];
[NSApp sendEvent:event];
break;
}
@@ -868,10 +866,7 @@
if(autoCompletionMode) {
[theView setCompletionIsOpen:NO];
[self close];
- if(commonPrefixWasInsertedByAutoComplete) {
- [theView setSelectedRange:theCharRange];
- [theView insertText:originalFilterString];
- }
+ if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholder];
[NSApp sendEvent:event];
return;
}
@@ -887,7 +882,7 @@
theCharRange.length++;
theParseRange.length++;
[self filter];
- [self insertCommonPrefix];
+ [self insertAutocompletePlaceholder];
}
else
@@ -904,10 +899,7 @@
} else {
if(!NSPointInRect([NSEvent mouseLocation], [self frame])) {
if(autoCompletionMode) {
- if(commonPrefixWasInsertedByAutoComplete) {
- [theView setSelectedRange:theCharRange];
- [theView insertText:originalFilterString];
- }
+ if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholder];
}
if(cursorMovedLeft) [theView performSelector:@selector(moveRight:)];
[NSApp sendEvent:event];
@@ -921,6 +913,34 @@
[NSApp sendEvent:event];
}
}
+
+ // If the autocomplete menu is open, but the placeholder is still present, it needs removing.
+ if (autoCompletionMode && autocompletePlaceholderWasInserted) {
+ [[theView textStorage] beginEditing];
+ NSRange attributeResultRange;
+ while (1) {
+ attributeResultRange = NSMakeRange(NSNotFound, 0);
+ if ([[theView textStorage] attribute:kSPAutoCompletePlaceholderName atIndex:0 longestEffectiveRange:&attributeResultRange inRange:NSMakeRange(0, [[theView textStorage] length])]) {
+
+ // A match was found - attributeResultRange contains the range of the attributed string
+ [[theView textStorage] deleteCharactersInRange:attributeResultRange];
+ } else {
+
+ // No match was found. attributeResultRange contains the range of the no match - this can be
+ // checked to see whether a match is inside the full range.
+ if (attributeResultRange.length == [[theView textStorage] length]) break;
+
+ // A match was found - retrieve the location
+ NSUInteger matchStart = attributeResultRange.location+attributeResultRange.length;
+ if ([[theView textStorage] attribute:kSPAutoCompletePlaceholderName atIndex:matchStart longestEffectiveRange:&attributeResultRange inRange:NSMakeRange(matchStart, [[theView textStorage] length] - matchStart)]) {
+ [[theView textStorage] deleteCharactersInRange:attributeResultRange];
+ }
+ }
+ }
+ [[theView textStorage] endEditing];
+ autocompletePlaceholderWasInserted = NO;
+ }
+
[theView setCompletionIsOpen:NO];
[self close];
usleep(70); // tiny delay to suppress while continously pressing of ESC overlapping
@@ -929,49 +949,50 @@
// ==================
// = Action methods =
// ==================
-- (void)insertCommonPrefix
+- (void)insertAutocompletePlaceholder
{
-
if([theTableView selectedRow] == -1 || fuzzyMode)
return;
- id cur = [filtered objectAtIndex:0];
+ // Clear any current placeholder
+ if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholder];
- if([cur objectForKey:@"noCompletion"]) return;
+ // Select the highlighted item in the list of suggestions
+ id cur = [filtered objectAtIndex:[theTableView selectedRow]];
+ // Ensure it's a valid suggestion and extract the string
+ if ([cur objectForKey:@"noCompletion"]) return;
NSString* curMatch = [cur objectForKey:@"match"] ?: [cur objectForKey:@"display"];
+ if (![curMatch length]) return;
- if(![curMatch length]) return;
-
- NSMutableString *commonPrefix = [NSMutableString string];
- [commonPrefix setString:curMatch];
- for(id candidate in filtered) {
- NSString* candidateMatch;
- candidateMatch = [candidate objectForKey:@"match"] ?: [candidate objectForKey:@"display"];
- NSString *tempPrefix = [candidateMatch commonPrefixWithString:commonPrefix options:NSCaseInsensitiveSearch];
- // if(![tempPrefix length]) break;
- if([commonPrefix length] > [tempPrefix length])
- [commonPrefix setString:tempPrefix];
- }
-
- // Insert common prefix automatically
- if([[self filterString] length] < [commonPrefix length]) {
+ // Insert a placeholder for the string in the textview
+ if ([originalFilterString length] < [curMatch length]) {
NSUInteger currentSelectionPosition = [theView selectedRange].location;
- NSString* toInsert = [commonPrefix substringFromIndex:[[self filterString] length]];
+ NSString* toInsert = [curMatch substringFromIndex:[originalFilterString length]];
[mutablePrefix appendString:toInsert];
theCharRange.length += [toInsert length];
theParseRange.length += [toInsert length];
[theView insertText:[toInsert lowercaseString]];
- commonPrefixWasInsertedByAutoComplete = YES;
+ autocompletePlaceholderWasInserted = YES;
// Restore the text selection location, and clearly mark the autosuggested text
[theView setSelectedRange:NSMakeRange(currentSelectionPosition, 0)];
NSMutableAttributedStringAddAttributeValueRange([theView textStorage], NSForegroundColorAttributeName, [[theView otherTextColor] colorWithAlphaComponent:0.3], NSMakeRange(currentSelectionPosition, [toInsert length]));
+ NSMutableAttributedStringAddAttributeValueRange([theView textStorage], kSPAutoCompletePlaceholderName, kSPAutoCompletePlaceholderVal, NSMakeRange(currentSelectionPosition, [toInsert length]));
[self checkSpaceForAllowedCharacter];
}
}
+- (void)removeAutocompletionPlaceholder
+{
+ if (!autocompletePlaceholderWasInserted) return;
+
+ [theView setSelectedRange:theCharRange];
+ [theView insertText:originalFilterString];
+ autocompletePlaceholderWasInserted = NO;
+}
+
- (void)insert_text:(NSString* )aString
{