So turns out ts_node_field_name_for_child takes a named node index,
but we were passing it normal index that counts both named and
anonymous nodes. That's what makes the field name all wrong in
treesit explorer.
* doc/lispref/parsing.texi:
(Accessing Node Information): Update docstring.
* lisp/treesit.el (treesit-node-index): Add some unrelated comment.
(treesit-node-field-name): Get named node index rather than all node
index.
* src/treesit.c (Ftreesit_node_field_name_for_child): Update
docstring, use ts_node_named_child_count.
* lisp/treesit.el (treesit-simple-indent-presets):
adaptive-fill-regexp don't have a capture group (the group in the
default value is supposed to be a non-capture group), so don't use the
group. Also, in the second diff hunk, replace looking-at with
looking-at-p so it doesn't override match data that we use later.
* lisp/treesit.el (treesit-explore-mode): Reset
treesit--explorer-last-node before calling treesit--explorer-refresh,
so that in the rare case described in the bug report, the explorer
buffer don't show the outdated node.
* lisp/treesit.el (treesit-update-ranges): If an embedded language
doesn't have any range, don't set its range to nil (which means whole
buffer), instead, set its range to a dummy (1 . 1) zero range.
* lisp/treesit.el (treesit--font-lock-notifier): Use
with-silent-modifications when marking modified text to be fontified
by jit-lock. This is what jit-lock itself does.
Raised in bug#63750, but not the main subject of it.
* lisp/treesit.el (treesit-install-language-grammar): Save the recipe
to treesit-language-source-alist when installation is successful.
* lisp/progmodes/c-ts-mode.el:
(c-ts-mode--indent-styles): Handle the empty line case.
* test/lisp/progmodes/c-ts-mode-resources/indent.erts: New test.
* doc/lispref/modes.texi (Parser-based Indentation): Update manual.
* lisp/treesit.el (treesit-simple-indent-presets): Support null as
a value for NODE-TYPE in the 'match' matcher.
Now it handles the case where NODE is nil when indenting an empty
line: it tries to get the previous sibling nonetheless.
* lisp/progmodes/c-ts-mode.el (c-ts-mode--anchor-prev-sibling):
* lisp/treesit.el (treesit-simple-indent-presets): Add an or form to
handle more cases.
Fix it for the case where there is no suitable rule for the line.
Right now treesit-indent-region would indent the line to column 0.
After the change the indentation is not altered.
* lisp/treesit.el (treesit-indent-region): Handle the case where
ANCHOR or OFFSET is nil specially.
Before this change, when you use a tree-sitter navigation function to
move to the next beginning of a thing, it jumps over the immediate
next thing and lands you at the beginning of the next-next thing.
Eg, when point is at the "|", and we evaluate
(treesit--navigate-thing pos 1 'beg), we go from
| (thing) (thing)
to
(thing) |(thing)
But some might expect point to go to
|(thing) (thing)
instead, which makes sense. Also, that's how Emacs expect defun
navigation functions to work. The discrepancy in expectation causes
bug#61617.
In this change I made tree-sitter navigation functions to work as what
Emacs expects. And what I described for moving to the next beginning
of thing is similarly applicable to moving to the end of previous end
of thing.
* lisp/treesit.el (treesit-beginning-of-defun)
(treesit-end-of-defun): Handle the case where defun-skipper moves
point back to where we started, by adding a retry.
(treesit--navigate-thing): Add a single condition checking for
progress to the condition form responsible for checking whether to
skip the next defun. Namely (eq pos (funcall advance next)))).
* test/src/treesit-tests.el:
(treesit--ert-defun-navigation-nested-master)
(treesit--ert-defun-navigation-top-level-master): Change tests to
reflect the new expectation.
When writing c-ts-mode Theo used parent-bol which works well except
one case:
1 for (int i=0;
2 i < 5;
3 i++) {
4 func(i);
5 }
In this case, when indenting "func(i)", parent-bol returns the start
of "i++" on line 3, instead of the "correct" anchor, the start of
"for" on line 1. parent-bol would have worked if the "for (...) {"
part is in one line.
To support this case I tried numerous things and added a bunch of
stuff, culminating in c-ts-common-statement-offset. It's complicated,
requires extra setup, and slow.
Not anymore! I think the new anchor standalone-parent really captures
the logic behind how people expect indentation to work. It's simple
and fast, and requires no setup.
* doc/lispref/modes.texi (Parser-based Indentation): Update manual.
* lisp/progmodes/c-ts-mode.el:
(c-ts-mode--standalone-grandparent): New anchor.
(c-ts-mode--indent-styles): Replace c-ts-common-statement-offset with
standalone-parent.
(c-ts-base-mode): Add comment.
* lisp/treesit.el:
(treesit-simple-indent-presets): New anchor standalone-parent.
Now prev-adaptive-prefix looks at the current line and checks if it
begins with a prefix itself. If it does, prev-adaptive-prefix tries
to place the anchor before the prefix on the previous line, rather
than after it.
- prev line
- this line -> This line starts with a "-", i.e., begins with a
prefix, so we place the anchor at the beginning of the
"-" of the previous line, rather than after it
- prev line
this line -> This line doesn't start with a prefix, so the anchor
is placed after the previous line's "-".
* doc/lispref/modes.texi (Parser-based Indentation): Update manual.
* lisp/treesit.el:
(treesit-simple-indent-presets): Add local variable
this-line-has-prefix, base what anchor to return on the value of
this-line-has-prefix and whether the prev line has a prefix.
* doc/lispref/compile.texi (Native-Compilation Variables):
Document the interpretation of non-absolute directory names that
are the value of 'native-comp-enable-subr-trampolines'.
* doc/emacs/display.texi (Parser-based Font Lock):
Update description of treesit-font-lock-level, moving 'property' to
level 4.
* lisp/treesit.el (treesit-font-lock-level): Likewise, in docstring.
* lisp/progmodes/c-ts-mode.el (c-ts-base-mode): Do that here.
* lisp/progmodes/cmake-ts-mode.el (cmake-ts-mode): Add a comment.
* lisp/progmodes/go-ts-mode.el (go-ts-mode): Add 'definition' to
level 1. Move 'function', 'property' and 'variable' to level 4.
(go-ts-mode--font-lock-settings): Move a bunch of existing rules
to 'definition'. Add highlighting of function parameters.
* lisp/progmodes/rust-ts-mode.el (rust-ts-mode)
(rust-ts-mode--font-lock-settings): Same. And also change "scoped
identifiers" highlights to only match capitalized names.
* lisp/treesit.el (treesit--font-lock-level-setter): Don't loop
over all the buffers if tree-sitter is not built-in, or else
initialization of defcustom will fail. (Bug#61155)
* lisp/progmodes/rust-ts-mode.el (treesit-node-parent):
* lisp/progmodes/c-ts-common.el (treesit-node-parent): Declare, to
* avoid byte-compilation warnings.
* lisp/progmodes/c-ts-mode.el (c-ts-mode-map): Bind "C-c .", for
consistency with CC mode.
* lisp/treesit.el (treesit-font-lock-level): Doc fix.
* doc/emacs/programs.texi (C Indent, Custom C Indent): Document
the indentation features of 'c-ts-mode'.
(Moving by Defuns): Document 'treesit-defun-tactic'.
* doc/emacs/files.texi (Visiting): Document
'treesit-max-buffer-size'.
* doc/emacs/display.texi (Traditional Font Lock)
(Parser-based Font Lock): New subsections.
* doc/emacs/emacs.texi (Top): Update top-level menu.
* lisp/treesit.el:
(treesit--children-covering-range-recurse): Return nil if LIMIT is
exceeded.
(treesit--font-lock-fast-mode): Change to a ternary value.
(treesit-font-lock-fontify-region): Enable fast mode based on the
result of treesit-subtree-stat.
* lisp/treesit.el:
(treesit--explorer-kill-explorer-buffer): New function.
(treesit-explore-mode):
1. Move prompt for language earlier, and terminate early if language
not available.
2. Make sure desktop-save doesn't save the explorer buffer.
3. Kill the explorer buffer when the source buffer is killed.
This has been brought up in bug#60691 and bug#60223. I proposed a fix
by testing the size of the tree rather than measuring the query time.
But after some thought, I fear that just looking at the size will give
us false-negatives. So I kept the time-based activation, just added a
grace count to reduce false-positives.
* lisp/treesit.el:
(treesit--font-lock-fast-mode-grace-count): New variable.
(treesit--font-lock-notifier): Only activate fast mode after 5
offenses.