At first glance, Textmate can appear to be nothing more than a bog-standard code editor, lacking the more advanced features of an IDE. However, a quick look under the hood reveals how its relationship with UNIX command line tools has allowed it to become a supremely powerful editor.
There are a whole host of available commands and bundles, but what if you need to extend existing ones or create your own? I’ll cover some of the basics which will help you get started…
For this example, I’m going to perform a simple append to end-of-line (EOL) operation on selected text using sed.
Using Filter Through Command
Textmate’s ‘Filter Through Command…’ (under Text) is our first port of call. This will allow us to send input data from Textmate to a command and then return the command’s output to the current document.
We now end up with a comma at the end of each line of the selected text. The comma can of course be replaced with any string.
Textmate’s strength however lies in its bundles; essentially containers for re-usable blocks of code, templates and snippets. Rather than having to use the ‘Filter Through Command’ feature each time, we can replicate its behaviour in a stored command. We can also extend the original sed command by taking the content of the clipboard and appending this to the end of each selected line.
Under ‘Bundles > Bundle Editor > Show Bundle Editor’ we create a new command within the Text bundle.
if [[ $(pbpaste|wc -l) -eq 0 ]]
else sed "s/$/,/"
The second line of our new command checks whether we have more than one line of data in the clipboard, if so we’ll default to simply appending a comma to the end of the selected lines (line 5). If the clipboard contains no more than one line, its contents are assigned to $r and placed into the sed command.
The input is ‘Selected Text’ or ‘Nothing’ and the output is ‘Replace Selected Text’. The command can be run by going to ‘Bundles > Text > Name of command’. We can also bind this command to a keyboard shortcut if we so wish.
Adding simple UI elements
As a final example, we can extend this command further by introducing a dialog box which prompts for the input of the string to be appended, rather than relying on the clipboard.
Create a new command under the Text bundle with the same input and output settings as above, enter the following as the command:
r=$(CocoaDialog inputbox --title "String to be appended to EOL"
--informative-text "Enter string:"
--button1 "Okay" --button2 "Cancel")
[[ $(head -n1 <<<"$r") == "2" ]] && exit_discard
r=$(tail -n1 <<<"$r")
A CocoaDialog input box is called and we create two buttons, ‘Cancel’ and ‘Okay’, along with some assistive text. The dialog will return two lines of text:
- the button pressed (numeric)
- the string entered into the input
On line 6, we perform a check to see whether the ‘Cancel’ button was clicked (button number 2). If so we can exit, otherwise we retrieve the content of the second line returned by the dialog, assign this to $r and place it into our sed command.
Hopefully you’ll be inspired to modify and extend the examples for your own use. Please feel free to post these in the comments!