JetBrains Live Templates: Context Scoping and Variable Resolution Explained
Live Templates stop working when context rules or variable scope are misunderstood. Here is how expansion actually works and how to fix common failures.
07 Aug 2025, 11:38 UTC

The problem: abbreviations that silently do nothing
If you type a Live Template abbreviation and press Tab but nothing appears, the template is usually not broken—it is out of context. JetBrains Live Templates expand only when the abbreviation matches a template whose assigned context matches the current editor state, and their variables resolve against the static code structure, not runtime values. Understanding these two rules turns silent failures into predictable code generation.
How expansion actually works
An abbreviation is just a trigger. When you press Tab, the IDE checks every active template whose abbreviation matches your input and whose context includes the current cursor location. Context is more than file type: a template can be restricted to Java statements, class declarations, comments, string literals, or other scopes. If the cursor sits outside the allowed scope, the abbreviation is ignored.
Variables are evaluated at expansion time by reading the PSI tree—the IDE's parsed representation of your source file. Built-in variables such as $MN$ (enclosing method name), $CC$ (enclosing class name), $SELECTION$ (currently highlighted text), and $END$ (final cursor position) are resolved from that tree. You can also write Groovy expressions to compute values, but those expressions operate on the PSI tree only. They can ask “what method am I in?” but not “what is the value of this variable?” This static resolution keeps expansion fast and predictable, but it also means templates cannot adapt to the contents of variables or the results of method calls.
Worked example: a Java debug-comment template
Suppose you want a quick debug comment in Java. Create a template with the abbreviation dbgc and the text // $CC$.$MN$: $END$. Assign it to the Java context and a statement or declaration scope. When your cursor sits inside calculateTotal() in InvoiceService.java, pressing Tab after dbgc inserts // InvoiceService.calculateTotal: and leaves the cursor ready for a note. The $CC$ and $MN$ variables reflect the enclosing class and method at that exact cursor position because they are read from the PSI tree during expansion. If you later rename the class or method, the IDE updates the PSI tree, and the next expansion reflects the new names automatically.
Assigning and checking context
Template management lives under Settings → Editor → Live Templates. Select a template and use the context controls to restrict or broaden where it applies. The settings dialog shows a context preview for each template; if an abbreviation does not expand, confirm that the preview includes your current file type and cursor location.
| Variable | Resolves to | Typical use |
|---|---|---|
$MN$ | Enclosing method name | Logging, comments |
$CC$ | Enclosing class name | Logging, factory calls |
$SELECTION$ | Currently selected text | Wrapping snippets |
$END$ | Final cursor position | Post-expansion editing |
Limits and common mistakes
Abbreviation conflicts
A common failure mode is abbreviation collision. If sout is already bound to the standard Java print template, defining another template with the same abbreviation in the same context creates ambiguity. The IDE may silently prefer one template or suppress expansion entirely. The Available templates list in the Live Templates settings shows every active abbreviation; duplicates there are the first place to look.
Variable scope is static, not runtime
Template variables are local to the expansion context. $PARAM$ refers only to a parameter position defined within the template text, not to arbitrary method arguments in the surrounding code. Likewise, Groovy expressions have access limited to the template's PSI context; attempting to reference runtime state or elements outside that scope may yield null or default values.
Export and import fragility
Moving templates between IDE instances relies on XML configuration export. Because the template schema can change between IDE releases, an XML file exported from one version may import into another with missing variables or disabled contexts. Treat exported template files as version-specific rather than universal.
Verifying the result
To verify a template, open a file that matches its context, type the abbreviation, and press Tab. Confirm that the snippet appears and the cursor lands at $END$. If variables are blank, move the cursor to a location where the enclosing method or class is unambiguous and expand again. For templates that wrap existing code, select the target lines first, then type the abbreviation and press Tab; the selected text replaces $SELECTION$. If the abbreviation still does nothing, open Settings → Editor → Live Templates and check the context preview and the available templates list for conflicts.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.