Freemarker Extension for Zed
Full-featured syntax highlighting and language support for Apache Freemarker Template Language (FTL) files in Zed editor, powered by a custom tree-sitter grammar.
Table of Contents
Discord - Join our discord server and chat with the maintainers.
Features
- Full Syntax Highlighting: Complete tree-sitter-based parser for accurate FTL syntax highlighting
- Comment Support: Both angle bracket (
<#-- -->) and square bracket ([#-- --]) comment styles - Smart Bracket Matching: Automatic closing and matching for all bracket types
- HTML Integration: Seamless HTML syntax highlighting within templates
- Freemarker Directives: Full support for:
- Control structures (
if,else,elseif,switch) - Loops (
list,foreach) - Variable assignment and interpolation
- Macros and functions
- Built-in functions
- Include and import statements
- Control structures (
- Lightweight: Minimal overhead, fast parsing
- Standards Compliant: Follows Apache Freemarker 2.3+ syntax specification
Installation
From Zed Extensions Gallery (Recommended)
- Open Zed editor
- Press
Cmd+Shift+X(macOS) orCtrl+Shift+X(Linux/Windows) to open Extensions - Search for "Freemarker"
- Click Install
Manual Installation (Development)
For local development or testing unreleased versions:
# Clone the repository into your Zed extensions directory
git clone https://github.com/debba/zed-freemarker ~/.config/zed/extensions/freemarker
# Restart Zed or reload extensionsVerify Installation
- Open a
.ftlfile in Zed - Check the language indicator in the bottom-right corner
- You should see "Freemarker" as the active language
Usage
Once installed, the extension automatically activates for files with the .ftl extension. The editor will provide:
- Syntax highlighting for Freemarker directives and expressions
- Comment toggling with
Cmd+/(macOS) orCtrl+/(Linux/Windows) - Automatic bracket pairing and closing
- HTML syntax within templates
Syntax Examples
Basic Variable Interpolation
<#-- Variable assignment -->
<#assign userName = "John Doe">
<#assign userAge = 25>
<h1>Welcome ${userName}!</h1>
<p>Age: ${userAge}</p>Conditional Statements
<#if userAge >= 18>
<p>You are an adult.</p>
<#elseif userAge >= 13>
<p>You are a teenager.</p>
<#else>
<p>You are a child.</p>
</#if>List Iteration
<#assign fruits = ["Apple", "Banana", "Cherry", "Date"]>
<h2>Fruit List:</h2>
<ul>
<#list fruits as fruit>
<li>${fruit}</li>
</#list>
</ul>Hash/Map Operations
<#assign user = {
"name": "Jane Smith",
"email": "jane@example.com",
"role": "Administrator"
}>
<h2>User Information:</h2>
<dl>
<dt>Name:</dt>
<dd>${user.name}</dd>
<dt>Email:</dt>
<dd>${user.email}</dd>
</dl>Built-in Functions
<p>Name in uppercase: ${user.name?upper_case}</p>
<p>Name length: ${user.name?length}</p>
<p>First fruit: ${fruits?first}</p>
<p>Capitalized: ${userName?cap_first}</p>Null Handling
<#-- Check if variable exists -->
<#if optionalValue??>
<p>Value: ${optionalValue}</p>
<#else>
<p>Value is not set</p>
</#if>
<#-- Default value -->
<p>${pageTitle!"Default Title"}</p>Macros
<#-- Macro definition -->
<#macro greet person>
<p>Hello, ${person}! Nice to meet you.</p>
</#macro>
<#-- Macro usage -->
<@greet person="Alice" />
<@greet person="Bob" />Alternative Square Bracket Syntax
[#assign name = "John Doe"]
<h1>Hello ${name}!</h1>
[#if user??]
<p>Welcome, ${user.name}!</p>
[#else]
<p>Please log in.</p>
[/#if]
[#list products as product]
<li>${product.name} - ${product.price}</li>
[/#list]Include and Import
<#-- Include another template -->
<#include "header.ftl">
<#-- Import macros from another file -->
<#import "lib/utils.ftl" as utils>
<@utils.formatDate date=.now />Development
Prerequisites
- Rust (for building tree-sitter grammar)
- Node.js (for tree-sitter CLI)
- Tree-sitter CLI
Building from Source
# Clone the repository
git clone https://github.com/debba/zed-freemarker.git
cd zed-freemarker
# Build the tree-sitter grammar
cd grammars/freemarker
npm install
npm run build
# Return to root and install in Zed
cd ../..
cp -r . ~/.config/zed/extensions/freemarkerTesting the Grammar
cd grammars/freemarker
# Run tree-sitter tests
tree-sitter test
# Open the playground for interactive testing
tree-sitter playgroundProject Structure
zed-freemarker/
├── extension.toml # Extension metadata
├── languages/
│ └── freemarker/
│ └── config.toml # Language configuration
├── grammars/
│ └── freemarker/ # Tree-sitter grammar
│ ├── src/
│ │ ├── grammar.json
│ │ └── node-types.json
│ ├── bindings/
│ ├── Cargo.toml
│ └── package.json
├── example.ftl # Example template file
└── README.mdRoadmap
- Language Server Protocol (LSP) support for:
- Code completion
- Go to definition
- Find references
- Hover documentation
- Snippet library for common Freemarker patterns
- Auto-formatting support
- Template validation and error checking
- Integration with Freemarker documentation
- Support for custom directives
- Theme customization for better highlighting
Contributing
Contributions are welcome and appreciated! Here's how you can help:
Reporting Issues
If you find a bug or have a feature request:
- Check if the issue already exists in GitHub Issues
- If not, create a new issue with:
- Clear description of the problem or feature
- Steps to reproduce (for bugs)
- Example code that demonstrates the issue
- Your Zed version and operating system
Pull Requests
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Test thoroughly with various
.ftlfiles - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request with a clear description of your changes
Development Guidelines
- Follow existing code style and conventions
- Add tests for new features when applicable
- Update documentation for user-facing changes
- Keep commits focused and atomic
- Write clear commit messages
Credits
- Inspired by the VS Code vs-freemarker extension
- Built with Tree-sitter
- Developed for Zed editor
- Apache Freemarker project
License
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright (c) 2026 Andrea Debernardi
Support
- Issues: GitHub Issues
- Repository: GitHub
- Tree-sitter Grammar: tree-sitter-freemarker
- Freemarker Documentation: Official Docs
Made with care for the Zed community