Use elisp-tree-sitter for Highlighting in Doom Emacs
Get faster, richer and more beautiful code syntax highlighting in Doom Emacs using the power of tree-sitter and abstract syntax trees.
Tree-sitter is a general programming language parser that efficiently builds and updates Abstract Syntax Trees (AST) for your code. Basically, it can read programming languages and understand the structure and meaning of code without having to execute it. Among many amazing things, one of its best and simplest features to take advantage of is richer syntax highlighting, which is what I use it for in Emacs. Today I’ll show you how to set up elisp-tree-sitter in Doom Emacs1 so you can quickly get prettier code with next to no effort.
First, add these lines to
(package! tree-sitter) (package! tree-sitter-langs)
packages.el config above has been simplified accordingly. There’s no longer any need to specify a
tsc package2 or write a manual
straight.el recipe to fetch it from GitHub.
config.el, you’ll need:
(use-package! tree-sitter :config (require 'tree-sitter-langs) (global-tree-sitter-mode) (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode))
doom sync in a terminal, restart Doom Emacs with
SPC q R and explore some code to see the new highlighting. You’ll notice some of these changes:
- Things that are harder to detect with regex are now highlighted and differentiated (e.g. function names, properties on objects, template strings)
- More use of italics and bold font weights to help with the above
- Potential speed and stability improvements, since AST parsing should be faster and more robust than regex parsing.
elisp-tree-sitter highlighting works by mapping each major mode in Emacs to a language-specific parser. This falls apart when a major mode happens to support multiple or mixed languages in the one file, for example
Personally, I tried mapping
tree-sitter-major-mode-language-alist, but it complained and didn’t work when I tried to turn on highlighting. This seems to be a dead end for now.
One other thing I found missing from the standard setup was SCSS support, which I’ve added by putting the following in my
:config section of
(pushnew! tree-sitter-major-mode-language-alist '(scss-mode . css))
This seems to work OK for now, however it’s not officially supported and may be unstable.