Uli's Web Site
[ Zathras.de - Uli's Web Site ]
Other Sites: Stories
Pix
Abi 2000
Stargate: Resurgence
Lost? Site Map!
 
 
     home | articles | moose | programming | articles >> blog

 Blog
 
 Blog Topics
 
 Archive
 

15 Most Recent [RSS]

 Uli's source code is on Github!
2010-03-05 @986
 
 Downtime on Friday
2010-03-04 @025
 
 Hacking the Press - A point for usability in press kits
2010-02-18 @404
 
 So. Git.
2010-02-15 @498
 
 Helpful Xcode User Scripts
2010-02-14 @485
 
 CocoaHeads München: Xcode Tiefergelegt Folien
2010-02-10 @995
 
 Debugging Assembler on Mac OS X
2010-02-07 @600
 
 The iPad
2010-01-29 @417
 
 Double click is a shortcut
2010-01-16 @621
 
 Removing transparency from NSImage
2010-01-16 @581
 
 Garbage collection, work of the devil?
2009-12-20 @881
 
 Let's talk about Coding Style
2009-12-15 @459
 
 The iPhone Reality Show
2009-12-13 @589
 
 The Sinus Curve of Life
2009-11-26 @430
 
 AppleScripting Cocoa a little
2009-11-26 @003
 

More...

Helpful Xcode User Scripts

One of the more annoying tasks when writing Cocoa code is defining symbolic constants for all those keys when doing key-value coding. I've already posted my trick for getting auto-validated key-value-observing constants, but there are constants that aren't accessors. Does lazy Uli have a trick for these as well?

[Xcode's User Script editing window and the User Scripts menu]

Yes! Xcode has a really neat feature called "User scripts". It takes the form of a little black scripture roll in the menu bar. If you open it, there is an "Edit User Scripts..." menu item. Choose it, and it shows a list of the scripts that come with Xcode, plus an edit field on the right where you can edit the current script.

The neat thing here is: These are just unix shell scripts. Notice the shebang at the top? That means you can specify every script interpreter, and you aren't stuck with those terrible search-and-replace-with-side-effects-languages like bash or zsh. You could use Perl, or Ruby, or ... heck, why not use PHP? Let's do that, let's solve our problem with constants in PHP. Click the "+" button and add a new script, change its name and give it a nice keyboard shortcut (I chose Cmd-Ctrl-K, K as in Konstant - C was already taken). Then paste in the folowing script:

#!/usr/bin/php
<?php
$fd = fopen( "php://stdin", "r" );
$the_ident = fgets($fd);
echo "NSString*\t$the_ident = @\"$the_ident\";\n";
?>
Make sure the "Input" popup is set to "Selection", and the "Output" is set to "Place on Clipboard". Now, whenever you need a new string constant as a dictionary key in Cocoa, you can just write the constant's symbolic name
MyAppShouldOpenUntitledWindowPrefsKey
select it by double-clicking, hit Cmd-Ctrl-K, and then paste a finished declaration for it at the top of your source file:
NSString*   MyShouldOpenUntitledDocPrefsKey = @"MyShouldOpenUntitledDocPrefsKey";

Of course that's just one of the neat macro things you can do. Since most scripting languages these days support regular expressions, you can do things like turn detect string literals on a line and generate a .strings file entry from it (or vice versa), put brackets and angle brackets around the selected expression (set the output to also be "Selection"), and do a multitude of other handy things.

Okay, you don't really have to write code for putting brackets around certain expressions. Just look in the Edit -> Insert Text Macro -> C and Edit -> Insert Text Macro -> Objective-C submenus. You can use the Preferences window's Key Bindings page to specify keyboard shortcuts (I chose Cmd-Ctrl-9, the key where my UK keyboard has the opening bracket, for Parenthesize Expression and Cmd-Ctrl-[ for Bracket Expression).

Of course, you can also put scripts in this menu that talk to the command line tool for your version control system of choice. For example, if you're as addicted to GUI clients as I am, you'll want the following script:

#!/bin/bash

# Find current document's repository root and cd to it:
MYPATH=`osascript -e "tell application \"Xcode\" to (path of document 1)"`
while [[ -n "$MYPATH" && "$MYPATH" != "/" && ! -e "$MYPATH/.git" ]]
do
	MYPATH=`dirname "$MYPATH"`
done
cd "$MYPATH"

if [[ -n "$MYPATH" && "$MYPATH" != "/" ]]
then
	# Now do our magic!
	open -a GitX.app "$MYPATH"
fi

This opens the current Xcode file's Git repository in GitX so you can get yourself some hot merging and staging goodness. You can write a lot of code following this principle. For example, here is a script that does a git push on the project folder in a Terminal window, so you can actually type something into the password prompt:

#!/bin/bash

# Find current document's repository root and cd to it:
MYPATH=`osascript -e 'tell application "Xcode" to (path of document 1)'`
while [[ -n "$MYPATH" && "$MYPATH" != "/" && ! -e "$MYPATH/.git" ]]
do
	MYPATH=`dirname "$MYPATH"`
done
cd "$MYPATH"

if [[ -n "$MYPATH" && "$MYPATH" != "/" ]]
then
	# Now do our magic!
	IGNORE=`osascript -e "tell application \"Terminal\" to do script \"cd \" & quote & \"${MYPATH}\" & quote & \"; git push\""`
fi

Any other suggestions for other useful scripts for coding that one may want to put in this menu?

Reader Comments: (RSS Feed)
Dirk writes:
You might also like this one that I originally developed for iPhone development but also work on Mac code. It handles all the property stuff which is quite redundant in Objective-C: http://github.com/holtwick/xobjc
Andy Lee writes:
Here's a script idea I *think* should be doable but have been too lazy to try as yet: http://www.notesfromandy.com/2009/09/04/app-idea-extract-method-name-from-selected-text/
Julián Romero writes:
I use this one a lot. It adds a log of the selected variable: #! /bin/sh echo -n 'NSLog(@"%%%{PBXSelectedText}%%% => %@", %%%{PBXSelectedText}%%%%%%{PBXSelection}%%%);'
Ross Carter writes:
I'm not a good typist, so I use user scripts to type things for me, like a divider: #! /usr/bin/perl -w # -- PB User Script Info -- # %%%{PBXName=NSLog}%%% # %%%{PBXOutput=ReplaceSelection}%%% use strict; my $object = <<'SELECTION'; %%%{PBXSelectedText}%%% SELECTION chomp $object; print "//------------------------------------------------------- // xxxxxxxxxxxx //------------------------------------------------------- "; exit 0; or logging the method selector: (same as above but with:) print "NSLog(@\"%s\", _cmd);"; or localized strings: print "NSLocalizedStringFromTable(@\"%%%{PBXSelectedText}%%%\", @\"TABLEGOESHERE\", @\"%%%{PBXSelectedText}%%%\")"; NSStringFrom (type re or ra to get autocompletion for Rect, Range, etc): print "NSStringFrom"; and various pragmas, to promote consistency in how I organize code within a file: print "#pragma mark -\n"; print "#pragma mark IBActions\n";
Uli Kusterer replies:
Dirk, that's a neat script, though it's unfortunate that it needs to mark up the ivars in a way that requires changes to the actual code. I wouldn't be able to use this on many open source projects unless I can convince everyone to use it.
Uli Kusterer replies:
Andy, that sounds like a neat idea, and Peter's command line tool looks like a good start. Would love to see what becomes of this. Along similar lines, I'd love a script that auto-adds method declarations to the @interface for a method I just declared in @interface. I.e. I write the implementation, leave the cursor somewhere nearby, start the script, and it finds the method signature, opens the header, finds the @implementation in there and inserts the prototype there. It'd be even cooler to be able to do that from a call: Double-click opening bracket and it'll analyze the types of the parameters and generate the right signature, then create an empty implementation and interface declaration. But I guess for that one might need Clang to actually parse the code.
Uli Kusterer replies:
Julian, that one is neat. Short, sweet, and will log any object type. Would be interesting to see if one could do a localized search and try to determine the type of that variable, then also make it work for ints etc.
Comment on this article:
Name:
E-Mail: (not shown, hashed for Gravatar)
Web Site URL: (optional)
Comment: (plain text only)
Please Enter the following word:
Or E-Mail Uli privately.

 
Created: 2009-11-01 @735 Last change: 2010-03-12 @856 | Home | Admin | Edit
© Copyright 2003-2010 by M. Uli Kusterer, all rights reserved.