FreeMarker for Visual Studio Code
Language support for Apache FreeMarker
templates (.ftl) in Visual Studio Code. Built on a client + server
Language Server Protocol architecture, with autocomplete, hover docs,
semantic highlighting, diagnostics, and reference-aware navigation
across an .ftl workspace.
If you write FreeMarker — for email templates, server-rendered HTML,
configuration generation, or any of the other places FreeMarker lives —
this extension gives you the IDE affordances you would expect from a
first-class language extension: directive completion when you type
<#, built-in completion when you type ?, hover popups with the
canonical FreeMarker reference one click away, and navigation across
macros and assigns.
Features
Syntax highlighting
A TextMate grammar (syntaxes/ftl.tmLanguage.xml) colors FreeMarker
templates — directives (<#if>, <#list>, <#macro>, …), interpolations
(${…}), comments (<#-- … -->), and the surrounding host markup.
Files with the .ftl extension activate automatically; the language id
is ftl (aliases: FreeMarker, freemarker).
Directive autocomplete (<#)
Server-side LSP completion provider, fed by a curated catalog of 33
FreeMarker directives. Type <# and the full directive set surfaces
with signature, summary, and snippet-style insert text:
- Control-flow:
if, elseif, else, switch, case, default,
break, continue.
- Iteration:
list, items, sep.
- Definitions:
assign, local, global, macro, function,
return, nested.
- Composition:
include, import.
- Output control:
compress, escape, noescape, noparse, t,
lt, rt, nt, flush.
- Error handling:
attempt, recover.
- Misc:
setting, outputformat, stop, visit, recurse, ftl.
Built-in function autocomplete (?)
Server-side LSP completion provider, fed by a curated catalog of 81
FreeMarker built-ins — the ?name operators applied to values:
- String:
?upper_case, ?lower_case, ?html, ?trim, ?contains, …
- Sequence:
?size, ?seq_contains, ?reverse, ?sort, ?first,
?last, …
- Hash:
?keys, ?values.
- Numeric:
?round, ?floor, ?ceiling, ?abs, ?int, ?string.
- Boolean:
?then, ?c.
- Date:
?date, ?time, ?datetime, ?iso_utc, ?iso_local, …
- Meta:
?eval, ?interpret, ?new, ?has_content, ?is_string,
?is_number, ?is_sequence, … and the rest of the is_* family.
Each completion item carries a Markdown body with signature, summary,
category, and a [Reference](https://github.com/prmichaelsen/freemarker-vscode/blob/HEAD/url) link to the canonical
freemarker.apache.org page (and, where the manual exposes it, the
exact anchor on that page).
Hover documentation
Hovering on a directive name (<#if, </#list) or a built-in name
(?upper_case, ?size) opens a Markdown popup with:
- The canonical signature.
- A one-paragraph summary from the FreeMarker reference.
- The directive / built-in category.
- A
[Reference](https://github.com/prmichaelsen/freemarker-vscode/blob/HEAD/url) link to the matching freemarker.apache.org
page (with anchor where applicable — see CHANGELOG v0.1.6 for the
curated anchor-overrides that handle pages where the manual shares
anchors across builtins).
Hover and completion share the catalog source of truth, so they speak
with one voice.
Snippets
Two snippet files contribute scaffold-style insertions:
snippets/ftl.json — FreeMarker directive scaffolds (if, list,
macro, assign, attempt/recover, …).
snippets/html.json — common HTML snippets useful inside FTL
templates.
Semantic token highlighting
The client registers a semantic-tokens provider that augments the
TextMate grammar with token-classification metadata. Toggleable via the
freemarker-vscode.semantic-tokens setting (default on).
Diagnostics
A client-side FreeMarkerDiagnosticsProvider surfaces parse-style
issues against open .ftl documents. Toggleable via the
freemarker-vscode.diagnostics setting (default on).
Go to Implementation
Jump to a macro or function's definition inside the workspace.
Toggleable via the freemarker-vscode.go-to-implementations setting
(default on).
Go to Reference
Find references to macros, assigns, and other named symbols across the
workspace. Requires the file watcher (freemarker-vscode.watcher).
Toggleable via the freemarker-vscode.go-to-reference setting
(default on).
Commands
Three commands are contributed to the command palette:
FreeMarker: Add file — freemarker-vscode.addFile.
FreeMarker: Debug parser — freemarker-vscode.debugParser.
FreeMarker: Check for updates — freemarker-vscode.checkForUpdates.
Install
The extension is published to the Visual Studio Code Marketplace under
publisher prmichaelsen:
- From inside VS Code: open the Extensions view (
Ctrl+Shift+X /
Cmd+Shift+X), search for FreeMarker, and install the entry
authored by prmichaelsen.
- From the CLI:
code --install-extension prmichaelsen.freemarker-vscode.
- From GitHub: download the latest
freemarker-vscode-<version>.vsix
from
github.com/prmichaelsen/freemarker-vscode/releases
and install it via the Extensions view's … → Install from VSIX….
VS Code ^1.75.0 is required.
Getting started
- Open any
.ftl file (or save a new file with the .ftl extension).
- Confirm the language mode in the status bar reads FreeMarker — the
grammar should color directives, interpolations, and comments
immediately.
- Type
<# anywhere — the directive completion list appears.
- Type
${someValue? — the built-in completion list appears.
- Hover on any directive or built-in name to see its signature, summary,
and a one-click link to the canonical FreeMarker reference page.
- Right-click a macro or assign name to use Go to Implementation or
Go to References.
Configuration
All settings live under the freemarker-vscode.* namespace and can be
edited from Settings → Extensions → FreeMarker:
| Setting |
Type |
Default |
Description |
freemarker-vscode.watcher |
boolean |
true |
Enable the file watcher. Required for "Go to Reference" and Test Explorer. |
freemarker-vscode.go-to-reference |
boolean |
true |
Enable the "Go to Reference" feature. Requires the watcher. |
freemarker-vscode.diagnostics |
boolean |
true |
Enable the diagnostics feature. |
freemarker-vscode.go-to-implementations |
boolean |
true |
Enable the "Go to Implementation" feature. |
freemarker-vscode.semantic-tokens |
boolean |
true |
Enable semantic-token highlighting. |
freemarker-vscode.telemetry |
boolean |
false |
Enable telemetry. |
Version & changelog
Current version: 0.1.6.
The full release history — including the v0.1.0 LSP directive
autocomplete cut, the v0.1.1 server-side hover migration, the v0.1.2
Jest + Mocha test-suite shipment, the v0.1.4 documentationUri
enrichment that put [Reference] links on every hover and completion
item, and the v0.1.5 / v0.1.6 URL-audit fixes — is in
CHANGELOG.md.
Contributing & development
To hack on the extension itself:
- Run
npm install at the project root. This installs deps in the
root, client/, and server/ workspaces (via postinstall).
- Open the project folder in VS Code.
- Press
Ctrl+Shift+B to start tsc watch mode across the client and
the server (see VS Code's
tasks docs).
- Switch to the Run and Debug view (
Ctrl+Shift+D), select Launch
Client from the dropdown, and press F5. VS Code spawns an
Extension Development Host
with the extension loaded.
- Inside the host window, open or create a
.ftl file and exercise
directive autocomplete, hover, etc.
Tests
The extension ships two suites:
- Unit tests (Jest) —
npm test or npm run test:unit from the
project root. Runs jest inside server/ and exercises the pure
LSP handler surface (catalogs, completion resolver, hover resolver,
symbol extraction) without spinning the LSP transport. Fast (~3 s).
- Integration tests (Mocha +
@vscode/test-electron) — npm run test:integration from the project root. Downloads a VS Code build,
launches it, loads the extension, opens fixture .ftl files under
integration/testFixture/, and asserts hover popups and completion
lists end-to-end via the VS Code API. Slow on first run; cached
thereafter.
Source repository
github.com/prmichaelsen/freemarker-vscode.
| |