Category Archives: TextMate

CSS3 TextMate Bundle

I’ve combined the previous CSS3 TextMate Snippets into a bundle, which was a lot easier to do than I thought it would be. I’ll detail how to make your own in a future post.

The bundle I’ve created plays nicely with existing CSS snippets that are bundled with TextMate. I’ve included:

  • background horizontal linear gradient
  • background vertical linear gradient
  • border-radius bottom left
  • border-radius bottom right
  • border-radius top left
  • border-radius top right
  • border-radius
  • box-shadow

You can download the bundle below.

Download CSS3.tmbundle.

Let me know how you get on, and if there any other properties you’d like me to add.

CSS3 Snippets in TextMate – Linear Gradients

Gradients are great. Linear gradients are super-great, because (as long as you don’t want funky angles) they work on pretty much all current browsers if you can remember the syntax. I can’t remember the syntax, but with a little home-schooling TextMate can…

Create these 2 snippets within TextMate’s CSS scope:

Name:
background: vertical linear gradient
Tab trigger:
background
Scope Selector:
source.css
Snippet:
background: ${1:top-color};
background: -webkit-gradient(linear, left top, left bottom, from(${1:top-color}), to(${2:bottom-color}));
background: -moz-linear-gradient(top, ${1:top-color}, ${2:bottom-color});
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=${1:top-color}, endColorstr=${2:bottom-color});
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=${1:top-color}, endColorstr=${2:bottom-color})";
$3

Name:
background: horizontal linear gradient
Tab trigger:
background
Scope Selector:
source.css
Snippet:
background: ${1:left-color};
background: -webkit-gradient(linear, left top, right top, from(${1:left-color}), to(${2:right-color}));
background: -moz-linear-gradient(left top, ${1:left-color}, ${2:right-color});
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=${1:left-color}, endColorstr=${2:right-color}, GradientType=1);
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=${1:left-color}, endColorstr=${2:right-color}, GradientType=1)";
$3

Now, typing background within a CSS context and pressing tab should show something like this:

background.jpg

Choosing one of the two new options at the bottom will give you all the code you need for most browsers to show a horizontal or vertical linear gradient. The first colour you enter (either the top-most or left-most colour) will become the default background for browsers that don’t support gradients, which is hopefully usually what you want. In case you were wondering, -ms-filter is specifically for IE8 (in IE8-mode) which requires quotes around the contents.

CSS3 Snippets in TextMate – border-radius

I don’t have the best memory in the world. I am incapable of remembering the exact syntax for most CSS properties, let alone the vendor specific versions of them. To that end I have started creating TextMate snippets to help me out.

text-shadow comes by default, but border-radius does not.

Create these 5 snippets within CSS:

Name:
border-radius
Tab trigger:
border-radius
Snippet:
border-radius: ${1:radius};
-moz-border-radius: ${1:radius};
-webkit-border-radius: ${1:radius};
$0

Name:
border-top-left-radius
Tab trigger:
border-radius
Snippet:
border-top-left-radius: ${1:radius};
-moz-border-radius-topleft: ${1:radius};
-webkit-border-top-left-radius: ${1:radius};
$0

Name:
border-top-right-radius
Tab trigger:
border-radius
Snippet:
border-top-right-radius: ${1:radius};
-moz-border-radius-topright: ${1:radius};
-webkit-border-top-right-radius: ${1:radius};
$0

Name:
border-bottom-left-radius
Tab trigger:
border-radius
Snippet:
${1:radius};
-moz-border-radius-bottomleft: ${1:radius};
-webkit-border-bottom-left-radius: ${1:radius};
$0

Name:
border-bottom-right-radius
Tab trigger:
border-radius
Snippet:
${1:radius};
-moz-border-radius-bottomright: ${1:radius};
-webkit-border-bottom-right-radius: ${1:radius};
$0

Now, anywhere that is a CSS context (inside a CSS file or inside style tags in an HTML file) type border-radius and press tab. TextMate asks which of our five snippets you want. Choose the appropriate one by typing the number alongside it, and the code appears. Now type the radius you want (don’t forget, you can enter two values if you want the equivalent of an elliptical radius) and it will automatically appear for all vendor-specific code. Finally, press tab again and your cursor jumps outside of the code we just typed.

I’ll provide more of these as I make them.

Using previously highlighted text in TextMate snippets

In a previous (and very verbose) post on TextMate snippets, I showed a snippet to easily and simply use a tab trigger to insert a try... catch statement. If you missed it feel free to catch up here. The idea was that you type in try, press tab and TextMate spits out:

try {

} catch(e) {

}

Now, the cursor is automatically positioned inside the try block, and the next time you press tab it moves to the catch block. Pressing tab again moves you outside the block. This is great, but not hugely useful in the real world. What would be more likely than writing an empty try... catch statement up-front would be to write some code, and choose to surround it in the try block. I promised to tell you how to do that, and it is much simpler than I thought.

The answer is the TextMate variable $TM_SELECTED_TEXT. It does exactly what it says it does, but you can’t use a tab trigger to achieve our goal here. Highlight some text, and start typing and of course, the text is overwritten. In this instance, a tab trigger will not do. You need to use a "Key Equivalent" (or hotkey or shortcut key to the rest of us). In my instance, I have more than enough of those to remember already, thankyouverymuch, and so I highlight the text and do one of the following:

  • Click the Bundle menu item at the top of the screen and drill down to my snippet
  • Press Ctrl+Escape and drill down to my snippet
  • Or, my favourite, press Ctrl+Command+T to bring up a list of all the snippets, type "try" to filter the list, and press return

