| Line 30... |
Line 30... |
| 30 |
*
|
30 |
*
|
| 31 |
* Created by Hans-J. Bibiko on 02/01/2012.
|
31 |
* Created by Hans-J. Bibiko on 02/01/2012.
|
| 32 |
*
|
32 |
*
|
| 33 |
*/
|
33 |
*/
|
| 34 |
|
34 |
|
| - |
|
35 |
#import "RGUI.h"
|
| 35 |
#import "NSString_RAdditions.h"
|
36 |
#import "NSString_RAdditions.h"
|
| 36 |
#import "RegexKitLite.h"
|
37 |
#import "RegexKitLite.h"
|
| 37 |
#import "PreferenceKeys.h"
|
38 |
#import "PreferenceKeys.h"
|
| 38 |
|
39 |
|
| 39 |
@implementation NSString (NSString_RAdditions)
|
40 |
@implementation NSString (NSString_RAdditions)
|
| Line 127... |
Line 128... |
| 127 |
|
128 |
|
| 128 |
NSTask *bashTask = [[NSTask alloc] init];
|
129 |
NSTask *bashTask = [[NSTask alloc] init];
|
| 129 |
[bashTask setLaunchPath:@"/bin/bash"];
|
130 |
[bashTask setLaunchPath:@"/bin/bash"];
|
| 130 |
|
131 |
|
| 131 |
NSMutableDictionary *theEnv = [NSMutableDictionary dictionary];
|
132 |
NSMutableDictionary *theEnv = [NSMutableDictionary dictionary];
|
| 132 |
if(shellEnvironment)
|
133 |
// set current environment variables to shell
|
| 133 |
[theEnv setDictionary:shellEnvironment];
|
134 |
[theEnv setDictionary:[[NSProcessInfo processInfo] environment]];
|
| 134 |
else
|
135 |
// overwrite or set additional variables
|
| 135 |
[theEnv setDictionary:[[NSProcessInfo processInfo] environment]];
|
136 |
if(shellEnvironment) [theEnv addEntriesFromDictionary:shellEnvironment];
|
| 136 |
|
137 |
|
| - |
|
138 |
// set exit codes
|
| 137 |
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionNone] forKey:kBASHTaskShellVariableExitNone];
|
139 |
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionNone] forKey:kBASHTaskShellVariableExitNone];
|
| 138 |
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionReplaceSection] forKey:kBASHTaskShellVariableExitReplaceSelection];
|
140 |
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionReplaceSection] forKey:kBASHTaskShellVariableExitReplaceSelection];
|
| 139 |
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionReplaceContent] forKey:kBASHTaskShellVariableExitReplaceContent];
|
141 |
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionReplaceContent] forKey:kBASHTaskShellVariableExitReplaceContent];
|
| 140 |
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionInsertAsText] forKey:kBASHTaskShellVariableExitInsertAsText];
|
142 |
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionInsertAsText] forKey:kBASHTaskShellVariableExitInsertAsText];
|
| 141 |
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionInsertAsSnippet] forKey:kBASHTaskShellVariableExitInsertAsSnippet];
|
143 |
[theEnv setObject:[NSNumber numberWithInteger:kBASHTaskRedirectActionInsertAsSnippet] forKey:kBASHTaskShellVariableExitInsertAsSnippet];
|
| Line 167... |
Line 169... |
| 167 |
}
|
169 |
}
|
| 168 |
[bashTask launch];
|
170 |
[bashTask launch];
|
| 169 |
|
171 |
|
| 170 |
NSInteger pid = -1;
|
172 |
NSInteger pid = -1;
|
| 171 |
pid = [bashTask processIdentifier];
|
173 |
pid = [bashTask processIdentifier];
|
| 172 |
|
174 |
|
| 173 |
if(!nonWaitingMode) {
|
175 |
if(!nonWaitingMode) {
|
| 174 |
// Listen to ⌘. to terminate
|
176 |
// Listen to ⌘. to terminate
|
| 175 |
while(1) {
|
177 |
while(1) {
|
| 176 |
if(![bashTask isRunning] || [bashTask processIdentifier] == 0) break;
|
178 |
if(![bashTask isRunning] || [bashTask processIdentifier] == 0) break;
|
| - |
|
179 |
usleep(1000);
|
| 177 |
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
180 |
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
| 178 |
untilDate:[NSDate distantPast]
|
181 |
untilDate:[NSDate distantPast]
|
| 179 |
inMode:NSDefaultRunLoopMode
|
182 |
inMode:NSDefaultRunLoopMode
|
| 180 |
dequeue:YES];
|
183 |
dequeue:YES];
|
| 181 |
usleep(10000);
|
- |
|
| 182 |
if(!event) continue;
|
184 |
if(!event) continue;
|
| 183 |
if ([event type] == NSKeyDown) {
|
185 |
if ([event type] == NSKeyDown) {
|
| 184 |
unichar key = [[event characters] length] == 1 ? [[event characters] characterAtIndex:0] : 0;
|
186 |
unichar key = [[event characters] length] == 1 ? [[event characters] characterAtIndex:0] : 0;
|
| 185 |
if (([event modifierFlags] & NSCommandKeyMask) && key == '.') {
|
187 |
if (([event modifierFlags] & NSCommandKeyMask) && key == '.') {
|
| 186 |
[bashTask terminate];
|
188 |
[bashTask terminate];
|
| Line 190... |
Line 192... |
| 190 |
[NSApp sendEvent:event];
|
192 |
[NSApp sendEvent:event];
|
| 191 |
} else {
|
193 |
} else {
|
| 192 |
[NSApp sendEvent:event];
|
194 |
[NSApp sendEvent:event];
|
| 193 |
}
|
195 |
}
|
| 194 |
}
|
196 |
}
|
| 195 |
|
- |
|
| 196 |
[bashTask waitUntilExit];
|
197 |
[bashTask waitUntilExit];
|
| 197 |
} else {
|
198 |
} else {
|
| 198 |
if (bashTask) [bashTask release];
|
199 |
if (bashTask) [bashTask release];
|
| 199 |
[fm removeItemAtPath:scriptFilePath error:nil];
|
200 |
[fm removeItemAtPath:scriptFilePath error:nil];
|
| 200 |
[fm removeItemAtPath:stdoutFilePath error:nil];
|
201 |
[fm removeItemAtPath:stdoutFilePath error:nil];
|
| Line 207... |
Line 208... |
| 207 |
// If return from bash re-activate R.app
|
208 |
// If return from bash re-activate R.app
|
| 208 |
[NSApp activateIgnoringOtherApps:YES];
|
209 |
[NSApp activateIgnoringOtherApps:YES];
|
| 209 |
|
210 |
|
| 210 |
NSInteger status = [bashTask terminationStatus];
|
211 |
NSInteger status = [bashTask terminationStatus];
|
| 211 |
NSData *errdata = nil;
|
212 |
NSData *errdata = nil;
|
| - |
|
213 |
if(stderr_file) errdata = [stderr_file readDataToEndOfFile];
|
| - |
|
214 |
|
| - |
|
215 |
if(status == 9 || userTerminated) {
|
| - |
|
216 |
if(theError != NULL)
|
| - |
|
217 |
*theError = [[[NSError alloc] initWithDomain:NSPOSIXErrorDomain
|
| - |
|
218 |
code:status
|
| - |
|
219 |
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
|
| - |
|
220 |
NLS(@"User Termination"),
|
| - |
|
221 |
NSLocalizedDescriptionKey,
|
| - |
|
222 |
@"",
|
| - |
|
223 |
@"terminated",
|
| - |
|
224 |
nil]] autorelease];
|
| - |
|
225 |
return @"";
|
| 212 |
|
226 |
}
|
| - |
|
227 |
|
| - |
|
228 |
|
| 213 |
// Check STDERR
|
229 |
// Check STDERR
|
| 214 |
if(theError != NULL && [errdata length] && (status < kBASHTaskRedirectActionNone || status > kBASHTaskRedirectActionLastCode)) {
|
230 |
if(theError != NULL && errdata && [errdata length] && (status < kBASHTaskRedirectActionNone || status > kBASHTaskRedirectActionLastCode)) {
|
| 215 |
[fm removeItemAtPath:stdoutFilePath error:nil];
|
231 |
[fm removeItemAtPath:stdoutFilePath error:nil];
|
| 216 |
if(stderr_file) [stderr_file readDataToEndOfFile];
|
232 |
if(theError != NULL && errdata && [errdata length]) {
|
| 217 |
if(status == 9 || userTerminated) return @"";
|
- |
|
| 218 |
if(theError != NULL) {
|
- |
|
| 219 |
NSMutableString *errMessage = [[[NSMutableString alloc] initWithData:errdata encoding:NSUTF8StringEncoding] autorelease];
|
233 |
NSMutableString *errMessage = [[[NSMutableString alloc] initWithData:errdata encoding:NSUTF8StringEncoding] autorelease];
|
| 220 |
[errMessage replaceOccurrencesOfString:[NSString stringWithFormat:@"%@: ", scriptFilePath] withString:@"" options:NSLiteralSearch range:NSMakeRange(0, [errMessage length])];
|
234 |
[errMessage replaceOccurrencesOfString:[NSString stringWithFormat:@"%@: ", scriptFilePath] withString:@"" options:NSLiteralSearch range:NSMakeRange(0, [errMessage length])];
|
| 221 |
*theError = [[[NSError alloc] initWithDomain:NSPOSIXErrorDomain
|
235 |
*theError = [[[NSError alloc] initWithDomain:NSPOSIXErrorDomain
|
| 222 |
code:status
|
236 |
code:status
|
| 223 |
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
|
237 |
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
|