Bug summary
Given the same input, GNU Emacs and neomacs produce different output:
|
treesit-query-expand '((nil) @f) |
| GNU Emacs 31.1 |
"(nil) @f" |
| neomacs 0.0.19 |
"(()) @f" |
() and nil are not the same thing in a tree-sitter query.
The tree-sitter query syntax reference says a node pattern is
a pair of parentheses containing two things: the node's type
so (()) contains no type name and matches nothing the syntax defines.
Steps to reproduce
Side-by-side comparison
emacs --batch -Q -l treesit-nil-demo.el
neomacs --batch -Q -l treesit-nil-demo.el
The acceptance check needs a grammar for any of go, ruby or lua.
;;; treesit-nil-demo.el --- -*- lexical-binding: t; -*-
(require 'treesit)
(defvar tnd-queries
'(((nil) @f)
([(false) (nil) (true)] @f)
([(false) (true)] @f))
"Query sexps to pass to `treesit-query-expand'.")
(defvar tnd-dirs
(let ((dirs (list (expand-file-name "tree-sitter/" user-emacs-directory)
(expand-file-name "~/.local/share/emacs/tree-sitter/")
(expand-file-name "~/.emacs.d/tree-sitter/"))))
(when (boundp 'treesit-extra-load-path)
(setq treesit-extra-load-path
(append (seq-filter #'file-directory-p dirs) treesit-extra-load-path)))
dirs)
"Where this script looks for grammars, so it needs no extra flags.")
(defvar tnd-lang (seq-find #'treesit-language-available-p '(go ruby lua)))
(dolist (q tnd-queries)
(let ((out (treesit-query-expand q)))
(princ (format "in %S\n" q))
(princ (format "out %S\n" out))
(princ (format "accepted %s\n\n"
(cond ((null tnd-lang) "(no grammar found)")
((ignore-errors (treesit-query-compile tnd-lang out t) t) "yes")
(t "no"))))))
(princ (if tnd-lang
(format "(grammar: %s)\n" tnd-lang)
(format "(no grammar found; looked in %s)\n" (string-join tnd-dirs " "))))
Output, same grammar files:
** GNU Emacs 31.1
in ((nil) @f)
out "(nil) @f"
accepted yes
in ([(false) (nil) (true)] @f)
out "[(false) (nil) (true)] @f"
accepted yes
in ([(false) (true)] @f)
out "[(false) (true)] @f"
accepted yes
(grammar: go)
** neomacs 0.0.19
in ((nil) @f)
out "(()) @f"
accepted no
in ([(false) (nil) (true)] @f)
out "[(false) (()) (true)] @f"
accepted no
in ([(false) (true)] @f)
out "[(false) (true)] @f"
accepted yes
(grammar: go)
The inputs are identical on both builds. The outputs are not, and each
build's own output is then handed back to the same grammar: GNU's is
accepted, neomacs's is rejected. The third query, which contains no nil,
expands the same way on both and is accepted by both.
go-ts-mode, ruby-ts-mode and lua-ts-mode all match nil literals in
their font-lock rules, so on neomacs opening a .go, .rb or
.lua file gives:
Warning (treesit-font-lock-rules-mismatch): Emacs cannot compile every
font-lock rules because a mismatch between the grammar and the rules. [...]
This error can be fixed by either downgrading the grammar (tree-sitter-go)
on your system, or upgrading the major mode package. The following are the
temporarily disabled features:
- `constant' for go.
The same grammar files work on GNU Emacs.
Expected behavior
No response
Neomacs --version output
GNU Emacs 31.1 (emacs-plus)
macOS 27.0 (Darwin 27.0.0), arm64
Neomacs 0.0.19
Git commit: b715d50bd26cceb537e905adf1cc3bfbf46fd340
Source date: 2026-09-20T12:37:58.000000000-04:00
Build: release for aarch64-apple-darwin with rustc 1.96.1
Standalone Rust binary for Neomacs (no C dependency)
Platform
macOS
Install source
Prebuilt release asset (downloaded from Releases)
Extra context
No response
Bug summary
Given the same input, GNU Emacs and neomacs produce different output:
treesit-query-expand '((nil) @f)"(nil) @f""(()) @f"()andnilare not the same thing in a tree-sitter query.The tree-sitter query syntax reference says a node pattern is
so
(())contains no type name and matches nothing the syntax defines.Steps to reproduce
Side-by-side comparison
The acceptance check needs a grammar for any of go, ruby or lua.
Output, same grammar files:
The inputs are identical on both builds. The outputs are not, and each
build's own output is then handed back to the same grammar: GNU's is
accepted, neomacs's is rejected. The third query, which contains no
nil,expands the same way on both and is accepted by both.
go-ts-mode,ruby-ts-modeandlua-ts-modeall match nil literals intheir font-lock rules, so on neomacs opening a
.go,.rbor.luafile gives:The same grammar files work on GNU Emacs.
Expected behavior
No response
Neomacs --version output
Platform
macOS
Install source
Prebuilt release asset (downloaded from Releases)
Extra context
No response