From 79c5e1f2d102ffa9d5121ee1f32aee8ca00c2a72 Mon Sep 17 00:00:00 2001 From: Bibiko Date: Wed, 13 Jan 2010 15:02:09 +0000 Subject: =?UTF-8?q?=E2=80=A2=20further=20improvements=20for=20F5=20complet?= =?UTF-8?q?ion=20-=20first=20steps=20for=20context-sensitive=20completion:?= =?UTF-8?q?=20parse=20left=20side=20of=20current=20word=20to=20look=20for?= =?UTF-8?q?=20db.table.field=20constructions=20-=20eg=20type:=20mysql.user?= =?UTF-8?q?.=20=20and=20press=20F5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: work in progress :) --- Source/CMTextView.h | 2 +- Source/CMTextView.m | 302 ++++++++++++++++++++++++++++++++-------- Source/SPNarrowDownCompletion.h | 7 +- Source/SPNarrowDownCompletion.m | 35 +++-- 4 files changed, 274 insertions(+), 72 deletions(-) (limited to 'Source') diff --git a/Source/CMTextView.h b/Source/CMTextView.h index 229f3bbc..cfabd3ef 100644 --- a/Source/CMTextView.h +++ b/Source/CMTextView.h @@ -88,7 +88,7 @@ static inline void NSMutableAttributedStringAddAttributeValueRange (NSMutableAtt - (void) doSyntaxHighlighting; - (void) setConnection:(MCPConnection *)theConnection withVersion:(NSInteger)majorVersion; - (void) doCompletion; -- (NSArray *)suggestionsForSQLCompletionWith:(NSString *)currentWord dictMode:(BOOL)isDictMode; +- (NSArray *)suggestionsForSQLCompletionWith:(NSString *)currentWord dictMode:(BOOL)isDictMode browseMode:(BOOL)dbBrowseMode withTableName:(NSString*)aTableName withDbName:(NSString*)aDbName; - (void) selectCurrentQuery; - (NSUInteger)characterIndexOfPoint:(NSPoint)aPoint; diff --git a/Source/CMTextView.m b/Source/CMTextView.m index 8cfc991f..96c3837e 100644 --- a/Source/CMTextView.m +++ b/Source/CMTextView.m @@ -93,18 +93,18 @@ YY_BUFFER_STATE yy_scan_string (const char *); [scrollView setHasVerticalRuler:YES]; [scrollView setRulersVisible:YES]; - // Re-define 34 tab stops for a better editing + // Re-define 64 tab stops for a better editing NSFont *tvFont = [self font]; float firstColumnInch = 0.5, otherColumnInch = 0.5, pntPerInch = 72.0; NSInteger i; NSTextTab *aTab; NSMutableArray *myArrayOfTabs; NSMutableParagraphStyle *paragraphStyle; - myArrayOfTabs = [NSMutableArray arrayWithCapacity:34]; + myArrayOfTabs = [NSMutableArray arrayWithCapacity:64]; aTab = [[NSTextTab alloc] initWithType:NSLeftTabStopType location:firstColumnInch*pntPerInch]; [myArrayOfTabs addObject:aTab]; [aTab release]; - for(i=1; i<34; i++) { + for(i=1; i<64; i++) { aTab = [[NSTextTab alloc] initWithType:NSLeftTabStopType location:(firstColumnInch*pntPerInch) + ((float)i * otherColumnInch * pntPerInch)]; [myArrayOfTabs addObject:aTab]; [aTab release]; @@ -161,22 +161,18 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) * * [NSDictionary dictionaryWithObjectsAndKeys:@"foo", @"display", @"`foo`", @"match", @"func-small", @"image", nil] */ -- (NSArray *)suggestionsForSQLCompletionWith:(NSString *)currentWord dictMode:(BOOL)isDictMode +- (NSArray *)suggestionsForSQLCompletionWith:(NSString *)currentWord dictMode:(BOOL)isDictMode browseMode:(BOOL)dbBrowseMode withTableName:(NSString*)aTableName withDbName:(NSString*)aDbName { - NSMutableArray *compl = [[NSMutableArray alloc] initWithCapacity:32]; + NSMutableArray *possibleCompletions = [[NSMutableArray alloc] initWithCapacity:32]; if(isDictMode) { for (id w in [[NSSpellChecker sharedSpellChecker] completionsForPartialWordRange:NSMakeRange(0,[currentWord length]) inString:currentWord language:nil inSpellDocumentWithTag:0]) - [compl addObject:[NSDictionary dictionaryWithObjectsAndKeys:w, @"display", @"dummy-small", @"image", nil]]; - - return [compl autorelease]; + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:w, @"display", @"dummy-small", @"image", nil]]; } - NSMutableArray *possibleCompletions = [[NSMutableArray alloc] initWithCapacity:32]; - // 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] ) + if([[self string] length] && !dbBrowseMode) { // Only parse for words if text size is less than 6MB if([[self string] length]<6000000) @@ -208,7 +204,7 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) } - if([mySQLConnection isConnected]) + if(!isDictMode && [mySQLConnection isConnected]) { // Add structural db/table/field data to completions list or fallback to gathering TablesList data NSDictionary *dbs = [NSDictionary dictionaryWithDictionary:[mySQLConnection getDbStructure]]; @@ -217,14 +213,21 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) NSSortDescriptor *desc = [[NSSortDescriptor alloc] initWithKey:nil ascending:YES selector:@selector(localizedCompare:)]; NSMutableArray *sortedDbs = [NSMutableArray array]; [sortedDbs addObjectsFromArray:[allDbs sortedArrayUsingDescriptors:[NSArray arrayWithObject:desc]]]; + NSString *currentDb = nil; - // Put current selected db at the top - if ([[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"selectedDatabase"] != nil) { + NSString *currentTable = nil; + if ([[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"selectedDatabase"] != nil) + currentDb = [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKeyPath:@"selectedDatabase"]; + if ([[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"tableName"] != nil) + currentTable = [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKeyPath:@"tableName"]; + + if(aTableName == nil && aDbName == nil) { + // Put current selected db at the top currentDb = [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKeyPath:@"selectedDatabase"]; [sortedDbs removeObject:currentDb]; [sortedDbs insertObject:currentDb atIndex:0]; } - // Put information_schema and mysql db at the end + // Put information_schema and mysql db at the end if not chosen if(currentDb && ![currentDb isEqualToString:@"mysql"]) { [sortedDbs removeObject:@"mysql"]; [sortedDbs addObject:@"mysql"]; @@ -233,31 +236,56 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) [sortedDbs removeObject:@"information_schema"]; [sortedDbs addObject:@"information_schema"]; } + + BOOL aTableNameExists = NO; + if(!aDbName) { + if(aTableName && [aTableName length] && [dbs objectForKey:currentDb] && [[dbs objectForKey:currentDb] objectForKey:aTableName]) { + aTableNameExists = YES; + aDbName = [NSString stringWithString:currentDb]; + } + } else if (aDbName && [aDbName length]) { + if(aTableName && [aTableName length] && [dbs objectForKey:aDbName] && [[dbs objectForKey:aDbName] objectForKey:aTableName]) { + aTableNameExists = YES; + } + } + + // If aDbName exist show only those table + if(aDbName && [aDbName length] && [allDbs containsObject:aDbName]) { + [sortedDbs removeAllObjects]; + [sortedDbs addObject:aDbName]; + } + for(id db in sortedDbs) { NSArray *allTables = [[dbs objectForKey:db] allKeys]; - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:db, @"display", @"database-small", @"image", nil]]; - NSArray *sortedTables = [allTables sortedArrayUsingDescriptors:[NSArray arrayWithObject:desc]]; + NSArray *sortedTables; + if(aTableNameExists) { + sortedTables = [NSArray arrayWithObject:aTableName]; + } else { + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:db, @"display", @"database-small", @"image", nil]]; + sortedTables= [allTables sortedArrayUsingDescriptors:[NSArray arrayWithObject:desc]]; + } for(id table in sortedTables) { NSDictionary * theTable = [[dbs objectForKey:db] objectForKey:table]; NSArray *allFields = [theTable allKeys]; NSInteger structtype = [[theTable objectForKey:@" struct_type "] intValue]; BOOL breakFlag = NO; - switch(structtype) { - case 0: - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"table-small-square", @"image", db, @"path", nil]]; - break; - case 1: - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"table-view-small-square", @"image", db, @"path", nil]]; - break; - case 2: - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"proc-small", @"image", db, @"path", nil]]; - breakFlag = YES; - break; - case 3: - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"func-small", @"image", db, @"path", nil]]; - breakFlag = YES; - break; - } + if(!aTableNameExists) + switch(structtype) { + case 0: + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"table-small-square", @"image", db, @"path", nil]]; + break; + case 1: + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"table-view-small-square", @"image", db, @"path", nil]]; + break; + case 2: + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"proc-small", @"image", db, @"path", nil]]; + breakFlag = YES; + break; + case 3: + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"func-small", @"image", db, @"path", nil]]; + breakFlag = YES; + break; + } if(!breakFlag) { NSArray *sortedFields = [allFields sortedArrayUsingDescriptors:[NSArray arrayWithObject:desc]]; for(id field in sortedFields) { @@ -269,9 +297,9 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) } } } else { - // Fallback for MySQL < 5 and if the data gathering is slow + // Fallback for MySQL < 5 and if the data gathering is in progress if(mySQLmajorVersion > 4) - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"updating data…", @"updating table data for completion in progress message"), @"path", nil]]; + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"fetching table data…", @"fetching table data for completion in progress message"), @"path", nil]]; // Add all database names to completions list for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allDatabaseNames"]) @@ -308,11 +336,11 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) } // Make suggestions unique - BOOL avoidUnique = ([currentWord isEqualToString:@"`"]) ? YES :NO; + NSMutableArray *compl = [[NSMutableArray alloc] initWithCapacity:32]; for(id suggestion in possibleCompletions) - if(avoidUnique || ![compl containsObject:suggestion]) + if(![compl containsObject:suggestion]) [compl addObject:suggestion]; - + [possibleCompletions release]; return [compl autorelease]; @@ -322,57 +350,211 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) - (void)doCompletion { - // No completion for a selection (yet?) - if ([self selectedRange].length > 0) return; + // No completion for a selection (yet?) and if caret positiopn == 0 + if ([self selectedRange].length > 0 || ![self selectedRange].location) return; + + NSString* filter; + NSString* dbName = nil; + NSString* tableName = nil; + NSRange completionRange = [self getRangeForCurrentWord]; + NSString* currentWord = [[self string] substringWithRange:completionRange]; + NSString* prefix = @""; + NSString* allow = @"_. "; // additional chars which not close the popup + + BOOL dbBrowseMode = NO; + BOOL backtickMode = NO; + BOOL caseInsensitive = YES; // Check if the caret is inside quotes "" or ''; if so // return the normal word suggestion due to the spelling's settings // plus all unique words used in the textView BOOL isDictMode = NO; - if([self getRangeForCurrentWord].length) - isDictMode = ([[[self textStorage] attribute:kQuote atIndex:[self getRangeForCurrentWord].location effectiveRange:nil] isEqualToString:kQuoteValue] ); + if(completionRange.length) + isDictMode = ([[[self textStorage] attribute:kQuote atIndex:completionRange.location effectiveRange:nil] isEqualToString:kQuoteValue] ); - BOOL dbStructureMode = ([[[self textStorage] attribute:kBTQuote atIndex:[self selectedRange].location-1 effectiveRange:nil] isEqualToString:kBTQuoteValue]) ? YES : NO; - // Refresh quote attributes - [[self textStorage] removeAttribute:kQuote range:NSMakeRange(0,[[self string] length])]; - // [self insertText:@""]; + if(!isDictMode) { + // Check if user wants to insert a db/table/field name + // currentWord == ` : user invoked completion via `|` + dbBrowseMode = ([currentWord isEqualToString:@"`"]) ? YES : NO; + // Is the caret inside backticks + dbBrowseMode = ([[[self textStorage] attribute:kBTQuote atIndex:[self selectedRange].location-1 effectiveRange:nil] isEqualToString:kBTQuoteValue]) ? YES : dbBrowseMode; + backtickMode = dbBrowseMode; - NSString* filter = [[self string] substringWithRange:[self getRangeForCurrentWord]]; - NSString* prefix = @""; - NSString* allow = @"_."; // additional chars which not close the popup - BOOL caseInsensitive = YES; + // Refresh quote attributes + [[self textStorage] removeAttribute:kQuote range:NSMakeRange(0, [[self string] length])]; + + if([currentWord hasSuffix:@"."]) { + dbBrowseMode = YES; + filter = @""; + completionRange = NSMakeRange(completionRange.location+completionRange.length,0); + } else { + filter = [NSString stringWithString:currentWord]; + } - SPNarrowDownCompletion* completionPopUp = [[SPNarrowDownCompletion alloc] initWithItems:[self suggestionsForSQLCompletionWith:filter dictMode:isDictMode] + + NSInteger caretPos = completionRange.location + completionRange.length; + NSInteger start = caretPos; + BOOL breakParsing = YES; + + // Parse string left from currentWord … + if(start > 1) { + // … for possible db/table/field completion + // table.foo| or `table`.foo| or `table`.`foo|` to set filter to "foo" + start--; + BOOL insideBackticks = backtickMode; + unichar currentCharacter; + NSCharacterSet *whiteSpaceCharSet = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + BOOL runFlag = YES; + while(start >= 0 && runFlag) { + currentCharacter = [[self string] characterAtIndex:start]; + if([whiteSpaceCharSet characterIsMember:currentCharacter] && !insideBackticks) { + breakParsing = YES; + break; + } + switch(currentCharacter) { + case '`': + insideBackticks = !insideBackticks; + break; + case '.': + if(!insideBackticks) { + start++; + NSInteger offset = (backtickMode) ? 1 : 0; + completionRange = NSMakeRange(start+offset,caretPos-start-offset); + filter = [[self string] substringWithRange:completionRange]; + caretPos = start; + runFlag = NO; + dbBrowseMode = YES; + breakParsing = NO; + } + break; + } + if(start == 0) { + breakParsing = YES; + break; + } + start--; + } + + // … go further and look for a table name + if(!breakParsing && start > 0) { + start--; + caretPos--; + runFlag = YES; + breakParsing = YES; + insideBackticks = NO; + while(runFlag) { + currentCharacter = [[self string] characterAtIndex:start]; + if(start == 0 || ([whiteSpaceCharSet characterIsMember:currentCharacter] && !insideBackticks)) { + if(start > 0) start++; + tableName = [[[self string] substringWithRange:NSMakeRange(start,caretPos-start)] stringByReplacingOccurrencesOfRegex:@"^`|`$" withString:@""]; + caretPos = start; + runFlag = NO; + breakParsing = !(start == 0); + break; + } + switch(currentCharacter) { + case '`': + insideBackticks = !insideBackticks; + break; + case '.': + if(!insideBackticks) { + start++; + tableName = [[[self string] substringWithRange:NSMakeRange(start,caretPos-start)] stringByReplacingOccurrencesOfRegex:@"^`|`$" withString:@""]; + caretPos = start; + runFlag = NO; + breakParsing = NO; + } + break; + } + if(start == 0) { + breakParsing = YES; + break; + } + if(start == 0) { + breakParsing = YES; + break; + } + start--; + } + } + + // … go further and look for a db name + if(!breakParsing && start > 0) { + start--; + caretPos--; + runFlag = YES; + breakParsing = YES; + insideBackticks = NO; + while(runFlag) { + currentCharacter = [[self string] characterAtIndex:start]; + if(start == 0 || ([whiteSpaceCharSet characterIsMember:currentCharacter] && !insideBackticks)) { + if(start > 0) start++; + dbName = [[[self string] substringWithRange:NSMakeRange(start,caretPos-start)] stringByReplacingOccurrencesOfRegex:@"^`|`$" withString:@""]; + caretPos = start; + runFlag = NO; + breakParsing = !(start == 0); + break; + } + switch(currentCharacter) { + case '`': + insideBackticks = !insideBackticks; + break; + case '.': + if(!insideBackticks) { + start++; + dbName = [[[self string] substringWithRange:NSMakeRange(start,caretPos-start)] stringByReplacingOccurrencesOfRegex:@"^`|`$" withString:@""]; + caretPos = start; + runFlag = NO; + breakParsing = NO; + } + break; + } + if(start == 0) { + breakParsing = YES; + break; + } + if(start == 0) { + breakParsing = YES; + break; + } + start--; + } + } + } + } else { + filter = [NSString stringWithString:currentWord]; + } + + SPNarrowDownCompletion* completionPopUp = [[SPNarrowDownCompletion alloc] initWithItems:[self suggestionsForSQLCompletionWith:currentWord dictMode:isDictMode browseMode:dbBrowseMode withTableName:tableName withDbName:dbName] alreadyTyped:filter staticPrefix:prefix additionalWordCharacters:allow caseSensitive:!caseInsensitive - charRange:[self getRangeForCurrentWord] + charRange:completionRange inView:self dictMode:isDictMode - dbMode:dbStructureMode]; + dbMode:dbBrowseMode + backtickMode:backtickMode + withDbName:dbName + withTableName:tableName]; //Get the NSPoint of the first character of the current word - NSRange range = NSMakeRange([self getRangeForCurrentWord].location,0); + NSRange range = NSMakeRange(completionRange.location,0); NSRange glyphRange = [[self layoutManager] glyphRangeForCharacterRange:range actualCharacterRange:NULL]; NSRect boundingRect = [[self layoutManager] boundingRectForGlyphRange:glyphRange inTextContainer:[self textContainer]]; boundingRect = [self convertRect: boundingRect toView: NULL]; 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; - // Adjust list location to be under the current word - pos.y -= [font pointSize]*1.25; + // 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]; - // TODO: where to place the release?? - // [completionPopUp release]; - } diff --git a/Source/SPNarrowDownCompletion.h b/Source/SPNarrowDownCompletion.h index 1a0359eb..f1d4e63c 100644 --- a/Source/SPNarrowDownCompletion.h +++ b/Source/SPNarrowDownCompletion.h @@ -43,6 +43,7 @@ BOOL caseSensitive; BOOL dictMode; BOOL dbStructureMode; + BOOL backtickMode; NSFont *tableFont; NSRange theCharRange; NSArray *words; @@ -51,7 +52,11 @@ NSMutableCharacterSet* textualInputCharacters; } -- (id)initWithItems:(NSArray*)someSuggestions alreadyTyped:(NSString*)aUserString staticPrefix:(NSString*)aStaticPrefix additionalWordCharacters:(NSString*)someAdditionalWordCharacters caseSensitive:(BOOL)isCaseSensitive charRange:(NSRange)initRange inView:(id)aView dictMode:(BOOL)mode dbMode:(BOOL)dbMode; +- (id)initWithItems:(NSArray*)someSuggestions alreadyTyped:(NSString*)aUserString staticPrefix:(NSString*)aStaticPrefix + additionalWordCharacters:(NSString*)someAdditionalWordCharacters caseSensitive:(BOOL)isCaseSensitive + charRange:(NSRange)initRange inView:(id)aView + dictMode:(BOOL)mode dbMode:(BOOL)theDbMode + backtickMode:(BOOL)theBackTickMode withDbName:(NSString*)dbName withTableName:(NSString*)tableName; - (void)setCaretPos:(NSPoint)aPos; - (void)insert_text:(NSString* )aString; diff --git a/Source/SPNarrowDownCompletion.m b/Source/SPNarrowDownCompletion.m index f47baeab..a041315e 100644 --- a/Source/SPNarrowDownCompletion.m +++ b/Source/SPNarrowDownCompletion.m @@ -124,7 +124,11 @@ [super dealloc]; } -- (id)initWithItems:(NSArray*)someSuggestions alreadyTyped:(NSString*)aUserString staticPrefix:(NSString*)aStaticPrefix additionalWordCharacters:(NSString*)someAdditionalWordCharacters caseSensitive:(BOOL)isCaseSensitive charRange:(NSRange)initRange inView:(id)aView dictMode:(BOOL)mode dbMode:(BOOL)dbMode +- (id)initWithItems:(NSArray*)someSuggestions alreadyTyped:(NSString*)aUserString staticPrefix:(NSString*)aStaticPrefix + additionalWordCharacters:(NSString*)someAdditionalWordCharacters caseSensitive:(BOOL)isCaseSensitive + charRange:(NSRange)initRange inView:(id)aView + dictMode:(BOOL)mode dbMode:(BOOL)theDbMode + backtickMode:(BOOL)theBackTickMode withDbName:(NSString*)dbName withTableName:(NSString*)tableName { if(self = [self init]) { @@ -135,7 +139,9 @@ if(aUserString && !filterStringIsBacktick) [mutablePrefix appendString:aUserString]; - dbStructureMode = dbMode; + dbStructureMode = theDbMode; + + backtickMode = theBackTickMode; if(aStaticPrefix) staticPrefix = [aStaticPrefix retain]; @@ -150,7 +156,7 @@ theView = aView; dictMode = mode; - + if(!dictMode) { suggestions = [someSuggestions retain]; words = nil; @@ -256,16 +262,24 @@ if(imageName) image = [NSImage imageNamed:imageName]; [[aTableColumn dataCell] setImage:image]; - return @""; } + return @""; } else if([[aTableColumn identifier] isEqualToString:@"name"]) { - return [[filtered objectAtIndex:rowIndex] objectForKey:@"display"]; + return (dictMode) ? [filtered objectAtIndex:rowIndex] : [[filtered objectAtIndex:rowIndex] objectForKey:@"display"]; } else if([[aTableColumn identifier] isEqualToString:@"type"]) { - [[aTableColumn dataCell] setTextColor:([aTableView selectedRow] == rowIndex)?[NSColor whiteColor]:[NSColor darkGrayColor]]; - return ([[filtered objectAtIndex:rowIndex] objectForKey:@"type"])?[[filtered objectAtIndex:rowIndex] objectForKey:@"type"]:@""; + if(dictMode) { + return @""; + } else { + [[aTableColumn dataCell] setTextColor:([aTableView selectedRow] == rowIndex)?[NSColor whiteColor]:[NSColor darkGrayColor]]; + return ([[filtered objectAtIndex:rowIndex] objectForKey:@"type"]) ? [[filtered objectAtIndex:rowIndex] objectForKey:@"type"] : @""; + } } else if ([[aTableColumn identifier] isEqualToString:@"path"]) { - [[aTableColumn dataCell] setTextColor:([aTableView selectedRow] == rowIndex)?[NSColor whiteColor]:[NSColor darkGrayColor]]; - return ([[filtered objectAtIndex:rowIndex] objectForKey:@"path"])?[[filtered objectAtIndex:rowIndex] objectForKey:@"path"]:@""; + if(dictMode) { + return @""; + } else { + [[aTableColumn dataCell] setTextColor:([aTableView selectedRow] == rowIndex)?[NSColor whiteColor]:[NSColor darkGrayColor]]; + return ([[filtered objectAtIndex:rowIndex] objectForKey:@"path"]) ? [[filtered objectAtIndex:rowIndex] objectForKey:@"path"] : @""; + } } return [filtered objectAtIndex:rowIndex]; } @@ -534,7 +548,8 @@ { [theView setSelectedRange:theCharRange]; [theView insertText:aString]; - if(dbStructureMode) + // If completion was invoked inside backticks move caret out of the backticks + if(backtickMode) [theView performSelector:@selector(moveRight:)]; } -- cgit v1.2.3