The R Project SVN R-packages

Rev

Rev 5741 | Rev 5770 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5741 Rev 5756
Line 104... Line 104...
104
 
104
 
105
- (void)awakeFromNib
105
- (void)awakeFromNib
106
{
106
{
107
 
107
 
108
	SLog(@"RScriptEditorTextView: awakeFromNib <%@>", self);
108
	SLog(@"RScriptEditorTextView: awakeFromNib <%@>", self);
109
 
-
 
-
 
109
	isSyntaxHighlighting = NO;
110
	prefs = [[NSUserDefaults standardUserDefaults] retain];
110
	prefs = [[NSUserDefaults standardUserDefaults] retain];
111
	[[Preferences sharedPreferences] addDependent:self];
111
	[[Preferences sharedPreferences] addDependent:self];
112
 
112
 
113
	if([prefs objectForKey:highlightCurrentLine] == nil) [prefs setBool:YES forKey:highlightCurrentLine];
113
	if([prefs objectForKey:highlightCurrentLine] == nil) [prefs setBool:YES forKey:highlightCurrentLine];
114
	if([prefs objectForKey:indentNewLines] == nil) [prefs setBool:YES forKey:indentNewLines];
114
	if([prefs objectForKey:indentNewLines] == nil) [prefs setBool:YES forKey:indentNewLines];
Line 149... Line 149...
149
		[scrollView setRulersVisible:YES];
149
		[scrollView setRulersVisible:YES];
150
	}
150
	}
151
	[self setAllowsDocumentBackgroundColorChange:YES];
151
	[self setAllowsDocumentBackgroundColorChange:YES];
152
	[self setContinuousSpellCheckingEnabled:NO];
152
	[self setContinuousSpellCheckingEnabled:NO];
153
 
153
 
-
 
154
	if(![Preferences flagForKey:enableLineWrappingKey withDefault: YES])
-
 
155
		[scrollView setHasHorizontalScroller:YES];
-
 
156
 
154
	// Re-define tab stops for a better editing
157
	// Re-define tab stops for a better editing
155
	[self setTabStops];
158
	[self setTabStops];
156
 
159
 
157
	// disabled to get the current text range in textView safer
160
	// disabled to get the current text range in textView safer
158
	[[self layoutManager] setBackgroundLayoutEnabled:NO];
161
	[[self layoutManager] setBackgroundLayoutEnabled:NO];
159
 
162
 
160
	NSSize layoutSize = [self maxSize];
-
 
161
	[self setHorizontallyResizable:YES];
-
 
162
	[self setMaxSize: layoutSize];
-
 
163
	if (!lineWrappingEnabled) {
-
 
164
		[scrollView setHasHorizontalScroller:YES];
-
 
165
		[[self textContainer] setWidthTracksTextView:NO];
-
 
166
	} else {
-
 
167
		[scrollView setHasHorizontalScroller:NO];
-
 
168
		[[self textContainer] setWidthTracksTextView:YES];
-
 
169
	}
-
 
170
	[[self textContainer] setHeightTracksTextView: NO];
-
 
171
	[[self textContainer] setContainerSize:layoutSize];
-
 
172
 
-
 
173
	// add NSViewBoundsDidChangeNotification to scrollView
163
	// add NSViewBoundsDidChangeNotification to scrollView
174
	[scrollView setPostsBoundsChangedNotifications:YES];
164
	[scrollView setPostsBoundsChangedNotifications:YES];
175
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(boundsDidChangeNotification:) name:NSViewBoundsDidChangeNotification object:[scrollView contentView]];
165
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(boundsDidChangeNotification:) name:NSViewBoundsDidChangeNotification object:[scrollView contentView]];
176
 
166
 
177
	NSColor *c = [Preferences unarchivedObjectForKey:normalSyntaxColorKey withDefault:nil];
167
	NSColor *c = [Preferences unarchivedObjectForKey:normalSyntaxColorKey withDefault:nil];
Line 330... Line 320...
330
		} else {
320
		} else {
331
			[theTextStorage removeAttribute:NSForegroundColorAttributeName range:NSMakeRange(0, [[theTextStorage string] length])];
321
			[theTextStorage removeAttribute:NSForegroundColorAttributeName range:NSMakeRange(0, [[theTextStorage string] length])];
332
		}
322
		}
333
 
323
 
