instead of using getLineStart which returns a character after scanning lines, we directly scan lines and count the newlines, so the string is needs to be scanned once only to know hoe many newlines. Some IMP caching to improve this ineffcient o(n) at every cursor movement

This commit is contained in:
Riccardo Mottola 2021-09-17 00:53:40 +02:00
parent bae62a963b
commit aff171ceff

View file

@ -967,15 +967,36 @@
if ([object isKindOfClass:[NSTextView class]]) if ([object isKindOfClass:[NSTextView class]])
{ {
NSTextView *tv = (NSTextView *)object; NSTextView *tv = (NSTextView *)object;
NSArray *selArray; NSString *str = [tv string];
NSRange lastSelection; NSRange selection;
NSRange selRange; NSUInteger selLine = NSNotFound;
NSUInteger selLine;
selArray = [tv selectedRanges]; // for speed reasons we cache [NSString characterAtIndex:index]
lastSelection = [[selArray lastObject] rangeValue]; SEL charAtIndexSel = @selector(characterAtIndex:);
NSLog(@"last selection is %@", [selArray lastObject]); unichar (*charAtIndexFunc)(NSString *, SEL, NSUInteger);
[[tv string] getLineStart:NULL end:&selLine contentsEnd:NULL forRange:lastSelection]; charAtIndexFunc = (unichar (*)())[str methodForSelector:charAtIndexSel];
selection = [tv selectedRange];
// now we calculate given the selection the line count, splitting on \n
// calling lineRangeForRange / paragraphForRange does the same thing
// we want to avoid to scan the string twice
{
NSUInteger i;
unichar ch;
NSUInteger nlCount;
nlCount = 0;
for (i = 0; i < selection.location; i++)
{
// ch = [str characterAtIndex:i];
ch = (*charAtIndexFunc)(str, charAtIndexSel, i);
if (ch == (unichar)0x000A) // new line
nlCount++;
}
selLine = nlCount + 1;
}
NSLog(@"%u corresponds to %u", selection.location, selLine);
} }
} }