Setting Up Neovim for Automad Theme Development

March 23, 2025  — 
 AutomadNeovimDev

As the developer of Automad, I wanted to make working with Automad themes in Neovim as smooth as possible. Automad has its own templating syntax, so I created tree-sitter-automad to provide proper syntax highlighting. Since it’s not yet an official parser, you need to manually register it in Neovim. To speed up template writing, you can also add custom snippets using LuaSnip. Here's how to set everything up.

Syntax Highlighting with Tree-sitter

By default, Neovim doesn't recognize tree-sitter-automad since it isn't an official parser yet. You can manually register it by modifying your Neovim config. Open ~/.config/nvim/init.lua (or ~/.config/nvim/lua/plugins/treesitter.lua if you separate plugins) and add:

local parser_config = require('nvim-treesitter.parsers').get_parser_configs()

parser_config.automad = {
  install_info = {
    url = 'https://github.com/automadcms/tree-sitter-automad',
    files = { 'src/parser.c' },
  }
}

require('nvim-treesitter.configs').setup {
  ensure_installed = { "lua", "html", "css", "javascript", "php", "automad" },
  highlight = {
    enable = true,
  },
}

Save the file and restart Neovim. Now Neovim will recognize Automad templates and provide syntax-aware highlighting.

Apart from the parser, Tree-sitter also needs query files to define syntax highlighting rules. Again, since Automad isn't an official parser yet, these queries aren't included by default, so you need to copy them manually.

Clone the tree-sitter-automad repository:

git clone https://github.com/automadcms/tree-sitter-automad.git ~/tree-sitter-automad

Then, create the directories where Neovim looks for Tree-sitter queries:

mkdir -p ~/.config/nvim/after/queries/php
mkdir -p ~/.config/nvim/after/queries/automad

Copy the query files from the repository into these directories:

cp ~/tree-sitter-automad/queries/* ~/.config/nvim/after/queries/php/
cp ~/tree-sitter-automad/queries/* ~/.config/nvim/after/queries/automad/

Once that's done, restart Neovim and check if the parser is working by running:

:checkhealth nvim-treesitter

If everything is set up correctly, automad should appear in the list of installed parsers. You can also take a look at my personal Neovim config repository to see how I have everything set up.

Adding Automad Snippets with LuaSnip

I personally use LuaSnip to manage my Neovim snipptes. To make writing Automad templates faster, I recommend that you define some custom Automad snippets directly inside your LuaSnip config. If you want to see how I integrate it into my setup, you can check out my personal Neovim config repository.

local luasnip = require('luasnip')
local s = luasnip.snippet
local t = luasnip.text_node
local i = luasnip.insert_node

luasnip.add_snippets('php', {
  s(
    { trig = '<@', name = 'Automad Statement' }, 
    { t({ '<@ ' }), i(1), t({ ' @>' }) }
  ),
  s(
    { trig = '@', name = 'Automad Variable' }, 
    { t({ '@{ ' }), i(1), t({ ' }' }) }
  ),
  s(
    { trig = '#', name = 'Automad Comment' }, 
    { t({ '<# ' }), i(1), t({ ' #>' }) }
  ),
  s(
    { trig = '@pagelist', name = 'foreach in pagelist' },
    { t({ '<@ foreach in pagelist @>', '	' }), i(1), t({ '', '<@ end @>' }) }
  ),
  s(
    { trig = '@pagelistelse', name = 'foreach in pagelist else' }, 
    {
      t({ '<@ foreach in pagelist @>', '	' }),
      i(1),
      t({ '', '<@ else @>', '	' }),
      i(2),
      t({ '', '<@ end @>' })
    }
  ),
  s(
    { trig = '@if', name = 'if ...' },
    { t({ '<@ if ' }), i(1), t({ ' @>', '	' }), i(2), t({ '', '<@ end @>' }) }
  ),
  s(
    { trig = '@ifelse', name = 'if ... else ...' }, 
    {
      t({ '<@ if ' }),
      i(1),
      t({ ' @>', '	' }),
      i(2),
      t({ '', '<@ else @>', '	' }),
      i(3),
      t({ '', '<@ end @>' })
    }
  ),
  s(
    { trig = '@with', name = 'with ...' },
    { t({ '<@ with ' }), i(1), t({ ' @>', '	' }), i(2), t({ '', '<@ end @>' }) }
  ),
  s(
    { trig = '@withelse', name = 'with ... else ...' }, 
    {
      t({ '<@ with ' }),
      i(1),
      t({ ' @>', '	' }),
      i(2),
      t({ '', '<@ else @>', '	' }),
      i(3),
      t({ '', '<@ end @>' })
	}
  ),
  s(
    { trig = '@for', name = 'for ... to ...' }, 
    {
      t({ '<@ for ' }),
      i(1),
      t({ ' to ' }),
      i(2),
      t({ ' @>', '	' }),
      i(3),
      t({ '', '<@ end @>' })
	}
  ),
  s(
    { trig = '@snippet', name = 'snippet ...' },
    { 
      t({ '<@ snippet ' }), 
      i(1), 
      t({ ' @>', '	' }), 
      i(2), 
      t({ '', '<@ end @>' })
    }
  ),
})

Now you can type Automad syntax triggers like @if, @for, or <@, then press Tab (or your configured expansion key) to insert full syntax structures automatically.

Wrapping Up

With Tree-sitter and LuaSnip set up, developing Automad themes in Neovim becomes much smoother. You now have syntax highlighting and custom snippets to speed up your workflow.

If you run into any issues, feel free to submit an issue on the tree-sitter-automad repository. You can also check out my personal Neovim config for more setup inspiration. Happy coding!

  Related Pages

Long-term open-source projects, such as Automad, require stability and independence from third-party libraries. Relying on external frameworks introduces risks that can impact maintainability, long-term support, and overall project longevity.

Creating a multilingual website can significantly expand your reach and user engagement by catering to a global audience. Automad 2, a lightweight CMS that prides itself on simplicity and flexibility, makes it easy to create and manage multilingual websites.

Starting with the latest alpha 16 of Automad 2, Open-Graph images are rendered automatically for every page on the fly. Colors can be customized, a logo can be added. No further setup needed. 

Automad 2.0 Alpha
October 4, 2024
 AutomadWeb

After a long development process, the stable release of Automad 2 is getting closer. While many aspects of the system have evolved, the core vision remains the same — delivering a fast, flexible, and file-based content management system with a powerful templating engine.