334
	} else if ([keyPath isEqualToString:enableLineWrappingKey]) {
324
	} else if ([keyPath isEqualToString:enableLineWrappingKey]) {
335
		lineWrappingEnabled = [[change objectForKey:NSKeyValueChangeNewKey] boolValue];
-
 
336
		NSSize layoutSize = NSMakeSize(10e6,10e6);
-
 
337
		[self setHorizontallyResizable:YES];
-
 
338
		[self setMaxSize: layoutSize];
325
		[self updateLineWrappingMode];
339
		[[self textContainer] setContainerSize:layoutSize];
-
 
340
		if (!lineWrappingEnabled) {
-
 
341
			[scrollView setHasHorizontalScroller:YES];
-
 
342
			[[self textContainer] setWidthTracksTextView:NO];
-
 
343
		} else {
-
 
344
			[[self textContainer] setContainerSize:[self bounds].size];
-
 
345
			[scrollView setHasHorizontalScroller:NO];
-
 
346
			[[self textContainer] setWidthTracksTextView:YES];
-
 
347
			// Enforce view to be re-layouted correctly
-
 
348
			[[self undoManager] disableUndoRegistration];
-
 
349
			[self selectAll:nil];
-
 
350
			[self cut:nil];
-
 
351
			[self paste:nil];
-
 
352
			[[self undoManager] enableUndoRegistration];
-
 
353
		}
-
 
354
		[[self textContainer] setHeightTracksTextView:NO];
-
 
355
 
-
 
356
		[[NSNotificationCenter defaultCenter] postNotificationName:NSWindowDidResizeNotification object:[[self delegate] window]];
-
 
357
 
326
 
358
	} else if ([keyPath isEqualToString:prefShowArgsHints]) {
327
	} else if ([keyPath isEqualToString:prefShowArgsHints]) {
359
		argsHints = [[change objectForKey:NSKeyValueChangeNewKey] boolValue];
328
		argsHints = [[change objectForKey:NSKeyValueChangeNewKey] boolValue];
360
		if(!argsHints) {
329
		if(!argsHints) {
361
			[[self delegate] setStatusLineText:@""];
330
			[[self delegate] setStatusLineText:@""];
Line 371... Line 340...
371
		} else if ([keyPath isEqualToString:HighlightIntervalKey]) {
340
		} else if ([keyPath isEqualToString:HighlightIntervalKey]) {
372
		braceHighlightInterval = [Preferences floatForKey:HighlightIntervalKey withDefault:0.3f];
341
		braceHighlightInterval = [Preferences floatForKey:HighlightIntervalKey withDefault:0.3f];
373
	}
342
	}
374
}
343
}
375
 
344
 
-
 
345
- (void)updateLineWrappingMode
-
 
346
{
-
 
347
 
-
 
348
	NSSize layoutSize;
-
 
349
 
-
 
350
	lineWrappingEnabled = [Preferences flagForKey:enableLineWrappingKey withDefault: YES];
-
 
351
	[self setHorizontallyResizable:YES];
-
 
352
	if (!lineWrappingEnabled) {
-
 
353
		layoutSize = NSMakeSize(10e6,10e6);
-
 
354
		[scrollView setHasHorizontalScroller:YES];
-
 
355
		[self setMaxSize:layoutSize];
-
 
356
		[[self textContainer] setContainerSize:layoutSize];
-
 
357
		[[self textContainer] setWidthTracksTextView:NO];
-
 
358
	} else {
-
 
359
		[scrollView setHasHorizontalScroller:NO];
-
 
360
		layoutSize = [self maxSize];
-
 
361
		[self setMaxSize:layoutSize];
-
 
362
		[[self textContainer] setContainerSize:layoutSize];
-
 
363
		[[self textContainer] setWidthTracksTextView:YES];
-
 
364
		// Enforce view to be re-layouted correctly
-
 
365
		[[self undoManager] disableUndoRegistration];
-
 
366
		[self selectAll:nil];
-
 
367
		[self cut:nil];
-
 
368
		[self paste:nil];
-
 
369
		[[self undoManager] enableUndoRegistration];
-
 
370
	}
-
 
371
	[[self textContainer] setHeightTracksTextView:NO];
-
 
372
 
-
 
373
	[[NSNotificationCenter defaultCenter] postNotificationName:NSWindowDidResizeNotification object:[[self delegate] window]];
-
 
374
}
-
 
375
 
