Skip to content
Browse files

Replace NSLog with NSAlerts for the cases that actually happen.

The NSLogs are still there, just disabled. Maybe add in runtime switch or
something.
  • Loading branch information...
1 parent 05a38f2 commit 715bdd2e7e2cce28ecb5e263486ceaa6af30485c @tom-seddon tom-seddon committed Aug 21, 2012
Showing with 170 additions and 75 deletions.
  1. +5 −5 XCFixin_UserScripts/UserScripts.org
  2. +165 −70 XCFixin_UserScripts/XCFixin_UserScripts.m
View
10 XCFixin_UserScripts/UserScripts.org
@@ -25,8 +25,11 @@ symlinks to them. Any it finds have their names added to the new
Select script from the menu, and the script runs. The current
selection is passed to the script as its standard input.
-The script's standard output replaces the current selection. Any
-standard error output is ignored.
+If the script's exit code is 0, the script's standard output replaces
+the current selection.
+
+If the script's exit code is anything else, an alert box is shown with
+the first 1K or so of the script's standard error output.
* Setting selection from a script
@@ -116,9 +119,6 @@ The current option names are:
- The key equivalent emacs notation 'thing' is lame and I need to find
some better way of doing it.
-- Error reporting is not great. If you run Console.app, you might find
- that the fixin has printed something useful there.
-
- If you run a script on text that includes the string
"%%%{PBXSelection}%%%", that string will disappear. (Presumably this
happened in Xcode3 too?)
View
235 XCFixin_UserScripts/XCFixin_UserScripts.m
@@ -8,6 +8,19 @@
#import "XCFixin.h"
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+// if true, extra verbose logging via NSLog.
+#define VERBOSE_LOGGING 0
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+// if true, an extra test menu item for whatever I'm testing at the
+// moment.
+#define TEST_UI 0
+
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@@ -19,6 +32,27 @@
return [NSString stringWithFormat:@"(%s *)%p: %@",class_getName([obj class]),obj,obj];
}
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+#if VERBOSE_LOGGING
+
+static void Log(NSString *fmt,...) NS_FORMAT_FUNCTION(1,2);
+
+static void Log(NSString *fmt,...)
+{
+ va_list v;
+ va_start(v,fmt);
+ NSLogv(fmt,v);
+ va_end(v);
+}
+
+#else//VERBOSE_LOGGING
+
+#define Log(...) ((void)0)
+
+#endif//VERBOSE_LOGGING
+
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@@ -28,7 +62,7 @@
if(!mainWindow)
{
if(log)
- NSLog(@"Can't find IDE text view - no main window.\n");
+ Log(@"Can't find IDE text view - no main window.\n");
return nil;
}
@@ -37,7 +71,7 @@
if(!DVTCompletingTextView)
{
if(log)
- NSLog(@"Can't find IDE text view - DVTCompletingTextView class unavailable.\n");
+ Log(@"Can't find IDE text view - DVTCompletingTextView class unavailable.\n");
return nil;
}
@@ -56,7 +90,7 @@
if(!textView)
{
if(log)
- NSLog(@"Can't find IDE text view - no DVTCompletingTextView in the responder chain.\n");
+ Log(@"Can't find IDE text view - no DVTCompletingTextView in the responder chain.\n");
return nil;
}
@@ -149,31 +183,28 @@ static NSRange NSMakeRangeFromStartAndEnd(NSUInteger start,NSUInteger end)
-(void)run
{
- NSLog(@"%s: path=%@\n",__FUNCTION__,fileName_);
+ Log(@"%s: path=%@\n",__FUNCTION__,fileName_);
NSTextView *textView=FindIDETextView(YES);
if(!textView)
{
- NSLog(@"Not running scripts - can't find IDE text view.\n");
+ Log(@"Not running scripts - can't find IDE text view.\n");
return;
}
NSTextStorage *textStorage=[textView textStorage];
if(!textStorage)
{
- NSLog(@"Not running scripts - IDE text view has no text storage.\n");
+ Log(@"Not running scripts - IDE text view has no text storage.\n");
return;
}
NSArray *inputRanges=[textView selectedRanges];
- NSLog(@"%s: %zu selected ranges:\n",__FUNCTION__,(size_t)[inputRanges count]);
+ Log(@"%s: %zu selected ranges:\n",__FUNCTION__,(size_t)[inputRanges count]);
for(NSUInteger i=0;i<[inputRanges count];++i)
- {
- NSRange range=[[inputRanges objectAtIndex:i] rangeValue];
- NSLog(@" %zu. %@\n",(size_t)i,NSStringFromRange(range));
- }
+ Log(@" %zu. %@\n",(size_t)i,NSStringFromRange([[inputRanges objectAtIndex:i] rangeValue]));
- NSLog(@"%s: select range: %@\n",__FUNCTION__,NSStringFromRange([textView selectedRange]));
+ Log(@"%s: select range: %@\n",__FUNCTION__,NSStringFromRange([textView selectedRange]));
NSString *inputStr=nil;
NSData *inputData=nil;
@@ -215,7 +246,7 @@ -(void)run
NSTask *task=[[[NSTask alloc] init] autorelease];
[task setLaunchPath:fileName_];
- NSLog(@"%s: [task launchPath] = %@\n",__FUNCTION__,[task launchPath]);
+ Log(@"%s: [task launchPath] = %@\n",__FUNCTION__,[task launchPath]);
NSPipe *stdinPipe=[NSPipe pipe];
NSPipe *stdoutPipe=[NSPipe pipe];
@@ -225,58 +256,97 @@ -(void)run
[task setStandardInput:stdinPipe];
[task setStandardError:stderrPipe];
- int exitCode=0;
- NSData *outputData=nil;
+ NSData *stdoutData=nil;
@try
{
- NSLog(@"%s: launching task...\n",__FUNCTION__);
+ Log(@"%s: launching task...\n",__FUNCTION__);
[task launch];
- NSLog(@"%s: task launched.\n",__FUNCTION__);
+ Log(@"%s: task launched.\n",__FUNCTION__);
if(inputData)
{
@try
{
- NSLog(@"%s: writing %zu bytes to task's stdin...\n",__FUNCTION__,(size_t)[inputData length]);
+ Log(@"%s: writing %zu bytes to task's stdin...\n",__FUNCTION__,(size_t)[inputData length]);
[[stdinPipe fileHandleForWriting] writeData:inputData];
- NSLog(@"%s: wrote to task's stdin.\n",__FUNCTION__);
+ Log(@"%s: wrote to task's stdin.\n",__FUNCTION__);
}
@catch(NSException *e)
{
// Maybe the task finished really quickly and it doesn't care what's in its stdin.
- NSLog(@"%s: ignoring error (%@) writing to task's stdin.\n",__FUNCTION__,e);
+ Log(@"%s: ignoring error (%@) writing to task's stdin.\n",__FUNCTION__,e);
}
}
[[stdinPipe fileHandleForWriting] closeFile];
@try
{
- NSLog(@"%s: reading from task's stdout...\n",__FUNCTION__);
- outputData=[[stdoutPipe fileHandleForReading] readDataToEndOfFile];
- NSLog(@"%s: read %zu bytes from task's stdout.\n",__FUNCTION__,(size_t)[outputData length]);
+ Log(@"%s: reading from task's stdout...\n",__FUNCTION__);
+ stdoutData=[[stdoutPipe fileHandleForReading] readDataToEndOfFile];
+ Log(@"%s: read %zu bytes from task's stdout.\n",__FUNCTION__,(size_t)[stdoutData length]);
}
@catch(NSException *e)
{
- NSLog(@"%s: error (%@) reading from task's stdout.\n",__FUNCTION__,e);
+ Log(@"%s: error (%@) reading from task's stdout.\n",__FUNCTION__,e);
}
-
- NSLog(@"%s: waiting for task exit...\n",__FUNCTION__);
+
+ Log(@"%s: waiting for task exit...\n",__FUNCTION__);
[task waitUntilExit];
- NSLog(@"%s: task exit.\n",__FUNCTION__);
+ Log(@"%s: task exit.\n",__FUNCTION__);
+
+ int exitCode=[task terminationStatus];
- exitCode=[task terminationStatus];
if(exitCode!=0)
- NSLog(@"Script failed - exit code %d.\n",exitCode);
+ {
+ NSData *stderrData=nil;
+
+ @try
+ {
+ Log(@"%s: reading from task's stderr...\n",__FUNCTION__);
+ stderrData=[[stderrPipe fileHandleForReading] readDataToEndOfFile];
+ Log(@"%s: read %zu bytes from task's stderr.\n",__FUNCTION__,(size_t)[stderrData length]);
+ }
+ @catch(NSException *e)
+ {
+ Log(@"%s: ignoring error (%@) reading from task's stderr.\n",__FUNCTION__,e);
+ stderrData=nil;
+ }
+
+ NSString *alertBody=@"";
+ if(stderrData)
+ {
+ alertBody=[[[NSString alloc] initWithData:stderrData
+ encoding:NSUTF8StringEncoding] autorelease];
+ }
+
+ NSUInteger maxLen=1000;
+ if([alertBody length]>maxLen)
+ alertBody=[[alertBody substringToIndex:maxLen] stringByAppendingString:[NSString stringWithFormat:@"\n\n(%u chars snipped)",(unsigned)([alertBody length]-maxLen)]];
+
+ if([alertBody length]==0)
+ alertBody=@"No error output was provided.";
+
+ [[NSAlert alertWithMessageText:[NSString stringWithFormat:@"Script failed - exit code %d",exitCode]
+ defaultButton:@"OK"
+ alternateButton:nil
+ otherButton:nil
+ informativeTextWithFormat:@"%@",alertBody] runModal];
+ return;
+ }
}
@catch(NSException *e)
{
if([[e name] isEqualToString:@"NSInvalidArgumentException"])
{
- exitCode=-1;
-
- NSLog(@"Script launch failed.\n");
+ [[NSAlert alertWithMessageText:@"Script launch failed"
+ defaultButton:@"OK"
+ alternateButton:nil
+ otherButton:nil
+ informativeTextWithFormat:@"Failed to launch \"%@\".\n\nReason: %@.",[task launchPath],[e reason]] runModal];
+
+ return;
}
else
@throw e;
@@ -285,14 +355,12 @@ -(void)run
{
}
- if(exitCode!=0)
- outputData=nil;
-
- if(outputData)
+ if(stdoutData)
{
NSString *selectionMarker=@"%%\x25{PBXSelection}%%%";
- NSString *outputStr=[[[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding] autorelease];
+ NSString *stdoutStr=[[[NSString alloc] initWithData:stdoutData
+ encoding:NSUTF8StringEncoding] autorelease];
NSRange a;//before 1st marker
NSRange b;//between 1st marker and 2nd marker (selection goes here)
@@ -303,49 +371,49 @@ -(void)run
case SRM_ALL:
{
a=NSMakeRange(0,0);
- b=NSMakeRange(0,[outputStr length]);
- c=NSMakeRange([outputStr length],0);
+ b=NSMakeRange(0,[stdoutStr length]);
+ c=NSMakeRange([stdoutStr length],0);
}
break;
case SRM_MARKER:
{
- NSRange r1=[outputStr rangeOfString:selectionMarker
+ NSRange r1=[stdoutStr rangeOfString:selectionMarker
options:NSLiteralSearch
range:NSMakeRangeFromStartAndEnd(0,
- [outputStr length])];
+ [stdoutStr length])];
if(r1.location==NSNotFound)
{
// no selection anywhere
a=NSMakeRangeFromStartAndEnd(0,
- [outputStr length]);
- c=b=NSMakeRange([outputStr length],
+ [stdoutStr length]);
+ c=b=NSMakeRange([stdoutStr length],
0);
}
else
{
a=NSMakeRangeFromStartAndEnd(0,
r1.location);
- NSRange r2=[outputStr rangeOfString:selectionMarker
+ NSRange r2=[stdoutStr rangeOfString:selectionMarker
options:NSLiteralSearch
range:NSMakeRangeFromStartAndEnd(r1.location+[selectionMarker length],
- [outputStr length])];
+ [stdoutStr length])];
if(r2.location==NSNotFound)
{
b=NSMakeRange(r1.location+[selectionMarker length],
0);
c=NSMakeRangeFromStartAndEnd(r1.location+[selectionMarker length],
- [outputStr length]);
+ [stdoutStr length]);
}
else
{
b=NSMakeRangeFromStartAndEnd(r1.location+[selectionMarker length],
r2.location);
c=NSMakeRangeFromStartAndEnd(r2.location+[selectionMarker length],
- [outputStr length]);
+ [stdoutStr length]);
}
}
}
@@ -354,25 +422,25 @@ -(void)run
default:
case SRM_NONE:
{
- a=NSMakeRange(0,[outputStr length]);
- b=NSMakeRange([outputStr length],0);
- c=NSMakeRange([outputStr length],0);
+ a=NSMakeRange(0,[stdoutStr length]);
+ b=NSMakeRange([stdoutStr length],0);
+ c=NSMakeRange([stdoutStr length],0);
}
break;
}
- outputStr=[[[outputStr substringWithRange:a] stringByAppendingString:[outputStr substringWithRange:b]] stringByAppendingString:[outputStr substringWithRange:c]];
+ stdoutStr=[[[stdoutStr substringWithRange:a] stringByAppendingString:[stdoutStr substringWithRange:b]] stringByAppendingString:[stdoutStr substringWithRange:c]];
[textView breakUndoCoalescing];
// don't insert text if the two strings are actually the same.
//
// this is a fix for scripts that just pop a %%%{PBXSeleciton}%%%
// into their input to put the cursor somewhere.
- if(![outputStr isEqualToString:inputStr])
+ if(![stdoutStr isEqualToString:inputStr])
{
- [textView insertText:outputStr
+ [textView insertText:stdoutStr
replacementRange:inputRange];
}
@@ -386,7 +454,7 @@ -(void)run
-(void)dealloc
{
- NSLog(@"%s: (%s *)%p: %@\n",__FUNCTION__,class_getName([self class]),self,fileName_);
+ Log(@"%s: (%s *)%p: %@\n",__FUNCTION__,class_getName([self class]),self,fileName_);
[fileName_ release];
fileName_=nil;
@@ -404,6 +472,9 @@ -(void)dealloc
@interface XCFixin_ScriptsHandler:NSObject
{
+#if TEST_UI
+ NSMenuItem *testUIMenuItem_;
+#endif//TEST_UI
NSMenuItem *refreshMenuItem_;
}
@end
@@ -437,14 +508,14 @@ -(void)refreshScriptsMenu
NSMenu *mainMenu=[NSApp mainMenu];
if(!mainMenu)
{
- NSLog(@"%s: main menu not found.\n",__FUNCTION__);
+ Log(@"%s: main menu not found.\n",__FUNCTION__);
return;
}
int scriptsMenuIndex=[mainMenu indexOfItemWithTitle:@"Scripts"];
if(scriptsMenuIndex<0)
{
- NSLog(@"%s: Scripts menu not found.\n",__FUNCTION__);
+ Log(@"%s: Scripts menu not found.\n",__FUNCTION__);
return;
}
@@ -454,18 +525,18 @@ -(void)refreshScriptsMenu
[scriptsMenu removeAllItems];
NSString *appSupportFolderName=SystemFolderName(kApplicationSupportFolderType,kUserDomain);
- NSLog(@"appSupportFolderName=%@\n",appSupportFolderName);
+ Log(@"appSupportFolderName=%@\n",appSupportFolderName);
NSString *scriptsFolderName=[NSString pathWithComponents:[NSArray arrayWithObjects:appSupportFolderName,@"Developer/Shared/Xcode/Scripts",nil]];
- NSLog(@"scriptsFolderName=%@\n",scriptsFolderName);
+ Log(@"scriptsFolderName=%@\n",scriptsFolderName);
NSString *scriptsPListName=[NSString pathWithComponents:[NSArray arrayWithObjects:scriptsFolderName,@"Scripts.xml",nil]];
- NSLog(@"scriptsPListName=%@\n",scriptsPListName);
+ Log(@"scriptsPListName=%@\n",scriptsPListName);
NSDictionary *scriptsProperties=[NSDictionary dictionaryWithContentsOfFile:scriptsPListName];
if(!scriptsProperties)
- NSLog(@"%s: No scripts plist loaded.\n",__FUNCTION__);
+ Log(@"%s: No scripts plist loaded.\n",__FUNCTION__);
else
- NSLog(@"%s: Scripts plist: %@\n",__FUNCTION__,scriptsProperties);
+ Log(@"%s: Scripts plist: %@\n",__FUNCTION__,scriptsProperties);
NSArray *scriptsFolderContents=[[NSFileManager defaultManager] contentsOfDirectoryAtPath:scriptsFolderName
error:nil];
@@ -483,19 +554,19 @@ -(void)refreshScriptsMenu
struct stat st;
if(stat([path UTF8String],&st)!=0)
{
- NSLog(@"%@: not a script (stat failed)\n",path);
+ Log(@"%@: not a script (stat failed)\n",path);
continue;
}
if(!(st.st_mode&(S_IFLNK|S_IFREG)))
{
- NSLog(@"%@: not a script (not symlink or regular file)\n",path);
+ Log(@"%@: not a script (not symlink or regular file)\n",path);
continue;
}
if(![defaultManager isExecutableFileAtPath:path])
{
- NSLog(@"%@: not a script (not executable)\n",path);
+ Log(@"%@: not a script (not executable)\n",path);
continue;
}
@@ -509,7 +580,7 @@ -(void)refreshScriptsMenu
NSString *name=[scripts objectAtIndex:scriptIdx];
NSString *path=[NSString pathWithComponents:[NSArray arrayWithObjects:scriptsFolderName,name,nil]];
- NSLog(@"Creating XCFixin_Script for %@.\n",path);
+ Log(@"Creating XCFixin_Script for %@.\n",path);
XCFixin_Script *script=[[[XCFixin_Script alloc] initWithFileName:path] autorelease];
NSMenuItem *scriptMenuItem=[[[NSMenuItem alloc] initWithTitle:name
@@ -523,7 +594,7 @@ -(void)refreshScriptsMenu
if(![scriptProperties isKindOfClass:[NSDictionary class]])
scriptProperties=nil;
- NSLog(@" Script properties: %@\n",scriptProperties);
+ Log(@" Script properties: %@\n",scriptProperties);
NSString *keyEquivalent=[scriptProperties objectForKey:@"keyEquivalent"];
if(keyEquivalent&&[keyEquivalent length]>0)
@@ -604,6 +675,13 @@ -(void)refreshScriptsMenu
[scriptsMenu addItem:[NSMenuItem separatorItem]];
}
+#if TEST_UI
+ testUIMenuItem_=[scriptsMenu addItemWithTitle:@"Test Item"
+ action:@selector(testUIAction:)
+ keyEquivalent:@""];
+ [testUIMenuItem_ setTarget:self];
+#endif//TEST_UI
+
refreshMenuItem_=[scriptsMenu addItemWithTitle:@"Refresh"
action:@selector(refreshScriptsMenuAction:)
keyEquivalent:@""];
@@ -621,6 +699,22 @@ -(IBAction)runScriptAction:(id)arg
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
+#if TEST_UI
+-(IBAction)testUIAction:(id)arg
+{
+ NSAlert *alert=[NSAlert alertWithMessageText:@"UI Test Text"
+ defaultButton:@"OK"
+ alternateButton:nil
+ otherButton:nil
+ informativeTextWithFormat:@"UI Test Body (%p)",self];
+ int x=[alert runModal];
+ Log(@"%s: result: %d\n",__FUNCTION__,x);
+}
+#endif//TEST_UI
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
-(IBAction)refreshScriptsMenuAction:(id)arg
{
[self refreshScriptsMenu];
@@ -634,7 +728,7 @@ -(BOOL)install
NSMenu *mainMenu=[NSApp mainMenu];
if(!mainMenu)
{
- NSLog(@"%s: main menu not found!\n",__FUNCTION__);
+ Log(@"%s: main menu not found!\n",__FUNCTION__);
return NO;
}
@@ -693,7 +787,7 @@ static BOOL GetClasses(const char *name0,...)
*c=objc_getClass(name);
if(!*c)
{
- NSLog(@"FATAL: class %s not found.\n",name);
+ Log(@"FATAL: class %s not found.\n",name);
return NO;
}
}
@@ -723,11 +817,12 @@ + (void)pluginDidLoad: (NSBundle *)plugin
XCFixin_ScriptsHandler *handler=[[XCFixin_ScriptsHandler alloc] init];
if(!handler)
- NSLog(@"%s: handler init failed.\n",__FUNCTION__);
+ Log(@"%s: handler init failed.\n",__FUNCTION__);
else
{
BOOL goodInstall=[handler install];
- NSLog(@"%s: handler installed: %s\n",__FUNCTION__,goodInstall?"YES":"NO");
+ (void)goodInstall;
+ Log(@"%s: handler installed: %s\n",__FUNCTION__,goodInstall?"YES":"NO");
}
XCFixinPostflight();

0 comments on commit 715bdd2

Please sign in to comment.
Something went wrong with that request. Please try again.