There is nothing to stop you just typing try and pressing return either.

Here is the final snippet:

Name:
try ... catch
Tab trigger:
try
Snippet:
try {
	$TM_SELECTED_TEXT$1
} catch(e) {
	$2
}


try... catch TextMate Bundle Editor Example

Note that there should be a trailing extra carriage return, to ensure the final tab takes us out on to the line following the block.

JavaScript Snippets in TextMate

So, I finally started getting into snippets in TextMate. If you haven't played with TextMate – it's described by its publisher MacroMates as The Missing Editor for Mac OS X. I'd have to agree, after messing with probably 30 or more IDEs by now – it's the only one that stays simple and true and easy, until you try to do something complicated. Only then do you really realise the ridiculous amount of power under the hood. I could imagine three day long courses on this thing. You can get a 30 day trial from here, and it's only €50 to buy which is an absolute bargain in anyone's money. It's OS X only, but e-TextEditor purports to do the same thing for Windows, even supporting bundles (the plug-in format). You can read more about that here – but I can't vouch for it, having not played with it. Anyway, I digress. TextMate (and apparently e-TextEditor) supports "Snippets" – which allow you to type something short (the "Tab trigger"), press the tab key, and have it auto-complete to something more complicated. The simplest example of this – type in:

lorem

and press tab, and TextMate spits out:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Pretty cool, right? It even moves the keyboard caret focus to straight after the newly inserted text. We can go a bit further, and include "Tab stops". These tell TextMate how to behave immediately after pressing tab the first time, to auto-complete, and the following consecutive times. For an if block, for example, you probably want to start typing your condition within the brackets following the if, and then start typing inside the braces. TextMate will automatically do this for you – make sure you have a .js file open, anywhere in the document type:

if

…and press tab, and you'll get:

if (true) {};

…and "true" will be automatically highlighted. Press tab after you've typed in your conditional statement, and the caret is moved inside the braces! This is all pretty great, but there were a few snippets missing, or not working just as I would like, so I've made them myself.

To create a snippet, open up TextMate. Under the "Bundles" menu, select "Bundle Editor", then "Edit Snippets". You'll see a long list of all the code types that TextMate understands – you'll want to find and expand "JavaScript". When creating a new snippet, click the plus symbol underneath the list and choose "New Snippet". Give it a name (this doesn't affect your tab trigger, although if you choose to have a menu of potential snippets for one tab trigger, the name is what will show there. See my "Lorem Ipsum" example at the end of this post on how to do that). The code for the snippet goes in the big box (click the question mark for help with the syntax). Everything else should already be selected correctly, And you just type the text that you want TextMate to react to in the text box next to "Activation".

Firstly, I modified the existing for loop snippet, to improve performance by just checking the property we're comparing our counter against once, instead of with every iteration. This is already well documented so I won't go into it further – but here's the amended snippet:

Name: for (...) {...}
Tab trigger: for
Snippet:
for (var ${20:i}=0, ${21:j}=${1:Things}.length; ${20:i} < ${21:j}; ${20:i}++) {
${100:${1:Things}[${20:i}]}$0
};

Then, I made a snippet for the switch operator.

Name: switch
Tab trigger: switch
Snippet:
switch (${1}) {
case "${2}" :
${3}
break;
case "${4}" :
${5}
break;
default :
}

I adjusted, and possibly fixed the setTimeout snippet (I wouldn't go so far as to say it was broken – TextMate is quite mature by now, and the developers are clearly very good, but the tab stop order was confusing to me, and there seemed to be an unnecessary one in there):

Name: setTimeout function
Tab trigger: timeout
Snippet:
setTimeout(function() {$1}, ${2:10});

I created a for in loop snippet:

Name: for in
Tab trigger: forin
Snippet:
for (var ${1:key} in ${2:object}) {
${3:${2:object}[${1:key}]}
}

A try catch snippet:

Name: tray catch
Tab trigger: try
Snippet:
try {
$1
} catch(e) {
$2
}

And finally, since I was on a roll and can never remember the syntax – the ternary operator:

Name: ternary
Tab trigger: ?
Snippet:
${1:condition} ? ${2:if true} : ${3:if false}

I also wanted to improve the Lorem Ipsum snippet. The point of Lorem Ipsum text is that it represents nothing more than a blob of text – you (or, I, at least) can't read it, so you don't associate it with anything, and it is therefore perfect for layout: you see the layout, you don't read the text. But, if you keep re-inserting the exact same block of text, patterns will form in your document, and it will not have the intended effect of looking like nondescript text. www.lipsum.com have a very good Lorem Ipsum generator, that can create multiple paragaphs which do not have to begin with "Lorem ipsum". Rather than looking these up all the time, I copied few random ones, and just made a pile of snippets with the same tab trigger ("lorem") as the original one, which has the affect of showing a menu when you press tab, with all the snippets associated with that tab trigger as all your different options in the menu. I named them "Lorem ipsum 1", "Lorem ipsum 2", "Lorem ipsum 3", "Lorem ipsum (short) 1", "Lorem ipsum (long) 1", etc and applied them to "Plain Text" rather than "JavaScript".

To see all of these working, first make sure TextMate understands your file is a JavaScript file – there's a drop-down (drop-up in this instance) menu at the bottom of the TextMate window, that defaults to "Plain Text" for new files – you'll want to select "JavaScript" from this list (though the "lorem" tab trigger should work in any document). Then type any of the tab triggers we have defined (it's case sensitive) and press tab! My next task is going to be doing this for all those pesky HTML tags I can never remember the exact syntax for, and getting the try catch snippet to surround highlighted text if you have some selected.