aboutsummaryrefslogtreecommitdiffstats
path: root/Source/CMTextView.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CMTextView.m')
-rw-r--r--Source/CMTextView.m104
1 files changed, 61 insertions, 43 deletions
diff --git a/Source/CMTextView.m b/Source/CMTextView.m
index 12b253da..cd00cafb 100644
--- a/Source/CMTextView.m
+++ b/Source/CMTextView.m
@@ -25,7 +25,7 @@
#import "SPStringAdditions.h"
/*
-all the extern variables and prototypes required for flex (syntax highlighting)
+all the extern variables and prototypes required for flex (used for syntax highlighting)
*/
#import "tokens.h"
extern int yylex();
@@ -84,7 +84,10 @@ YY_BUFFER_STATE yy_scan_string (const char *);
}
-
+/*
+List of keywords for autocompletion. If you add a keyword here,
+it should also be added to the flex file tokens.l
+*/
-(NSArray *)keywords {
return [NSArray arrayWithObjects:
@"ADD",
@@ -374,62 +377,77 @@ sets self as delegate for the textView's textStorage to enable syntax highlighti
- (void)textStorageDidProcessEditing:(NSNotification *)notification
/*
-performs syntax highlighting
-this method recolors the entire text on every keypress. for a single sql query,
-that should be no problem, but it could be a nuisance when editing large sql queries
-*/
+ 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 a few 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.
+ */
{
NSTextStorage *textStore = [notification object];
//make sure that the notification is from the correct textStorage object
- if (textStore==[self textStorage])
- {
+ if (textStore!=[self textStorage]) return;
- NSColor *reservedColor = [NSColor blueColor];
- NSColor *quoteColor = [NSColor grayColor];
- NSColor *commentColor = [NSColor redColor ];
-
- NSString *string = [textStore string];
- unsigned int length = [string length];
- int token;
- NSRange textRange, tokenRange;
-
- textRange = NSMakeRange(0, length);
-
- //first remove the old colors
- [textStore removeAttribute:NSForegroundColorAttributeName range:textRange];
-
- //initialise flex
- yyuoffset = 0; yyuleng = 0;
- yy_switch_to_buffer(yy_scan_string([[textStore string] UTF8String]));
-
- //now loop through all the tokens
- while (token=yylex()){
- tokenRange = NSMakeRange(yyuoffset, yyuleng); //convert the result from flex to an NSRange
- tokenRange = NSIntersectionRange(tokenRange, textRange); // make sure that tokenRange is valid (and therefore within textRange)
- // otherwise a bug in the lex code could cause the the TextView to crash
-
- switch (token) {
+
+ 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];
+
+ NSColor *tokenColor;
+
+ int token;
+ NSRange textRange, tokenRange;
+
+ textRange = NSMakeRange(0, [textStore length]);
+
+ //don't color texts longer than about 20KB. would be too slow
+ if (textRange.length > 20000) return;
+
+ //first remove the old colors
+ [textStore removeAttribute:NSForegroundColorAttributeName range:textRange];
+
+
+ //initialise flex
+ yyuoffset = 0; yyuleng = 0;
+ yy_switch_to_buffer(yy_scan_string([[textStore string] UTF8String]));
+
+ //now loop through all the tokens
+ while (token=yylex()){
+ switch (token) {
case SPT_SINGLE_QUOTED_TEXT:
case SPT_DOUBLE_QUOTED_TEXT:
- [textStore addAttribute: NSForegroundColorAttributeName
- value: quoteColor
- range: tokenRange ];
+ tokenColor = quoteColor;
break;
case SPT_RESERVED_WORD:
- [textStore addAttribute: NSForegroundColorAttributeName
- value: reservedColor
- range: tokenRange ];
+ tokenColor = keywordColor;
break;
case SPT_COMMENT:
- [textStore addAttribute: NSForegroundColorAttributeName
- value: commentColor
- range: tokenRange ];
+ tokenColor = commentColor;
break;
- }}
+ default:
+ tokenColor = nil;
+ }
+
+ if (!tokenColor) continue;
+
+ tokenRange = NSMakeRange(yyuoffset, yyuleng);
+
+ // make sure that tokenRange is valid (and therefore within textRange)
+ // otherwise a bug in the lex code could cause the the TextView to crash
+ tokenRange = NSIntersectionRange(tokenRange, textRange);
+ if (!tokenRange.length) continue;
+
+ [textStore addAttribute: NSForegroundColorAttributeName
+ value: tokenColor
+ range: tokenRange ];
}
+
}
+
@end