Sunday, July 10, 2011

What’s Cool In IntelliJIDEA. Part II: Live Templates

In IntelliJ, I use Live Templates quite heavily and still think that these are underused. It is not only the standard number of templates that can make your life easier while typing yet another piece of code, but it is also the ability to define new templates with all the bells and whistles that are available in IntelliJ standard template list.

In the previous post I've covered the basics of Live Templates but I think that it would be cool to cover these in more details and to point out some less-known aspects of this functionality.

First of all, Ctrl+J is the shortcut to use in order to get a list of the available by default. But if you had time to practice, most likely you can remember the abbreviations by heart, like psvm, iter, psfs, soutv, etc.

One thing I do for sure before using Live Templates is that I change the default expansion key, which is Tab by default, to a Space key. It seems to me that it is more natural to use Space for this purpose as when you type you actually hit the Space key almost automatically.

Another cool feature of Live Templates is to surround a capable statement with a block of code - also covered in the previous post.

How do I define my own template?

IntelliJ provides a number of templates in its default distribution but obviously it doesn't cover all cases you might need. So here's the main purpose of this post - how to define a custom live template in IntelliJ. First, let's make up a use case - a situation where we'd like to have some means for typing faster but which isn't defined in the IDE by default.

For some reason, IntelliJ doesn't provide try-catch template by default. It only suggests this option if you'd like to surround an existing statement with the try-catch block, but not when you just want to create an empty one. Here's what we can do: open Settings window (Ctrl+Alt+S) and start typing 'Live Templates' - this will lead you to the templates' settings - and hit the "Add.." button on the right.

It is quite easy to create a simple template which just has to generate a defined text for the given keyword. For the empty try-catch block we just need to fill in the abbreviation and the code itself, and not to forget to bind it to Java context using the corresponding checkbox.

This is quite a dumb template, nothing intelligent here. But what if we'd like to suggest the exception type in the catch block? What if we'd like to position the cursor in some particular place after the template is applied? Let's make our brand new template a little smarter.

To ask IntelliJ for a type of the throwable in the catch block we can add a variable ($EXCEPTION$) and define its value using a special function provided by IntelliJ. Say, I'd like the type to be a subtype of java.lang.Exception class, hence I'm using the subtype(<type>) function:

You've probably noticed that I've used another variable, $END$, but there's no value defined in the dialog window. This is a predefined variable, meaning where should the cursor be positioned after the last choice made within the templates.

So now once I type 'try' and hit the space key, the template is expanded to the following:

First the cursor will be positioned inside the catch block in order to choose the type of the exception to be handled. Right after I make my mind about the type and hit the Enter key, the cursor will be positioned back into the try block.

We can go further and add an option to choose the method call on the exception instance by emulating the Ctrl+Space behavior using a special function again. This is a fictional example but let's assume we want that :)

For the purpose, I've defined a $METHOD$ variable which is assigned a complete() function in the template editor:

Now, once the type of the exception is selected, the next thing to happen is the automatic auto-completion action on the instance of the exception within the catch block - the list of available methods will popup:

There's actually a fair number of functions that could be used in Live Templates for the variable assignment. The nice part is that these work not only for Java but also other languages - when writing JavaScript, HTML or Groovy code, for instance.

Surround with template

The other type of live templates available in IntelliJ is the surrounding templates. It means you can select a text block (or just position the cursor to a desired location) and hit the Ctrl+Alt+T shortcut - a popup with the templates list will be suggested.

Defining a custom surround template isn't any different from the normal templates besides that the selected block of code (or text) is assigned to a predefined $SELECTION$ variable. Also, if a template contains this variable it will not appear in the list of normal templates provided via Ctrl+J.

Let's make an example for defining a custon surrounding template. Assume we'd like to quote a selected text. This is a very simple template - just need to add the quotes around the $SELECTION$ variable in the template editor:

Now if I select a text and hit Ctrl+Alt+T shortcut and then "Q" key the selected text will be put into quotes:


If you use IntelliJ, Live Templates should be your bread and butter for tying the code faster. There's plenty of the standard templates defined in IntelliJ, but don't be limited only to the standard template list - define your own templates according to your code specifics - you will not regret that!


0x1e said...

Great opportunities for practice, it'd surely take some time to get around these features (i mean also part 1 post).

For what i've already used before, maybe it'd worth noting, are live templates for logging, like log (to introduce logger), err, info, debug and warn

daleqq said...

When complete input the code in the try-catch live template, is there any tip that can quickly jump to the line after catch? Thanks.

arhan said...

if you use "surround with" try-catch live template, then it automatically selects a line in the catch block. Are you looking for something different?

It is easy to define your own live template and you can define your own final cursor position as you wish using the $END$ terminator.

Freak said...

went here after your talk at geecon - thanks for showing couple useful features :)

Disqus for Code Impossible