Textmate: "Snippet Commands" and Placeholders

Draft

Textmate snippets are chunks of templated text, sprinkled with placeholders of the form
${1:default value}
When you invoke a snippet, it injects text into the current document, and it lets you tab through all of the placeholder fields and edit their values.

Sometimes you need to generate a lot of stubbed-out files in one go, e.g. when creating a Firefox extension. Snippets aren't so useful here, but Textmate commands are. At their simplest these are just scripts (pick a language; I like Python) which you invoke from within Textmate.

It sure would be nice to be able to use placeholders in those stubbed-out files, and to use Textmate as a sort of form editor. For example, the install.rdf file in a Firefox extension bundle has about eight fields which you might want to edit. You can generate default values for these fields when stubbing out the bundle, but several of them (e.g. the bundle ID, or your real-world name) might require customization.

There's a really simple way to create a Textmate command that lets you do placeholder editing on any file.

Open Textmate's bundle editor. Create a new bundle. Name it Fill in the blanks. In the command editor pane, set Save: to Current File. Put this text into the Command(s): text area:
cat "$TM_FILEPATH"
Set Input: to Selected Text or Document. Set Output: to Insert as Snippet.

Save your changes by selecting a different bundle in the bundle editor.

Now imagine you have written a script which generates a stub file. Wherever the file contains a value that you might want to change manually, put that value inside a placeholder, e.g.
${1:default value}
Run the script to generate your stub file. Open the stub in Textmate. Select all of the text, then invoke your "Fill in the blanks" bundle.

Voila! The contents of your stub file have not changed, but now you can tab from one placeholder field to the next, editing the values which your stub generator provided.

sigh

So many words for a simple procedure. I should put up a screencast on the Om OS X blog...