Amit Patel: Emacs Tree-sitter custom highlighting, part 1

Wait 5 sec.

A few years ago I blogged about custom tree-sitter-based syntax highlighting in emacs. I started out with highlighting certain keywords in red. I wanted to show the keywords that interrupt control flow: Screenshot showing syntax highlighting of keywords in black or redI highlight regular keywords (while, if) in bold. I highlight control flow interrupting keywords (return, continue) in red.That's syntax highlighting.But I also wanted to highlight names based on their meaning. In some projects I'm working with horizontal and vertical measurements, and I thought it would be nice to highlight those variable names differently. In some projects I'm working with Delaunay+Voronoi meshes, and I wanted to highlight the triangles, edges, and polygons differently. In some projects I'm working with hexagonal grids, and I wanted to highlight the three axes differently, like I do in my guide to hexagonal grids. In some projects I am working with html+js mixed code, and I wanted to highlight the html vs js differently, like I do in my tutorial on how I write interactive tutorials.In that blog post from a few years ago, I had used emacs tree-sitter mode to implement this type of highlighting. Since then, emacs has incorporated its own tree-sitter mode, which works differently from the third party package. I decided to update my code to work with the new tree-sitter functions.Let's start with highlighting keywords. This doesn't really need tree sitter mode, but I'm using it because I want to highlight more in part 2 of this post. The treesit-font-lock-rules function compiles tree sitter patterns into some internal format. Since the set of keywords is different per language, I'm going to make one variable per language. Here's the one for Python:(defface amitp-control-keyword-face)(defvar amitp/python-treesit-settings (treesit-font-lock-rules :language 'python :feature 'keyword :override t '( (["assert" "await" "break" "continue" "finally" "raise" "return" "yield"] @amitp-control-keyword-face) ) ))This will highlight those keywords in my amitp-control-keyword-face instead of the default font-lock-keyword-face.A minor note — I had tried reusing my previous tree-sitter face names, which were named with periods (variable.horizontal) and colons (amitp:keyword), but I ran into some errors, so I switched to only using dashes (variable-horizontal) for the new tree sitter modes.I then have to install these highlighting rules into treesit-font-lock-settings, which is a buffer-local variable. So I install it from a hook:(add-hook 'python-ts-mode-hook (lambda () (setq-local treesit-font-lock-settings (append treesit-font-lock-settings amitp/python-treesit-settings))))That's all it took to get my keywords highlighting the way I wanted. But wait, there's more!I had noticed that type aliases didn't highlight the way I wanted. Here's the screenshot: The keyword type isn't being highlighted here. I could add it as a keyword like the others:(defvar amitp/python-treesit-settings (treesit-font-lock-rules :language 'python :feature 'keyword :override t '( (["assert" "await" "break" "continue" "finally" "raise" "return" "yield"] @amitp-control-keyword-face) (["type"] @font-lock-keyword-face) ;;