fixing an emacs + typescript-ts-mode problem
Recently, I’ve been having a problem with Typescript files in Emacs —
any time I open one and it tries to activate eglot
(the new-ish
built-in LSP mode), I would get this massive multi-line error that
started with query pattern is malformed
. Read on to see how I fixed
it.
Step one, of course, was to search for the error message, which led me to an r/emacs post about the same problem, in which the offered and reported-to-work solution was “downgrade the treesitter grammar” …but nowhere in the thread does anybody explain how one might go about doing that, and searching for “how to downgrade treesitter grammar” was not a helpful exercise.
Now, I knew from the thread what version of the grammar I needed to
grab — v0.20.3
— and since I use a helper package called
treesit-auto
to help
manage tree-sitter grammars, I figured the answer was probably
somewhere in there. After poking around a little bit, I found
treesit-auto-recipe-list
, which is a list of grammars, their github
repos, what modes they associate with, and how to compile them. I even
found the entries for typescript-ts-mode
and tsx-ts-mode
in that
list.
Each of the recipes is the list is the output from a function called
make-treesit-auto-recipe
, and all of them look roughly like this:
(make-treesit-auto-recipe
:lang 'typescript
:ts-mode 'typescript-ts-mode
:remap 'typescript-mode
:requires 'tsx
:url "https://github.com/tree-sitter/tree-sitter-typescript"
:revision "master"
:source-dir "typescript/src"
:ext "\\.ts\\'")
Clearly the fix here is to get that :revision "master"
bit to
instead say :revision "v0.20.3"
— but how? Ideally I’d replace the
entry in the existing list, but that felt like it would turn into a
rat-hole of searching for ELsip list-munging functions. A quick skim
of the documentation and code in treesit-auto
strongly suggested
that the list would be checked in order and the first entry that
matched the ts-mode
node would be the one that got used — so my fix
ended up looking like this:
;; this fixes a problem where v0.20.4 of this grammar blows up with emacs
(defvar genehack/tsx-treesit-auto-recipe
(make-treesit-auto-recipe
:lang 'tsx
:ts-mode 'tsx-ts-mode
:remap '(typescript-tsx-mode)
:requires 'typescript
:url "https://github.com/tree-sitter/tree-sitter-typescript"
:revision "v0.20.3"
:source-dir "tsx/src"
:ext "\\.tsx\\'")
"Recipe for libtree-sitter-tsx.dylib")
(add-to-list 'treesit-auto-recipe-list genehack/tsx-treesit-auto-recipe)
(defvar genehack/typescript-treesit-auto-recipe
(make-treesit-auto-recipe
:lang 'typescript
:ts-mode 'typescript-ts-mode
:remap 'typescript-mode
:requires 'tsx
:url "https://github.com/tree-sitter/tree-sitter-typescript"
:revision "v0.20.3"
:source-dir "typescript/src"
:ext "\\.ts\\'")
"Recipe for libtree-sitter-typescript.dylib")
(add-to-list 'treesit-auto-recipe-list genehack/typescript-treesit-auto-recipe)
Once I added that to my
config,
deleted the existing grammar libraries (they were at
tree-sitter/libtree-sitter-tsx.dylib
and
tree-sitter/libtree-sitter-typescript.dylib
in my Emacs
configuration directory), and restarted Emacs, when I visited a TS
file, I got prompted to install the Typescript tree-sitter grammar,
which I did, and then everything went back to working. A fine use of
an hour on Sunday morning…
And now that I’ve written this all up, I will return to the r/emacs post where i found the answer, and link to this post, so that hopefully the next person that runs across this issue and finds that post doesn’t have to spend an hour figuring out how to downgrade the typescript tree-sitter grammar…
Onwards.