Skip to content

Commit

Permalink
• fixed bug for RTextView:copy
Browse files Browse the repository at this point in the history
• fixed issues for changing font size via trackpad gesture
• fixed issue for setting selection background color
• started to add functionality to support user-definable actions like inserting programmable text macros with highlighted snippet etc. - will be continued soon
• improved *.R dragging by applying the above mentioned text macro mechanism
- the value of the parameter(s) 'chdir' is/are highlighted which can then changed by the user; use TAB and SHIFT+TAB to navigate through the highlighted snippets; a final TAB will place the cursor at the end of the inserted template - docs will follow
- added possibility to the user to define other drag actions due to file extension - docs will follow
- fixed some minor issues
• some minor fixes and improvements

git-svn-id: https://svn.r-project.org/R-packages/trunk/Mac-GUI@6070 694ef91d-65df-0310-b7bb-92e67a308ead
  • Loading branch information
Hans-Jörg Bibiko committed Feb 8, 2012
1 parent f4e505e commit f4df599
Show file tree
Hide file tree
Showing 11 changed files with 1,103 additions and 85 deletions.
15 changes: 12 additions & 3 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
NEWS for R.app GUI for Mac OS X

Last-update: 2012-02-05 [HJBB]
Last-update: 2012-02-08 [HJBB]
* In Script Editor "function list" selection
follows cursor position.
* Added support for dragging *.R and *.Rdata files to
RConsole or Script Editor to insert template
"source()" and "load()" resp. For these file
extensions holding down CMD key while dragging
will insert the file path only.
will insert the file path only. The file path will be
inserted relative to the documents and the set working
directory resp. By holding down the ALT key while dragging
the full path will be inserted.
For dragged *.R files the value(s) of the paramater 'chdir'
is/are highlighted. The highlighted parts of the template
can be reached by press TAB and SHIFT+TAB. A TAB for the
last highlighted part will place the cursor at the end of
the inserted template. This mechanism is part of the new
implemented user-definable text macro system.
* "Copy" for RConsole and Script Editor will also add
rich text format (RTF) data to the pasteboard in order
to be able to paste text syntax highlighted
to be able to paste text syntax highlighted.

Last-update: 2012-02-02 [HJBB]
* Added under menu Format > "Format Source Code".
Expand Down
38 changes: 26 additions & 12 deletions NSString_RAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*
*/

#import "RGUI.h"
#import "NSString_RAdditions.h"
#import "RegexKitLite.h"
#import "PreferenceKeys.h"
Expand Down Expand Up @@ -129,11 +130,12 @@ - (NSString *)evaluateAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironme
[bashTask setLaunchPath:@"/bin/bash"];

NSMutableDictionary *theEnv = [NSMutableDictionary dictionary];
if(shellEnvironment)
[theEnv setDictionary:shellEnvironment];
else
[theEnv setDictionary:[[NSProcessInfo processInfo] environment]];
// set current environment variables to shell
[theEnv setDictionary:[[NSProcessInfo processInfo] environment]];
// overwrite or set additional variables
if(shellEnvironment) [theEnv addEntriesFromDictionary:shellEnvironment];

// set exit codes
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionNone] forKey:kBASHTaskShellVariableExitNone];
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionReplaceSection] forKey:kBASHTaskShellVariableExitReplaceSelection];
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionReplaceContent] forKey:kBASHTaskShellVariableExitReplaceContent];
Expand Down Expand Up @@ -169,16 +171,16 @@ - (NSString *)evaluateAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironme

NSInteger pid = -1;
pid = [bashTask processIdentifier];

if(!nonWaitingMode) {
// Listen to ⌘. to terminate
while(1) {
if(![bashTask isRunning] || [bashTask processIdentifier] == 0) break;
usleep(1000);
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast]
inMode:NSDefaultRunLoopMode
dequeue:YES];
usleep(10000);
if(!event) continue;
if ([event type] == NSKeyDown) {
unichar key = [[event characters] length] == 1 ? [[event characters] characterAtIndex:0] : 0;
Expand All @@ -192,7 +194,6 @@ - (NSString *)evaluateAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironme
[NSApp sendEvent:event];
}
}

