TextMate Macro
You know, I thought I’d mentioned TextMate before, but apparently not. TextMate is the text editor for Mac OS X as far as I am concerned, and has taken over IDE duties from … well, everything else, including XCode whenever I’m not actively tinkering with Core Data Models or something.
There are a bunch of reasons, and I’m not going to go off on a rant about TextMate’s awesomeness, but I will quickly draw attention to three features: mate <folder>, TextMate Dialogs and the scriptable (in the language of your choice) bundle system (documentation and screencast).
One thing I’ve been doing quite a bit recently is writing Python code that works with Apple’s Cocoa framework. This tends to require a lot of looking up Cocoa documentation and then translating Objective-C function prototypes into Python (because Cocoa’s API relies heavily on you implementing delegates and other callback-style methods that conform to their protocol).
Here’s my first stab at a TextMate macro to do this for you:
#!/usr/local/bin/python -S
from os import environ as env
source = env['TM_SELECTED_TEXT']
if ':' in source:
parts = source.split(':')
result = []
vars = ['self']
first = True
for part in parts:
try:
before, part = part.rsplit(' ',1)
vars.append(before.rsplit(')',1)[1].strip())
result.append(part.strip()+'_')
except:
part = part.rsplit(')',1)[1]
if first:
result.append(part.strip()+'_')
else:
vars.append(part.strip())
first = False
else:
result.append(part.lsplit(')',1)[1].strip())
result = 'def %s(%s):\n' % ("".join(result), ", ".join(vars))
print result
To install it, open the TextMate Bundle Editor, find the Python section, and add a new Command. Give it a suitable name, and paste the code above into the “Command(s)” text area. The other settings I use are:
Save: Nothing
Input: Selected Text or Line
Output: Replace Selected Text
To test it, simply cut and paste a method prototype from the Cocoa documentation, eg:
- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor
Make sure this text is selected, activate your new macro, and you should get:
def control_textShouldBeginEditing_(self, control, fieldEditor):
You’ll notice that it assumes you’re defining a method inside a class and need a self parameter. TextMate doesn’t seem to define a “scope” for Python classes that would allow me to add or omit this automatically (without parsing the document myself). It’d be nice to add other features to this as well; say, detecting Objective-C function calls and changing those into matching Python calls. But for now, this is still a nifty timesaver.