aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBibiko <bibiko@eva.mpg.de>2009-05-02 21:37:33 +0000
committerBibiko <bibiko@eva.mpg.de>2009-05-02 21:37:33 +0000
commit62f46ff751c551aa07594f0f5ef19f80ce7b83f0 (patch)
tree5600a4dfb64c98db8e2e5b2d198691a0262ede0f
parent49d3909683d5067ee6b912a37e7af23ab97d057e (diff)
downloadsequelpro-62f46ff751c551aa07594f0f5ef19f80ce7b83f0.tar.gz
sequelpro-62f46ff751c551aa07594f0f5ef19f80ce7b83f0.tar.bz2
sequelpro-62f46ff751c551aa07594f0f5ef19f80ce7b83f0.zip
• improved completion in CQ's text view
- added database names - fixed logic for detecting if caret is inside quotes - if caret inside backticks show only db, table, column names • outsourced syntax highlighting into a method for further improvements
-rw-r--r--Source/CMTextView.h9
-rw-r--r--Source/CMTextView.m119
-rw-r--r--Source/SPEditorTokens.h6
-rw-r--r--Source/SPEditorTokens.l2
4 files changed, 93 insertions, 43 deletions
diff --git a/Source/CMTextView.h b/Source/CMTextView.h
index 7abc2ef1..964598cd 100644
--- a/Source/CMTextView.h
+++ b/Source/CMTextView.h
@@ -23,6 +23,12 @@
#import <Cocoa/Cocoa.h>
#import "NoodleLineNumberView.h"
+#import <MCPKit_bundled/MCPKit_bundled.h>
+#import "CMCopyTable.h"
+#import "CMTextView.h"
+#import "CMMCPConnection.h"
+#import "CMMCPResult.h"
+
@interface CMTextView : NSTextView {
BOOL autoindentEnabled;
@@ -38,7 +44,7 @@
BOOL sqlStringIsTooLarge;
IBOutlet NSScrollView *scrollView;
-
+
}
- (IBAction)showMySQLHelpForCurrentWord:(id)sender;
@@ -63,5 +69,6 @@
- (void) selectLineNumber:(unsigned int)lineNumber ignoreLeadingNewLines:(BOOL)ignLeadingNewLines;
- (unsigned int) getLineNumberForCharacterIndex:(unsigned int)anIndex;
- (void) autoHelp;
+- (void) doSyntaxHighlighting:(NSTextStorage*)textStore;
@end
diff --git a/Source/CMTextView.m b/Source/CMTextView.m
index 25dda47d..982cd9c6 100644
--- a/Source/CMTextView.m
+++ b/Source/CMTextView.m
@@ -42,7 +42,10 @@ YY_BUFFER_STATE yy_scan_string (const char *);
#define kWQquoted @"Quoted" // set via lex to indicate a quoted string
#define kSQLkeyword @"SQLkw" // attribute for found SQL keywords
#define kQuote @"Quote"
+#define kQuoteValue @"isQuoted"
#define kValue @"dummy"
+#define kBTQuote @"BTQuote"
+#define kBTQuoteValue @"isBTQuoted"
#define SP_CQ_SEARCH_IN_MYSQL_HELP_MENU_ITEM_TAG 1000
@@ -230,6 +233,7 @@ YY_BUFFER_STATE yy_scan_string (const char *);
[self scrollRangeToVisible:selRange];
}
+
/*
* Handle some keyDown events in order to provide autopairing functionality (if enabled).
*/
@@ -406,6 +410,10 @@ YY_BUFFER_STATE yy_scan_string (const char *);
}
+
+/*
+ * Notify autoHelp if user changed the insertion point
+ */
- (void)mouseDown:(NSEvent *)theEvent
{
@@ -617,39 +625,58 @@ YY_BUFFER_STATE yy_scan_string (const char *);
- (NSArray *)completionsForPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int *)index
{
+ if (!charRange.length) return nil;
+
// Check if the caret is inside quotes "" or ''; if so
// return the normal word suggestion due to the spelling's settings
- if(!sqlStringIsTooLarge && [[self textStorage] attribute:kQuote atIndex:charRange.location effectiveRange:nil])
+ if(!sqlStringIsTooLarge && [[[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];
- NSCharacterSet *separators = [NSCharacterSet characterSetWithCharactersInString:@" \t\r\n,()\"'`-!;=+|?:~"];
- NSArray *textViewWords = [[self string] componentsSeparatedByCharactersInSet:separators];
+
+ NSMutableArray *compl = [[NSMutableArray alloc] initWithCapacity:32];
+ NSMutableArray *possibleCompletions = [[NSMutableArray alloc] initWithCapacity:32];
+
NSString *partialString = [[self string] substringWithRange:charRange];
unsigned int partialLength = [partialString length];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[cd] %@ AND length > %d", partialString, partialLength];
+ NSArray *matchingCompletions;
+
+ unsigned i, insindex;
+ insindex = 0;
+
+ // Add current table names omitting the first item (it's the table header)
id tableNames = [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"tables"];
-
- //unsigned int options = NSCaseInsensitiveSearch | NSAnchoredSearch;
- //NSRange partialRange = NSMakeRange(0, partialLength);
-
- NSMutableArray *compl = [[NSMutableArray alloc] initWithCapacity:32];
-
- NSMutableArray *possibleCompletions = [NSMutableArray arrayWithArray:textViewWords];
- [possibleCompletions addObjectsFromArray:[self keywords]];
- [possibleCompletions addObjectsFromArray:tableNames];
-
+ [possibleCompletions addObjectsFromArray:[tableNames objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, [tableNames count]-1)]]];
+
// Add column names to completions list for currently selected table
if ([[[self window] delegate] table] != nil) {
id columnNames = [[[[self window] delegate] valueForKeyPath:@"tableDataInstance"] valueForKey:@"columnNames"];
[possibleCompletions addObjectsFromArray:columnNames];
}
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[cd] %@ AND length > %d", partialString, partialLength];
- NSArray *matchingCompletions = [[possibleCompletions filteredArrayUsingPredicate:predicate] sortedArrayUsingSelector:@selector(compare:)];
+ // Add all database names
+ MCPResult *queryResult = [[[[self window] delegate] valueForKeyPath:@"mySQLConnection"] valueForKey:@"listDBs"];
+ if ([queryResult numOfRows])
+ [queryResult dataSeek:0];
+ for (i = 0 ; i < [queryResult numOfRows] ; i++)
+ {
+ [possibleCompletions addObject:[[queryResult fetchRowAsArray] objectAtIndex:0]];
+ }
- unsigned i, insindex;
+ // If caret is not inside backticks add keywords and all words coming from the view.
+ if(!sqlStringIsTooLarge && ![[[self textStorage] attribute:kBTQuote atIndex:charRange.location effectiveRange:nil] isEqualToString:kBTQuoteValue] )
+ {
+ NSCharacterSet *separators = [NSCharacterSet characterSetWithCharactersInString:@" \t\r\n,()\"'`-!;=+|?:~"];
+ NSArray *textViewWords = [[self string] componentsSeparatedByCharactersInSet:separators];
+
+ [possibleCompletions addObjectsFromArray:textViewWords];
+ [possibleCompletions addObjectsFromArray:[self keywords]];
+ }
- insindex = 0;
+ // Check for possible completions
+ matchingCompletions = [[possibleCompletions filteredArrayUsingPredicate:predicate] sortedArrayUsingSelector:@selector(compare:)];
+
for (i = 0; i < [matchingCompletions count]; i++)
{
NSString* obj = [matchingCompletions objectAtIndex:i];
@@ -1734,6 +1761,13 @@ SYNTAX HIGHLIGHTING!
autouppercaseKeywordsEnabled = YES;
autohelpEnabled = NO;
delBackwardsWasPressed = NO;
+
+ // commentColor = [NSColor colorWithDeviceRed:0.000 green:0.455 blue:0.000 alpha:1.000];
+ // quoteColor = [NSColor colorWithDeviceRed:0.769 green:0.102 blue:0.086 alpha:1.000];
+ // keywordColor = [NSColor colorWithDeviceRed:0.200 green:0.250 blue:1.000 alpha:1.000];
+ // backtickColor = [NSColor colorWithDeviceRed:0.0 green:0.0 blue:0.658 alpha:1.000];
+ // numericColor = [NSColor colorWithDeviceRed:0.506 green:0.263 blue:0.0 alpha:1.000];
+ // variableColor = [NSColor colorWithDeviceRed:0.5 green:0.5 blue:0.5 alpha:1.000];
lineNumberView = [[NoodleLineNumberView alloc] initWithScrollView:scrollView];
[scrollView setVerticalRulerView:lineNumberView];
@@ -1761,24 +1795,9 @@ SYNTAX HIGHLIGHTING!
}
-- (void)textStorageDidProcessEditing:(NSNotification *)notification
-/*
- * Performs syntax highlighting.
- * This method recolors the entire text on every keypress. For performance reasons, this function does
- * nothing if the text is more than 20 KB.
- *
- * The main bottleneck is the [NSTextStorage addAttribute:value:range:] method - the parsing itself is really fast!
- *
- * Some sample code from Andrew Choi ( http://members.shaw.ca/akochoi-old/blog/2003/11-09/index.html#3 ) has been reused.
- */
+- (void)doSyntaxHighlighting:(NSTextStorage*)textStore
{
-
-
- NSTextStorage *textStore = [notification object];
-
- //make sure that the notification is from the correct textStorage object
- if (textStore!=[self textStorage]) return;
-
+ NSColor *tokenColor;
NSColor *commentColor = [NSColor colorWithDeviceRed:0.000 green:0.455 blue:0.000 alpha:1.000];
NSColor *quoteColor = [NSColor colorWithDeviceRed:0.769 green:0.102 blue:0.086 alpha:1.000];
NSColor *keywordColor = [NSColor colorWithDeviceRed:0.200 green:0.250 blue:1.000 alpha:1.000];
@@ -1786,8 +1805,6 @@ SYNTAX HIGHLIGHTING!
NSColor *numericColor = [NSColor colorWithDeviceRed:0.506 green:0.263 blue:0.0 alpha:1.000];
NSColor *variableColor = [NSColor colorWithDeviceRed:0.5 green:0.5 blue:0.5 alpha:1.000];
- NSColor *tokenColor;
-
int token;
NSRange textRange, tokenRange;
@@ -1885,11 +1902,37 @@ SYNTAX HIGHLIGHTING!
range: tokenRange ];
// Add an attribute to be used to distinguish quotes from keywords etc.
// used e.g. in completion suggestions
- if(token == SPT_DOUBLE_QUOTED_TEXT || token == SPT_SINGLE_QUOTED_TEXT || SPT_BACKTICK_QUOTED_TEXT)
+ else if(token < 4)
[textStore addAttribute: kQuote
- value: kValue
+ value: kQuoteValue
+ range: tokenRange ];
+ else if(token == SPT_BACKTICK_QUOTED_TEXT)
+ [textStore addAttribute: kBTQuote
+ value: kBTQuoteValue
range: tokenRange ];
}
+
+}
+
+/*
+ * Performs syntax highlighting.
+ * This method recolors the entire text on every keypress. For performance reasons, this function does
+ * nothing if the text is more than 20 KB.
+ *
+ * The main bottleneck is the [NSTextStorage addAttribute:value:range:] method - the parsing itself is really fast!
+ *
+ * Some sample code from Andrew Choi ( http://members.shaw.ca/akochoi-old/blog/2003/11-09/index.html#3 ) has been reused.
+ */
+- (void)textStorageDidProcessEditing:(NSNotification *)notification
+{
+
+
+ NSTextStorage *textStore = [notification object];
+
+ //make sure that the notification is from the correct textStorage object
+ if (textStore!=[self textStorage]) return;
+
+ [self doSyntaxHighlighting:textStore];
}
diff --git a/Source/SPEditorTokens.h b/Source/SPEditorTokens.h
index 44d0340f..65aba747 100644
--- a/Source/SPEditorTokens.h
+++ b/Source/SPEditorTokens.h
@@ -9,9 +9,9 @@
#define SPT_DOUBLE_QUOTED_TEXT 1
#define SPT_SINGLE_QUOTED_TEXT 2
-#define SPT_BACKTICK_QUOTED_TEXT 3
-#define SPT_RESERVED_WORD 4
-#define SPT_COMMENT 5
+#define SPT_COMMENT 3
+#define SPT_BACKTICK_QUOTED_TEXT 4
+#define SPT_RESERVED_WORD 5
#define SPT_WHITESPACE 6
#define SPT_WORD 7
#define SPT_OTHER 8
diff --git a/Source/SPEditorTokens.l b/Source/SPEditorTokens.l
index e366b552..dd206c7e 100644
--- a/Source/SPEditorTokens.l
+++ b/Source/SPEditorTokens.l
@@ -44,7 +44,7 @@ keywords (X(OR|509|A)|S(MALLINT|SL|H(OW({s}(E(NGINE(S)?|RRORS)|M(ASTER|UTEX)|BIN
%%
\"([^"\\]|\\(.|\n))*\"? { return SPT_DOUBLE_QUOTED_TEXT; } /* double quoted strings */
'([^'\\]|\\(.|\n))*'? { return SPT_SINGLE_QUOTED_TEXT; } /* single quoted strings */
-`[^`]*`? { return SPT_BACKTICK_QUOTED_TEXT; } /* identifier quoting */
+`[^`]*`? { return SPT_BACKTICK_QUOTED_TEXT; } /* backtick quoted string */
"/*" { BEGIN(comment); return SPT_COMMENT; } /* beginning of a c style comment */
<comment>[^*]* { return SPT_COMMENT; } /* anything except * in a c cmnt */