Make Smarter Divs with Snippets
April 7th, 2007
Earlier today James asked how I accomplished the auto-complete div’s with ending comments in my screencast post. This is how I do it.
First of all, this post is specific to TextMate. I’ve heard there are other editors out there that have similar functionality but I haven’t used them — all the same, these steps could easily be translated to work with those programs as well.
Create a New Snippet
Obviously the first step is to create a new snippet. This can be done by either going through the menus Bundles->Bundle Editor->Show Bundle Editor or using the key combination Control+Option+Command+B.
With the bundle editor now open you can create a new snippet. All new snippets will be saved into a bundle named after your username, the same one that you specified when you set up your computer.
The menu otions for new items in the snippet editor
At the bottom left of the editor window you’ll see a plus sign (+). Selecting that will give you a menu of options, choose the “New Snippet†option to create the new snippet. After selecting the “New Snippet†option you’ll be taken to the new snippet in the bundles list (the list of items directly above the button you just pressed) and the name of your new snippet will be highlighted and waiting for you to choose a name for this snippet — I went with div id (divid), the part in parenthesis being a reminder to how I invoke the snippet.
Coding the Snippet
Now we need to create the code that the snippet will execute when it’s invoked. Since we’re just dealing with creating a div it’s pretty straightforward.
In the bundle editor there is a large text input area taking up the majority of the right portion of the window. When a new snippet is created it is auto-populated with some instructions, delete those. In it’s place place the following code:
<div id="name"> </div> <!-- end #name -->
Adding the Tab Structure
In TextMate bundles/snippets you can create a specific tab order that will be followed when the snippet is executed in your document. The syntax for setting up this order is $n, where n is a number between 1 and 9 — I had asked about extending that beyond 9 but don’t know if it’s been done yet.
Knowing this we can revisit our snippet because we want to make sure we get to specify the name of the id in the div. Now we have:
<div id="$1">
$0
</div> <!-- end #$1 -->
By repeating the snippet variable $1 after “end #†in the snippet we will end up with the same text in both places. Placing the $0 ensures that the final tab for this snippet will place our cursor in between the opening and closing div tags with an indent.
Defining How to Call the Snippet
Now we’ve got our snippet set up we need to set the parameters on how we call it in our files. Below the large text area we placed our snippet code in are the options for activating it. For the activation I tend to favor “Tab Trigger†over “Key Equivalentâ€. Beside the activation popup menu, for this snippet at least, enter the text “divid†— or whatever you would feel comfortable typing to invoke this snippet into action.
For the scope selector add “text.html, source.phpâ€. This will enable the snippet for both HTML pages and PHP pages, as definied by the language selection when you’re working on your files.
Now if you create a new HTML or PHP document and type “divid†— or whatever you chose — followed by the tab key. You’ll see your snippet code appear and your cursor will be placed in between the quotation marks following id=. Type in whatever text you want and you’ll notice it is repeated, exactly, after the end # at the bottom of the snippet. Hitting the tab key again will place your cursor in between the opening and closing div tags, where we placed the $0 in the bundle editor. Your snippet is now complete.
Adding that Extra Polish
When I create snippets I like to have little hint or include optional code that I might not need when invoking a certain snippet. Extra options like tabindex in input tags or id’s in a tags. TextMate makes that easy.
Using syntax like this, ${1:text here}, you can specify any type of text or attributes in snippets. Snippets can also be nested which is how I achieve the optional attributes inside of tags. For example, lets say that we want to have an optional tabindex in our input tags. All we need to do is create a new snippet, the same as before, and use the following code in the snippet area:
<input type="${1:text}" name="${2:name}"${3: tabindex="${4:1}"} />
Now when I invoke the input snippet and tab through it I can change the type and name attributes as expected. When I get to the third tab the “ tabindex=”1″†will all be selected. If I want to have a tabindex I can simply hit tab again and the tabindex number will be highlighted, allowing me to change it. If I don’t want to include the tabindex attribute, when it’s highlighted I just need to delete it and move on.
Now it’s Your Turn
Add whatever snippets you want and set the tab triggers to whatever you feel comfortable with. Go nuts!
April 7th, 2007 at 1:57 pm
Awesome! thanks for the walk through, I hadn’t created any snippets, as the textmate docs are confusing and the snippet creator adds that default code which makes it even more confusing, but your tutorial really opened my eyes, sometimes we just need something explained more simply to get it.
Thanks Mike.
April 7th, 2007 at 3:23 pm
James, I’m so glad this helped you out. It took me a long time to figure out how snippets worked myself. Up until the last couple months I’ve barely been scratching the surface of what snippets and commands (custom and built-in) can do.
You’re very welcome.
April 20th, 2007 at 9:24 pm
[...] gives us a simple and straight forward look at making snippets in textmate, really opened my eyes, go give him a nod and a thank [...]
May 4th, 2007 at 9:33 am
Mike, This is an awesome little tutorial for TextMate snippets. I absolutely don’t want to take anything away from this post, however, just want to warn you and your readers about stupid IE, and the dumb things it does when comments are sometimes added to the end of certain types of divs. It turns out IE duplicates text unnecessarily when comments are added after certain types of divs. Here is my blog entry about it explaining it in further detail. I only mention this because it was such a huge pain in the butt to figure out what was going on in the first place.
http://www.patmullin.com/weblog/2006/08/25/another-ie-bug-unnecessarily-duplicating-text/
May 4th, 2007 at 10:27 am
Thanks for the heads up Patrick I haven’t heard of that before. I’m curious though, is it for a specific version of IE that this bug manifests itself? I don’t test in IE 5.5 any more and to my recollection I haven’t seen this bug appear in any of the pages I use the closing div comments.
Edit: After reading up on the issue at PIE it seems it affects IE 6. I’m wondering if this has been fixed or patched in any of the security patches/releases from Windows. Probably not but we can always hope