[bashTask waitUntilExit];
} else {
if (bashTask) [bashTask release];
Expand All @@ -209,13 +210,26 @@ - (NSString *)evaluateAsBashCommandWithEnvironment:(NSDictionary*)shellEnvironme

NSInteger status = [bashTask terminationStatus];
NSData *errdata = nil;

if(stderr_file) errdata = [stderr_file readDataToEndOfFile];

if(status == 9 || userTerminated) {
if(theError != NULL)
*theError = [[[NSError alloc] initWithDomain:NSPOSIXErrorDomain
code:status
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
NLS(@"User Termination"),
NSLocalizedDescriptionKey,
@"",
@"terminated",
nil]] autorelease];
return @"";
}


// Check STDERR
if(theError != NULL && [errdata length] && (status < kBASHTaskRedirectActionNone || status > kBASHTaskRedirectActionLastCode)) {
if(theError != NULL && errdata && [errdata length] && (status < kBASHTaskRedirectActionNone || status > kBASHTaskRedirectActionLastCode)) {
[fm removeItemAtPath:stdoutFilePath error:nil];
if(stderr_file) [stderr_file readDataToEndOfFile];
if(status == 9 || userTerminated) return @"";
if(theError != NULL) {
if(theError != NULL && errdata && [errdata length]) {
NSMutableString *errMessage = [[[NSMutableString alloc] initWithData:errdata encoding:NSUTF8StringEncoding] autorelease];
[errMessage replaceOccurrencesOfString:[NSString stringWithFormat:@"%@: ", scriptFilePath] withString:@"" options:NSLiteralSearch range:NSMakeRange(0, [errMessage length])];
*theError = [[[NSError alloc] initWithDomain:NSPOSIXErrorDomain
Expand Down
21 changes: 0 additions & 21 deletions NSTextView_RAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -506,25 +506,4 @@ - (void)makeTextSizeSmaller
[self setEditable:editableStatus];
}




#pragma mark -
#pragma mark multi-touch trackpad support

/**
* Trackpad two-finger zooming gesture for in/decreasing the font size
*/
- (void) magnifyWithEvent:(NSEvent *)anEvent
{

//Font resizing for RTextViews only
if([(RTextView*)self isRConsole]) return;

if([anEvent deltaZ]>5.0)
[self makeTextSizeLarger];
else if([anEvent deltaZ]<-5.0)
[self makeTextSizeSmaller];
}

@end
2 changes: 1 addition & 1 deletion PrefPanes/SyntaxColorsPrefPane.m
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ - (void) updatePreferences
if (c && ![c isEqualTo:[currentLineSyntaxColorWell color]]) [currentLineSyntaxColorWell setColor:c];
c=[Preferences unarchivedObjectForKey:editorCursorColorKey withDefault:[NSColor colorWithDeviceRed:0.000 green:0.000 blue:0.000 alpha:1.0]];
if (c && ![c isEqualTo:[cursorSyntaxColorWell color]]) [cursorSyntaxColorWell setColor:c];
c=[Preferences unarchivedObjectForKey:editorSelectionBackgroundColorKey withDefault:[NSColor selectedControlTextColor]];
c=[Preferences unarchivedObjectForKey:editorSelectionBackgroundColorKey withDefault:[NSColor colorWithCalibratedRed:0.71f green:0.835f blue:1.0f alpha:1.0f]];
if (c && ![c isEqualTo:[selectionSyntaxColorWell color]]) [selectionSyntaxColorWell setColor:c];

// c=[Preferences unarchivedObjectForKey:sectionRdSyntaxColorKey withDefault:nil];
Expand Down
15 changes: 15 additions & 0 deletions PreferenceKeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,21 @@
#define kBASHTaskShellVariableExitReplaceContent @"R_TASK_EXIT_REPLACE_CONTENT"
#define kBASHTaskShellVariableExitReplaceSelection @"R_TASK_EXIT_REPLACE_SELECTION"

// user defined actions and snippet support

#define kDragActionFolderName @"DragActions"
#define kUserCommandFileName @"command.sh"

#define kShellVarNameDraggedFilePath @"R_DRAGGED_FILE_PATH"
#define kShellVarNameDraggedRelativeFilePath @"R_DRAGGED_RELATIVE_FILE_PATH"
#define kShellVarNameCurrentLine @"R_CURRENT_LINE"
#define kShellVarNameCurrentWord @"R_CURRENT_WORD"
#define kShellVarNameSelectedText @"R_SELECTED_TEXT"
#define kShellVarNameCommandPath @"R_COMMAND_PATH"
#define kShellVarNameCurrentFilePath @"R_FILE_PATH"
#define kShellVarNameCurrentSnippetIndex @"R_CURRENT_SNIPPET_INDEX"



// other constants

Expand Down
4 changes: 4 additions & 0 deletions RController.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@
NSString *home;
NSString *lastFunctionForHint;
NSString *lastFunctionHintText;

NSString *appSupportPath;
}

/* process pending events. if blocking is set to YES then the method waits indefinitely for one event. otherwise only pending events are processed. */
Expand Down Expand Up @@ -303,9 +305,11 @@

- (NSString*) home;
- (NSString*) currentWorkingDirectory;
- (NSString*)getAppSupportPath;
- (int) helpServerPort;
- (BOOL)isREditMode;


- (IBAction)performFindPanelAction:(id)sender;
- (IBAction)performFindPanelFindInWebViewAction:(id)sender;
- (IBAction)closeFindInWebViewSheet:(id)sender;
Expand Down
61 changes: 59 additions & 2 deletions RController.m
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ - (id) init {
stderrColorKey, stdoutColorKey, rootColorKey, selectionColorKey, nil];
defaultConsoleColors = [[NSArray alloc] initWithObjects: // default colors
[NSColor whiteColor], [NSColor blueColor], [NSColor blackColor], [NSColor purpleColor],
[NSColor redColor], [NSColor grayColor], [NSColor purpleColor], [NSColor selectedControlTextColor], nil];
[NSColor redColor], [NSColor grayColor], [NSColor purpleColor], [NSColor colorWithCalibratedRed:0.71f green:0.835f blue:1.0f alpha:1.0f], nil];
consoleColors = [defaultConsoleColors mutableCopy];

filteredHistory = nil;
Expand All @@ -227,6 +227,7 @@ - (id) init {

lastFunctionForHint = [[NSString stringWithString:@""] retain];
lastFunctionHintText = nil;
appSupportPath = nil;

return self;

Expand Down Expand Up @@ -331,6 +332,11 @@ - (void) awakeFromNib {
[consoleTextView setFont:[Preferences unarchivedObjectForKey:RConsoleDefaultFont withDefault:[NSFont fontWithName:@"Monaco" size:11]]];
[consoleTextView setDrawsBackground:NO];
[[consoleTextView enclosingScrollView] setDrawsBackground:NO];
NSMutableDictionary *attr = [NSMutableDictionary dictionary];
[attr setDictionary:[consoleTextView selectedTextAttributes]];
[attr setObject:[Preferences unarchivedObjectForKey:selectionColorKey withDefault:[NSColor colorWithCalibratedRed:0.71f green:0.835f blue:1.0f alpha:1.0f]] forKey:NSBackgroundColorAttributeName];
[consoleTextView setSelectedTextAttributes:attr];
[consoleTextView setNeedsDisplayInRect:[consoleTextView bounds]];

NSLayoutManager *lm = [[consoleTextView layoutManager] retain];
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
Expand Down Expand Up @@ -1061,6 +1067,7 @@ - (void) dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[Preferences sharedPreferences] removeDependent:self];
if(home) [home release];
if(appSupportPath) [appSupportPath release];
if(filteredHistory) [filteredHistory release], filteredHistory = nil;
if(currentWebViewForFindAction) [currentWebViewForFindAction release];
if(searchInWebViewWindow) [searchInWebViewWindow release], searchInWebViewWindow = nil;
Expand Down Expand Up @@ -2205,6 +2212,8 @@ - (void)textStorageDidProcessEditing:(NSNotification *)notification
// if the user really changed the text
if(editedMask != 1) {

[consoleTextView checkSnippets];

// Cancel setting undo break point
[NSObject cancelPreviousPerformRequestsWithTarget:consoleTextView
selector:@selector(breakUndoCoalescing)
Expand Down Expand Up @@ -3622,7 +3631,7 @@ - (void) updatePreferences {
[attr setObject:[consoleColors objectAtIndex:iInputColor] forKey:NSForegroundColorAttributeName];
[consoleTextView setTypingAttributes:attr];
[attr setDictionary:[consoleTextView selectedTextAttributes]];
[attr setObject:[consoleColors objectAtIndex:iSelectionColor] forKey:NSForegroundColorAttributeName];
[attr setObject:[consoleColors objectAtIndex:iSelectionColor] forKey:NSBackgroundColorAttributeName];
[consoleTextView setSelectedTextAttributes:attr];
}
[consoleTextView setNeedsDisplay:YES];
Expand All @@ -3641,6 +3650,46 @@ - (NSWindow *)getRConsoleWindow{
return RConsoleWindow;
}

- (NSString*)getAppSupportPath
{

BOOL isDir;

if(!appSupportPath) {

NSString *tpath;
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);

if (![paths count]) {
SLog(@"RController.getAppSupportPath bailed due to no search paths found");
return nil;
}

// Use only the first path returned
tpath = [paths objectAtIndex:0];

// Append the application name
tpath = [tpath stringByAppendingPathComponent:
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"]];

// Check if user created the app support path already
[[NSFileManager defaultManager] fileExistsAtPath:tpath isDirectory:&isDir];

if(isDir) appSupportPath = [tpath retain];

}

// Check if app support path still exists
[[NSFileManager defaultManager] fileExistsAtPath:appSupportPath isDirectory:&isDir];
if(!isDir) {
if(appSupportPath) [appSupportPath release];
appSupportPath = nil;
}

return appSupportPath;

}

- (void)setStatusLineText:(NSString*)text
{

Expand Down Expand Up @@ -3837,6 +3886,14 @@ - (NSMenu *)textView:(NSTextView *)view menu:(NSMenu *)menu forEvent:(NSEvent *)

}

- (NSRange)textView:(NSTextView *)aTextView willChangeSelectionFromCharacterRange:(NSRange)oldSelectedCharRange toCharacterRange:(NSRange)newSelectedCharRange
{
// Check if snippet session is still valid
if (!newSelectedCharRange.length && [consoleTextView isSnippetMode]) {
[consoleTextView checkForCaretInsideSnippet];
}

return newSelectedCharRange;
}

@end
24 changes: 17 additions & 7 deletions RDocumentWinCtrl.m
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,7 @@ - (BOOL)textView:(NSTextView *)textViewSrc doCommandBySelector:(SEL)commandSelec
}


if([Preferences flagForKey:indentNewLineAfterSimpleClause withDefault:YES]) {
else if([Preferences flagForKey:indentNewLineAfterSimpleClause withDefault:YES]) {

// indent only next line after simple if,for,while,function commands without trailing {
// and if line has more opened ( than )
Expand All @@ -1084,18 +1084,18 @@ - (BOOL)textView:(NSTextView *)textViewSrc doCommandBySelector:(SEL)commandSelec
for(i=0; i<[line length]; i++) {
if(RPARSERCONTEXTFORPOSITION(textView, i) == pcExpression) {
c=CFStringGetCharacterAtIndex((CFStringRef)line,i);
switch(c){
case ')':closedP++;break;
case '(':openedP++;break;
}
if(c==')')
closedP++;
else if (c=='(')
openedP++;
}
}
if(openedP>closedP) {
[textView breakUndoCoalescing];
[textView insertText:indentString];
}
else if([line isMatchedByRegex:@"^\\s*(if|for|while)\\s*\\([^\\)]+?\\)\\s*$"]
|| [line isMatchedByRegex:@"(<-|=)\\s*function\\s*\\([^\\)]+?\\)\\s*$"]) {
else if([line isMatchedByRegex:@"^\\s*(if|for|while)\\s*\\(.+\\)\\s*$"]
|| [line isMatchedByRegex:@"(<-|=)\\s*function\\s*\\(.+\\)\\s*$"]) {
[textView breakUndoCoalescing];
[textView insertText:indentString];
lastLineWasCodeIndented = YES;
Expand Down Expand Up @@ -2036,4 +2036,14 @@ - (IBAction)checkRdDocument:(id)sender
[[self document] checkRdDocument];
}

- (NSRange)textView:(NSTextView *)aTextView willChangeSelectionFromCharacterRange:(NSRange)oldSelectedCharRange toCharacterRange:(NSRange)newSelectedCharRange
{
// Check if snippet session is still valid
if (!newSelectedCharRange.length && [textView isSnippetMode]) {
[textView checkForCaretInsideSnippet];
}

return newSelectedCharRange;
}

@end
Loading

0 comments on commit f4df599

Please sign in to comment.