376
- (void)drawRect:(NSRect)rect
376
- (void)drawRect:(NSRect)rect
377
{
377
{
378
	// Draw background only for screen display but not while printing
378
	// Draw background only for screen display but not while printing
379
	if([NSGraphicsContext currentContextDrawingToScreen]) {
379
	if([NSGraphicsContext currentContextDrawingToScreen]) {
380
 
380
 
Line 516... Line 516...
516
 * Some sample code from Andrew Choi ( http://members.shaw.ca/akochoi-old/blog/2003/11-09/index.html#3 ) has been reused.
516
 * Some sample code from Andrew Choi ( http://members.shaw.ca/akochoi-old/blog/2003/11-09/index.html#3 ) has been reused.
517
 */
517
 */
518
- (void)doSyntaxHighlighting
518
- (void)doSyntaxHighlighting
519
{
519
{
520
 
520
 
521
	if (!syntaxHighlightingEnabled || [[self delegate] plain] || [theTextStorage length] > 40000000) return;
521
	if (isSyntaxHighlighting || !syntaxHighlightingEnabled || [[self delegate] plain] || [theTextStorage length] > 40000000) return;
522
 
522
 
523
	NSString *selfstr        = [theTextStorage string];
523
	NSString *selfstr    = [theTextStorage string];
524
	NSUInteger strlength     = [selfstr length];
524
	NSInteger strlength  = (NSInteger)[selfstr length];
525
 
525
 
526
	// Avoid syntax highlighting of a big change but re-trigger it for highlighting it partly
526
	// Avoid syntax highlighting of a big change but re-trigger it for highlighting it partly
527
	if([theTextStorage editedRange].length > (int)(R_SYNTAX_HILITE_BIAS * 4)) {
527
	if([theTextStorage editedRange].length > (int)(R_SYNTAX_HILITE_BIAS * 4)) {
528
		[self insertText:@""];
528
		[self insertText:@""];
529
		// remove inserting action from undo manager is keep edit status
529
		// remove inserting action from undo manager is keep edit status
530
		[[self undoManager] undo];
530
		[[self undoManager] undo];
531
		return;
531
		return;
532
	}
532
	}
533
 
533
 
534
	// Do highlighting partly (max R_SYNTAX_HILITE_BIAS*2).
534
	// == Do highlighting partly (max R_SYNTAX_HILITE_BIAS*2 around visibleRange
535
	// The approach is to take the middle position of the current view port
-
 
536
	// and highlight only ±R_SYNTAX_HILITE_BIAS of that middle position
-
 
537
	// considering of line starts resp. ends
535
	// by considering entire lines).
538
 
536
 
539
	// Get the text range currently displayed in the view port
537
	// Get the text range currently displayed in the view port
540
	NSRect visibleRect = [[[self enclosingScrollView] contentView] documentVisibleRect];
538
	NSRect visibleRect = [[[self enclosingScrollView] contentView] documentVisibleRect];
541
	NSRange visibleRange = [[self layoutManager] glyphRangeForBoundingRectWithoutAdditionalLayout:visibleRect inTextContainer:[self textContainer]];
539
	NSRange visibleRange = [[self layoutManager] glyphRangeForBoundingRectWithoutAdditionalLayout:visibleRect inTextContainer:[self textContainer]];
542
 
540
 
543
	if(!visibleRange.length) return;
541
	if(!visibleRange.length) return;
544
 
542
 
545
	// Take roughly the middle position in the current view port
543
	NSInteger start = visibleRange.location - R_SYNTAX_HILITE_BIAS;
-
 
544
	if (start > 0)
-
 
545
		while(start > 0) {
546
	NSUInteger curPos = visibleRange.location+(NSUInteger)(visibleRange.length/2);
546
			if(CFStringGetCharacterAtIndex((CFStringRef)selfstr, start)=='\n')
-
 
547
				break;
-
 
548
			start--;
547
 
549
		}
548
	// get the last line to parse due to R_SYNTAX_HILITE_BIAS
550
	if(start < 0) start = 0;
549
	// but look for only R_SYNTAX_HILITE_BIAS chars forwards
-
 
550
	NSUInteger end = curPos + R_SYNTAX_HILITE_BIAS;
551
	NSInteger end = NSMaxRange(visibleRange) + R_SYNTAX_HILITE_BIAS;
551
	NSInteger lengthChecker = R_SYNTAX_HILITE_BIAS;
-
 
552
	if (end > strlength ) {
552
	if (end > strlength) {
553
		end = strlength;
553
		end = strlength;
554
	} else {
554
	} else {
555
		while(end < strlength && lengthChecker > 0) {
555
		while(end < strlength) {
556
			if(CFStringGetCharacterAtIndex((CFStringRef)selfstr, end)=='\n')
556
			if(CFStringGetCharacterAtIndex((CFStringRef)selfstr, end)=='\n')
557
				break;
557
				break;
558
			end++;
558
			end++;
559
			lengthChecker--;
-
 
560
		}
559
		}
561
	}
560
	}
562
	if(lengthChecker <= 0)
-
 
563
		end = curPos + R_SYNTAX_HILITE_BIAS;
-
 
564
 
-
 
565
	// get the first line to parse due to R_SYNTAX_HILITE_BIAS
-
 
566
	// but look for only R_SYNTAX_HILITE_BIAS chars backwards
-
 
567
	NSUInteger start, start_temp;
-
 
568
	if(end <= (R_SYNTAX_HILITE_BIAS*2))
-
 
569
	 	start = 0;
-
 
570
	else
-
 
571
	 	start = end - (R_SYNTAX_HILITE_BIAS*2);
-
 
572
 
-
 
573
	start_temp = start;
-
 
574
	lengthChecker = R_SYNTAX_HILITE_BIAS;
-
 
575
	if (start > 0)
-
 
576
		while(start>0 && lengthChecker > 0) {
-
 
577
			if(CFStringGetCharacterAtIndex((CFStringRef)selfstr, start)=='\n')
-
 
578
				break;
-
 
579
			start--;
-
 
580
			lengthChecker--;
-
 
581
		}
-
 
582
	if(lengthChecker <= 0)
-
 
583
		start = start_temp;
-
 
584
 
561
 
585
	NSRange textRange = NSMakeRange(start, end-start);
562
	NSRange textRange = NSMakeRange(start, end-start);
586
 
563
 
587
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
564
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
588
	[[self layoutManager] ensureLayoutForCharacterRange:textRange];
565
	[[self layoutManager] ensureLayoutForCharacterRange:textRange];
Line 591... Line 568...
591
	// only to be sure that nothing went wrongly
568
	// only to be sure that nothing went wrongly
592
	textRange = NSIntersectionRange(textRange, NSMakeRange(0, [theTextStorage length])); 
569
	textRange = NSIntersectionRange(textRange, NSMakeRange(0, [theTextStorage length])); 
593
 
570
 
594
	if (!textRange.length)
571
	if (!textRange.length)
595
		return;
572
		return;
596
 
-
 
-
 
573
	isSyntaxHighlighting = YES;
597
	[theTextStorage beginEditing];
574
	[theTextStorage beginEditing];
598
 
575
 
599
	NSColor *tokenColor = nil;
576
	NSColor *tokenColor = nil;
600
 
577
 
601
	size_t tokenEnd, token;
578
	size_t tokenEnd, token;
Line 651... Line 628...
651
		// If the current token is marked as SQL keyword, uppercase it if required.
628
		// If the current token is marked as SQL keyword, uppercase it if required.
652
		tokenEnd = NSMaxRange(tokenRange) - 1;
629
		tokenEnd = NSMaxRange(tokenRange) - 1;
653
 
630
 
654
		NSMutableAttributedStringAddAttributeValueRange(theTextStorage, NSForegroundColorAttributeName, tokenColor, tokenRange);
631
		NSMutableAttributedStringAddAttributeValueRange(theTextStorage, NSForegroundColorAttributeName, tokenColor, tokenRange);
655
		
632
		
656
		// if(!allowToCheckForUpperCase) continue;
-
 
657
		
-
 
658
		// Add an attribute to be used in the auto-pairing (keyDown:)
633
		// Add an attribute to be used in the auto-pairing (keyDown:)
659
		// to disable auto-pairing if caret is inside of any token found by lex.
634
		// to disable auto-pairing if caret is inside of any token found by lex.
660
		// For discussion: maybe change it later (only for quotes not keywords?)
635
		// For discussion: maybe change it later (only for quotes not keywords?)
661
		if(token < 6)
636
		if(token < 6)
662
			NSMutableAttributedStringAddAttributeValueRange(theTextStorage, kLEXToken, kLEXTokenValue, tokenRange);
637
			NSMutableAttributedStringAddAttributeValueRange(theTextStorage, kLEXToken, kLEXTokenValue, tokenRange);
Line 680... Line 655...
680
		if(c) [typeAttr setObject:c forKey:NSForegroundColorAttributeName];
655
		if(c) [typeAttr setObject:c forKey:NSForegroundColorAttributeName];
681
		[self setTypingAttributes:typeAttr];
656
		[self setTypingAttributes:typeAttr];
682
	}
657
	}
683
 
658
 
684
	[theTextStorage endEditing];
659
	[theTextStorage endEditing];
-
 
660
	isSyntaxHighlighting = NO;
685
 
661
 
686
}
662
}
687
 
663
 
688
-(void)resetHighlights
664
-(void)resetHighlights
689
{
665
{
Line 739... Line 715...
739
	if(startListeningToBoundChanges) {
715
	if(startListeningToBoundChanges) {
740
		[NSObject cancelPreviousPerformRequestsWithTarget:self 
716
		[NSObject cancelPreviousPerformRequestsWithTarget:self 
741
									selector:@selector(doSyntaxHighlighting) 
717
									selector:@selector(doSyntaxHighlighting) 
742
									object:nil];
718
									object:nil];
743
 
719
 
744
		if(![theTextStorage changeInLength]) {
720
		if(![theTextStorage changeInLength] && ![self selectedRange].length) {
745
			[self performSelector:@selector(doSyntaxHighlighting) withObject:nil afterDelay:0.05];
721
			[self performSelector:@selector(doSyntaxHighlighting) withObject:nil afterDelay:0.05];
746
 
722
 
747
		}
723
		}
748
	}
724
	}
749
 
725