A quick setup guide for .heex files on Emacs. At the time of writing, Doom Emacs only
supports up to 28, and 29+ are not supported yet. This guide could become irrelevent
once Emacs 29 becomes stable.
Since I'm using Doom Emacs, this will provide steps to get .heex working on it as well.
We'll need to install the tree-sitter-cli before proceeding.
Rust version
git clone https://github.com/tree-sitter/tree-sitter
cd tree-sitter/cli
cargo build --release # Build tree-sitter in release mode
cd ../
cp ./target/release/tree-sitter /path/for/binThere's a NPM package as well so this can be used if Rust is not installed in your system.
NPM version
npm i -g tree-sitter-cli@19Verify with the following command.
> ~/bin/tree-sitter
tree-sitter 0.19.5 (8d8690538ef0029885c7ef1f163b0e32f256a5aa)
Max Brunsfeld <maxbrunsfeld@gmail.com>
Generates and tests parsers
USAGE:
tree-sitter <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
SUBCOMMANDS:
build-wasm Compile a parser to WASM
dump-languages Print info about all known language parsers
generate Generate a parser
help Prints this message or the help of the given subcommand(s)
highlight Highlight a file
init-config Generate a default config file
parse Parse files
query Search files using a syntax tree query
tags
test Run a parser's tests
web-ui Test a parser interactively in the browserBuild
Let's start with retrieving the tree-sitter code for heex.
The repo for tree-sitter-heex is provided by the Phoenix team and is available at phoenixframework/tree-sitter-heex.
git clone https://github.com/phoenixframework/tree-sitter-heex.git
At the time of writting, tree-sitter-heex comes with src/parser.c, but since it was generated with v0.20 of the CLI, we'll need to use the v0.19 version to regenerate it.
tree-sitter generateYou should see some diffs after the command which you can ignore.
> git status
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: src/parser.c
modified: src/tree_sitter/parser.h
no changes added to commit (use "git add" and/or "git commit -a")cc -shared -fPIC -fno-exceptions -g -I src src/parser.c -o ./heex.so -O2
You should see a heex.so file now.
Emacs
Now that heex.so is available, it's time to get it loaded into Emacs.
Tree-sitter Emacs looks for custom built libraries in tree-sitter-load-path, which is a list of strings.
You can run Alt x => describe-variable in Emacs to check for the current values. In my case, $HOME/.tree-sitter-/bin was already included in the variable
so I'll be placing the built heex.so there.
mkdir -p ~/.tree-sitter/bin
mv ./heex.so ~/.tree-sitter/bin/
Next step will be to instruct Emacs to load heex.so when it opened a file with .heex extension.
Add the following to ~/.doom.d/config.el
;; Elixir
;; Add heex-mode for modifying .heex files
(define-derived-mode heex-mode web-mode "HEEx" "Major mode for editing HEEx files")
(add-to-list 'auto-mode-alist '("\\.heex?\\'" . heex-mode))
(add-to-list 'tree-sitter-major-mode-language-alist '(heex-mode . heex))
(add-hook 'heex-mode-hook #'tree-sitter-hl-mode)
(add-hook 'heex-mode-hook
(lambda()
;; Ask tree-sitter to load 'heex.so'
(tree-sitter-load 'heex)
;; Auto format .heex files on save, requires liveview 0.18+
(add-hook 'before-save-hook 'elixir-format nil t)))Restart/reload Emacs and this should now show up.

Notes
Syntax highlighting itself is not really working for me at the moment, so will
probably update this post after I figure that out. Might have to deal with web-mode
directly.