diff options
-rw-r--r-- | Source/NoodleLineNumberView.h | 6 | ||||
-rw-r--r-- | Source/NoodleLineNumberView.m | 28 | ||||
-rw-r--r-- | Source/SPSQLParser.m | 33 |
3 files changed, 40 insertions, 27 deletions
diff --git a/Source/NoodleLineNumberView.h b/Source/NoodleLineNumberView.h index 7b1d2a5a..855f75ee 100644 --- a/Source/NoodleLineNumberView.h +++ b/Source/NoodleLineNumberView.h @@ -57,8 +57,14 @@ SEL lineNumberForCharacterIndexSel; IMP lineNumberForCharacterIndexIMP; SEL lineRangeForRangeSel; + SEL numberWithUnsignedIntegerSel; + IMP numberWithUnsignedIntegerIMP; SEL addObjectSel; IMP addObjectIMP; + + NSLayoutManager *layoutManager; + NSTextContainer *container; + } @property(retain) NSColor *alternateTextColor; diff --git a/Source/NoodleLineNumberView.m b/Source/NoodleLineNumberView.m index 9fb57456..a701584c 100644 --- a/Source/NoodleLineNumberView.m +++ b/Source/NoodleLineNumberView.m @@ -56,7 +56,7 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); @interface NoodleLineNumberView (Private) -- (NSMutableArray *)lineIndices; +- (NSArray *)lineIndices; - (void)invalidateLineIndices; - (void)calculateLines; - (void)updateGutterThicknessConstants; @@ -89,6 +89,8 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); lineNumberForCharacterIndexIMP = [self methodForSelector:lineNumberForCharacterIndexSel]; lineRangeForRangeSel = @selector(lineRangeForRange:); addObjectSel = @selector(addObject:); + numberWithUnsignedIntegerSel = @selector(numberWithUnsignedInteger:); + numberWithUnsignedIntegerIMP = [NSNumber methodForSelector:numberWithUnsignedIntegerSel]; } @@ -173,9 +175,13 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); if ((aView != nil) && [aView isKindOfClass:[NSTextView class]]) { + layoutManager = [aView layoutManager]; + container = [aView textContainer]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange:) name:NSTextStorageDidProcessEditingNotification object:[(NSTextView *)aView textStorage]]; [self invalidateLineIndices]; } + } #pragma mark - @@ -192,7 +198,7 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); if(editMask != 1) [self invalidateLineIndices]; - [self setNeedsDisplay:YES]; + [self setNeedsDisplayInRect:[[[self scrollView] contentView] bounds]]; } @@ -295,8 +301,6 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); if ([view isKindOfClass:[NSTextView class]]) { - NSLayoutManager *layoutManager; - NSTextContainer *container; NSRect visibleRect; NSRange range, nullRange; NSString *labelText; @@ -306,8 +310,6 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); NSSize stringSize; NSArray *lines; - layoutManager = [view layoutManager]; - container = [view textContainer]; nullRange = NSMakeRange(NSNotFound, 0); yinset = [view textContainerInset].height; @@ -477,7 +479,7 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); #pragma mark - #pragma mark PrivateAPI -- (NSMutableArray *)lineIndices +- (NSArray *)lineIndices { if (lineIndices == nil) @@ -500,7 +502,8 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); if ([view isKindOfClass:[NSTextView class]]) { - NSUInteger index, stringLength, lineEnd, contentEnd; + + NSUInteger index, stringLength, lineEnd, contentEnd, lastLine; NSString *textString; CGFloat newThickness; @@ -522,18 +525,19 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); // Cache loop methods for speed RangeOfLineIMP rangeOfLineIMP = (RangeOfLineIMP)[textString methodForSelector:lineRangeForRangeSel]; addObjectIMP = [lineIndices methodForSelector:addObjectSel]; - + do { - (void*)(*addObjectIMP)(lineIndices, addObjectSel, [NSNumber numberWithUnsignedInteger:index]); + (void*)(*addObjectIMP)(lineIndices, addObjectSel, (*numberWithUnsignedIntegerIMP)([NSNumber class], numberWithUnsignedIntegerSel, index)); + lastLine = index; index = NSMaxRange((*rangeOfLineIMP)(textString, lineRangeForRangeSel, NSMakeRange(index, 0))); } while (index < stringLength); // Check if text ends with a new line. - [textString getLineStart:NULL end:&lineEnd contentsEnd:&contentEnd forRange:NSMakeRange([[lineIndices lastObject] unsignedIntegerValue], 0)]; + [textString getLineStart:NULL end:&lineEnd contentsEnd:&contentEnd forRange:NSMakeRange(lastLine, 0)]; if (contentEnd < lineEnd) - (void*)(*addObjectIMP)(lineIndices, addObjectSel, [NSNumber numberWithUnsignedInteger:index]); + (void*)(*addObjectIMP)(lineIndices, addObjectSel, (*numberWithUnsignedIntegerIMP)([NSNumber class], numberWithUnsignedIntegerSel, index)); NSUInteger lineCount = [lineIndices count]; if(lineCount < 10) diff --git a/Source/SPSQLParser.m b/Source/SPSQLParser.m index 4cb0aaa4..1650b2c2 100644 --- a/Source/SPSQLParser.m +++ b/Source/SPSQLParser.m @@ -668,6 +668,7 @@ TO_BUFFER_STATE to_scan_string (const char *); // Cache frequently used selectors, avoiding dynamic binding overhead IMP charAtIndex = [self methodForSelector:@selector(_charAtIndex:)]; + SEL charAtIndexSEL = @selector(_charAtIndex:); IMP endIndex = [self methodForSelector:@selector(endIndexOfStringQuotedByCharacter:startingAtIndex:)]; IMP substringWithRange = [self methodForSelector:@selector(substringWithRange:)]; @@ -676,7 +677,7 @@ TO_BUFFER_STATE to_scan_string (const char *); // Walk along the string, processing characters for (currentStringIndex = startIndex + 1; currentStringIndex < stringLength; currentStringIndex++) { - currentCharacter = (unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex); + currentCharacter = (unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex); // Check for the ending character, and if it has been found and quoting/brackets is valid, return. // If delimiter support is active and a delimiter is set, check for the delimiter @@ -722,8 +723,8 @@ TO_BUFFER_STATE to_scan_string (const char *); // For comments starting "--[\s]", ensure the start syntax is valid before proceeding. case '-': if (stringLength < currentStringIndex + 2) break; - if ((unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex+1) != '-') break; - if (![[NSCharacterSet whitespaceCharacterSet] characterIsMember:(unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex+2)]) break; + if ((unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex+1) != '-') break; + if (![[NSCharacterSet whitespaceCharacterSet] characterIsMember:(unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex+2)]) break; currentStringIndex = [self endIndexOfCommentOfType:SPDoubleDashComment startingAtIndex:currentStringIndex]; break; @@ -736,7 +737,7 @@ TO_BUFFER_STATE to_scan_string (const char *); case '/': if(ignoreCommentStrings) break; if (stringLength < currentStringIndex + 1) break; - if ((unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex+1) != '*') break; + if ((unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex+1) != '*') break; currentStringIndex = [self endIndexOfCommentOfType:SPCStyleComment startingAtIndex:currentStringIndex]; break; @@ -754,15 +755,15 @@ TO_BUFFER_STATE to_scan_string (const char *); // and that the "d" is the start of a word if (supportDelimiters && stringLength >= currentStringIndex + 11 && (currentStringIndex == 0 - || [[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:(unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex-1)])) + || [[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:(unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex-1)])) { - switch((unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex+1)) { + switch((unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex+1)) { case 'e': case 'E': - switch((unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex+2)) { + switch((unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex+2)) { case 'l': case 'L': - switch((unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex+3)) { + switch((unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex+3)) { case 'i': case 'I': if([self isMatchedByRegex:@"^(delimiter[ \\t]+(\\S+))(?=\\s|\\Z)" @@ -819,18 +820,19 @@ TO_BUFFER_STATE to_scan_string (const char *); // Cache the charAtIndex selector, avoiding dynamic binding overhead IMP charAtIndex = [self methodForSelector:@selector(_charAtIndex:)]; + SEL charAtIndexSEL = @selector(_charAtIndex:); stringLength = [string length]; // Walk the string looking for the string end for ( currentStringIndex = index; currentStringIndex < stringLength; currentStringIndex++) { - currentCharacter = (unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex); + currentCharacter = (unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex); // If the string end is a backtick and one has been encountered, treat it as end of string if (quoteCharacter == '`' && currentCharacter == '`') { // ...as long as the next character isn't also a backtick, in which case it's being quoted. Skip both. - if ((currentStringIndex + 1) < stringLength && (unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex+1) == '`') { + if ((currentStringIndex + 1) < stringLength && (unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex+1) == '`') { currentStringIndex++; continue; } @@ -844,7 +846,7 @@ TO_BUFFER_STATE to_scan_string (const char *); characterIsEscaped = NO; i = 1; quotedStringLength = currentStringIndex - 1; - while ((quotedStringLength - i) > 0 && (unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex - i) == '\\') { + while ((quotedStringLength - i) > 0 && (unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex - i) == '\\') { characterIsEscaped = !characterIsEscaped; i++; } @@ -852,7 +854,7 @@ TO_BUFFER_STATE to_scan_string (const char *); // If an even number have been found, it may be the end of the string - as long as the subsequent character // isn't also the same character, in which case it's another form of escaping. if (!characterIsEscaped) { - if ((currentStringIndex + 1) < stringLength && (unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), currentStringIndex+1) == quoteCharacter) { + if ((currentStringIndex + 1) < stringLength && (unichar)(long)(*charAtIndex)(self, charAtIndexSEL, currentStringIndex+1) == quoteCharacter) { currentStringIndex++; continue; } @@ -876,6 +878,7 @@ TO_BUFFER_STATE to_scan_string (const char *); // Cache the charAtIndex selector, avoiding dynamic binding overhead IMP charAtIndex = [self methodForSelector:@selector(_charAtIndex:)]; + SEL charAtIndexSEL = @selector(_charAtIndex:); switch (commentType) { @@ -888,7 +891,7 @@ TO_BUFFER_STATE to_scan_string (const char *); case SPHashComment: index++; for ( ; index < stringLength; index++ ) { - currentCharacter = (unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), index); + currentCharacter = (unichar)(long)(*charAtIndex)(self, charAtIndexSEL, index); if (currentCharacter == '\r') containsCRs = YES; if (currentCharacter == '\r' || currentCharacter == '\n') { return index-1; @@ -901,8 +904,8 @@ TO_BUFFER_STATE to_scan_string (const char *); case SPCStyleComment: index = index+2; for ( ; index < stringLength; index++ ) { - if ((unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), index) == '*') { - if ((stringLength > index + 1) && (unichar)(long)(*charAtIndex)(self, @selector(_charAtIndex:), index+1) == '/') { + if ((unichar)(long)(*charAtIndex)(self, charAtIndexSEL, index) == '*') { + if ((stringLength > index + 1) && (unichar)(long)(*charAtIndex)(self, charAtIndexSEL, index+1) == '/') { return (index+1); } } |