Commit Graph

461 Commits

Author SHA1 Message Date
altermo
170ff4b244 refactor(treesitter): use same visual-select as lsp #38475
Problem
treesitter select over-complicates visual selection.

Solution
make it use same visual selection logic as lsp.
2026-03-25 05:20:42 -04:00
Gregory Anders
a728eb7af1 refactor(treesitter)!: remove "all" option of Query:iter_matches #33070
This option was introduced to help with transitioning to the new
behavior during the 0.11 release cycle with the intention of removing in
0.12.
2026-03-23 14:34:14 -04:00
Justin M. Keyes
e3a1e47bb2 docs: misc 2026-03-20 23:30:09 +01:00
altermo
929be7ee00 refactor(treesitter): move range related functions 2026-03-14 12:25:14 +01:00
nikolightsaber
fd1e019e90 refactor(treesitter)!: get_parser return nil on error #37276 2026-03-13 15:57:36 -04:00
Justin M. Keyes
017d8aa298 refactor: rename _ensure_integer => _assert_integer 2026-03-13 20:32:01 +01:00
Lewis Russell
ce1154048b refactor: integer functions, optimize asserts #34112
refactor(lua): add integer coercion helpers

Add vim._tointeger() and vim._ensure_integer(), including optional base
support, and switch integer-only tonumber()/assert call sites in the Lua
runtime to use them.

This also cleans up related integer parsing in LSP, health, loader, URI,
tohtml, and Treesitter code.

supported by AI
2026-03-12 11:04:05 -04:00
Justin M. Keyes
b8a976afda docs: api, messages, lsp, trust
gen_vimdoc.lua: In prepare for the upcoming release, comment-out the
"Experimental" warning for prerelease features.
2026-03-11 18:00:18 +01:00
altermo
72d3a57f27 feat(treesitter): incremental selection
Co-authored-by: György Andorka <gyorgy.andorka@protonmail.com>
2026-03-08 11:07:49 +01:00
Christian Clason
908591c61c refactor(lua): adapt to Stylua 2.4.0 2026-03-07 18:23:35 +01:00
Stefan VanBuren
d8e03d5d5a fix(treesitter): escape hyphen in lua pattern
Ref: https://github.com/neovim/neovim/pull/38140#discussion_r2897235978
2026-03-07 11:08:34 +01:00
Stefan VanBuren
01817eb6f3 fix(treesitter): normalize language aliases
Hyphenated language names are silently dropped when used as injections
(see #38132).

This combines the normalization of language aliases into `resolve_lang`,
and also adds the normalization of hyphens to underscores, which allows
for handling of injected language tags with hyphens in their names.

Fixes #38132.
2026-03-04 17:15:59 +01:00
phanium
16aab4cb48 fix(treesitter): InspectTree only show the largest injection #37906
Problem:
:InspectTree don't show luadoc injection lua file. Since luadoc share
the same "root" with comment in their common primary (lua) tree.
Current logic simply show the largest (comment injection) and ignore all
smaller one (luadoc injection).

Solution:
Handle different lang injections separately. Then sort them by
byte_length to ensure the draw tree consistent.
2026-02-24 16:22:30 -05:00
zeertzjq
08f4811061 fix(treesitter): :InspectTree wrong title for non-relative path #37965
Problem:  :InspectTree sets wrong title for file with non-relative path.
Solution: Use full path if relpath() returns nil.
2026-02-19 12:05:48 -05:00
Michele Campeotto
d0822bbd15 fix(treesitter): highlight group for EditQuery captures #36265
fix(treesitter): more distinctive highlight for EditQuery captures

Problem: EditQuery shows captures in the source buffer using the Title
highlight group, which could be too similar to Normal.

Solution: Use a virtual text diagnostic highlight group: they are
displayed in a similar manner to the query captures so we can assume
that the color scheme should have appropriate styling applied to make
them visible.
2026-02-12 08:07:13 -05:00
Yochem van Rosmalen
f7041625f1 refactor(lua): use vim.fs instead of fnamemodify
Although powerful -- especially with chained modifiers --, the
readability (and therefore maintainability) of `fnamemodify()` and its
modifiers is often worse than a function name, giving less context and
having to rely on `:h filename-modifiers`. However, it is used plenty in
the Lua stdlib:

- 16x for the basename: `fnamemodify(path, ':t')`
- 7x for the parents: `fnamemodify(path, ':h')`
- 7x for the stem (filename w/o extension): `fnamemodify(path, ':r')`
- 6x for the absolute path: `fnamemodify(path, ':p')`
- 2x for the suffix: `fnamemodify(path, ':e')`
- 2x relative to the home directory: `fnamemodify(path, ':~')`
- 1x relative to the cwd: `fnamemodify(path, ':.')`

The `fs` module in the stdlib provides a cleaner interface for most of
these path operations: `vim.fs.basename` instead of `':t'`,
`vim.fs.dirname` instead of `':h'`, `vim.fs.abspath` instead of `':p'`.
This commit refactors the runtime to use these instead of fnamemodify.

Not all fnamemodify calls are removed; some have intrinsic differences
in behavior with the `vim.fs` replacement or do not yet have a
replacement in the Lua module, i.e. `:~`, `:.`, `:e` and `:r`.
2026-01-28 10:57:39 +00:00
ashab-k
86c939ba91 fix(treesitter): fix spell navigation on first line (#37361)
Problem:  Spell navigation skips words on the first line because
          _on_spell_nav passes an empty range (0,0) to the highlighter.

Solution: Use math.max(erow, srow + 1) to ensure a valid search window.

Signed-off-by: ashab-k <ashabkhan2000@gmail.com>
2026-01-15 10:20:24 +08:00
Peter Cardenas
f8ac713448 fix(treesitter): use metadata in :EditQuery captures #37116
Problem:
When the `#offset!` directive is used with `:EditQuery`, the query does not take the offset into consideration when creating the extmark to preview the capture.

Solution:
Use the capture metadata to modify the node range before creating the extmark.
2025-12-30 10:44:18 -05:00
Jaehwang Jung
756e1eb017 fix(treesitter.foldexpr): duplicate callbacks #37048
Problem:
VimEnter clears foldinfo, so register_cbs is called again after
VimEnter. The duplicate parser callbacks break incremental fold
computation.

Solution:
Check if the callbacks are already registered.
2025-12-21 00:47:46 -05:00
Harsh Kapse
043f5a291a feat(health): show available queries for treesitter (#37005)
Problem: Outdated query files in `runtimepath` can trigger errors
which are hard to diagnose.

Solution: Add section to `:check treesitter` that lists all query 
files in `runtimepath`, sorted by language and query type. Files
are listed in `runtimepath` order so that the first of multiple entry
is typically the one that is used.

Note: Unlike the `nvim-treesitter` health check, this does not try
to parse the queries so will not flag incompatible ones (which would
be much more expensive).
2025-12-20 16:34:24 +01:00
Riley Bruins
976a47e81b Revert "refactor(treesitter): use scratch buffer for string parser" #36964
This reverts commit 2a7cb32959.
2025-12-15 02:09:36 -05:00
Jaehwang Jung
63737e6e73 fix(treesitter): no injection highlighting on last line #36951
Problem:
If the last visible line in a window is not fully displayed, this line
may not get injection highlighting. This happens because line('w$')
actually means the last *completely displayed* line.

Solution:
Use line('w$') + 1 for the botline.

This reverts 4244a96774
"test: fix failing lsp/utils_spec #36609",
which changed the test based on the wrong behavior.
2025-12-14 19:01:49 -05:00
Chris Grieser
4e2ed1d03c fix(treesitter): missing nowait for :InspectTree keymaps #36804 2025-12-02 10:49:58 -05:00
Riley Bruins
098da1fc2c perf(treesitter): parse multiple ranges in languagetree, eliminate flickering #36503
**Problem:** Whenever `LanguageTree:parse()` is called, injection trees
from previously parsed ranges are dropped.

**Solution:** Allow the function to accept a list of ranges, so it can
return injection trees for all the given ranges.

Co-authored-by: Jaehwang Jung <tomtomjhj@gmail.com>
2025-11-18 10:09:49 -08:00
Riley Bruins
f2bfde9140 fix(treesitter): reset next_col when performing intermediate highlights
The iterator is meant to be fully reset in this code path, but only the
`next_row` state was being reset. This would only cause highlight
artifacts for very brief periods of time, though.
2025-11-06 09:27:21 +00:00
Justin M. Keyes
1f2883e879 fix(outline): use 2-space indent instead of 1-space
2 spaces is more visually distinct at very little cost.
2025-10-24 02:07:37 +02:00
Riley Bruins
ac15b384a6 refactor(treesitter): use scratch buffer for string parser #35988
This commit changes `languagetree.lua` so that it creates a scratch
buffer under the hood when dealing with string parsers. This will make
it much easier to just use extmarks whenever we need to track injection
trees in `languagetree.lua`. This also allows us to remove the
`treesitter.c` code for parsing a string directly.

Note that the string parser's scratch buffer has `set noeol nofixeol` so
that the parsed source exactly matches the passed in string.
2025-10-02 15:33:18 -07:00
skewb1k
e3c36f31e3 fix(highlight): ensure extmark range is within buffer bounds #35928
Adds an additional check for the case when end_col = 0, addressing
https://github.com/neovim/neovim/issues/35814#issuecomment-3340709532.

Validation is now localized to the highlighter without affecting the C API.
2025-09-26 19:32:28 -07:00
bfredl
5119c03be7 fix(treesitter): use subpriorities for tree ordering
This partially reverts 0b8a72b739,
that is unreverts 15e77a56b7

"priority" is an internal neovim concept which does not occur in shared
queries. Ideally a single priority space should eventually be enough
for our needs. But as we don't want to poke at the usages of
priorities right now in the wider ecosystem,
introduce the "subpriorities" so that treesitter code can distinguish
highlights of the same priorities with different tree nesting depth.

This mainly affects `injection.combined` as parent-tree nodes might appear
in the middle of child-tree nodes which otherwise is not possible.
2025-09-09 12:56:49 +02:00
bfredl
f9d2115a35 perf(highlight): allow decoration providers to skip ranges without data
Continuing the work of #31400

That PR allowed the provider to be invoked multiple times per line.
We want only to do that when there actually is more data later on the
line. Additionally, we want to skip over lines which contain no new
highlight items. The TS query cursor already tells us what the next
position with more data is, so there is no need to reinvoke the range
callback before that.

NB: this removes the double buffering introduced in #32619 which
is funtamentally incompatible with this (nvim core is supposed to keep
track of long ranges by itself, without requiring a callback reinvoke
blitz). Need to adjust the priorities some other way to fix the same issue.
2025-09-09 12:54:04 +02:00
Yochem van Rosmalen
4cda52a5d1 docs(treesitter): fix language-injection url #35592 2025-09-01 14:08:08 -07:00
vanaigr
5edbabdbec perf: add on_range in treesitter highlighting 2025-08-28 08:22:38 -05:00
Christian Clason
c10e36fc01 refactor(lua): consistent use of local aliases 2025-08-28 11:34:01 +02:00
Sean Dewar
3ec63cdab8 fix(treesitter): run FileType autocmds in the context of <abuf>
Problem: many FileType autocommands assume curbuf is the same as the target
buffer; this can cause &syntax to be restored for the wrong buffer in some cases
when TSHighlighter:destroy is called.

Solution: run nvim_exec_autocmds in the context of the target buffer via
nvim_buf_call.
2025-08-19 20:03:05 +01:00
Jalil David Salamé Messina
bd45e2be63 fix(checkhealth): wrong ABI version for treesitter parsers #35327
Don't print ABI version of duplicated parsers that are later in the
runtime path (see [#35326]).

Change the sorting from `name > path` to `name > rtpath_index`, this
ensures the first (loaded) parser is first in the list and any
subsequent parsers can be considered "not loaded".

This is fuzzy at best since `vim.treesitter.language.add` can take a
path to a parser and change the load order.

The correct solution is for `vim.treesitter.language.inspect` to return
the parser path so we can compare against it and/or for it to also be
able to take a path to a parser so we can inspect it without loading it
first.
2025-08-14 11:47:43 -07:00
Jaehwang Jung
3eab5bd38a fix(treesitter): set local values of window options 2025-08-12 16:26:11 +01:00
Justin M. Keyes
56a4ef3c21 docs: lsp, ui events, dev guidance, osc7
fix #34981
2025-07-28 22:00:25 -04:00
Peter Cardenas
e5c2ce5905 fix(treesitter): ":EditQuery [lang]" with injected languages #34914
Problem:
`:EditQuery` command accepts a language argument, but it doesn't
highlight properly for injected languages.

Solution:
- Fully parse with the root language and then filter the query on the
  child trees that are of the language requested.
- Also support completion (`EditQuery <tab>`).
2025-07-19 11:36:51 -07:00
Phạm Bình An
435f03ee10 docs: tag of :EditQuery #34844
Problem:
- Running `:h :EditQuery` throws error `E149: Sorry, no help for
  :EditQuery`
- vim_diff.txt miss an entry for `:EditQuery`

Solution:
- Make tag `[:EditQuery]()` right-aligned, similar to command `:Open`
- Update vim_diff.txt
2025-07-08 05:28:12 -07:00
glepnir
28b7c2df52 fix(health): floating window closes when opening TOC (gO) #34794
Problem: Health check floating window gets closed when pressing 'gO' to show TOC because LSP floating preview system auto-closes on BufEnter events triggered by :lopen.

Solution: Temporarily disable BufEnter event for the current window during TOC operations and adjust window layout to prevent overlap.
2025-07-08 05:21:09 -07:00
Artem
18e0301e1f fix(treesitter): inconsistent highlight of multiline combined injection #32619
Problem:
Combined injections not entirely highlighted.

Solution:
Reapply layer highlights on each line.
2025-07-06 11:05:41 -07:00
Lewis Russell
e34e2289c2 fix(diagnostic): fix flaky error 2025-07-04 18:03:41 +01:00
Rodrigodd
168bf0024e fix(treesitter): ensure TSLuaTree is always immutable
Problem:

The previous fix in #34314 relies on copying the tree in `tree_root` to
ensure the `TSNode`'s tree cannot be mutated. But that causes the
problem where two calls to `tree_root` return nodes from different
copies of a tree, which do not compare as equal. This has broken at
least one plugin.

Solution:

Make all `TSTree`s on the Lua side always immutable, avoiding the need
to copy the tree in `tree_root`, and make the only mutation point,
`tree_edit`, copy the tree instead.
2025-07-02 17:05:17 +01:00
phanium
0694ca8822 fix: map wincmd instead of remap #34635
Same issue: a59b052857
2025-06-25 06:33:58 -07:00
Luis Calle
cfb4d3d2f2 docs(treesitter): fix parameter list for Query:iter_matches (#34553) 2025-06-22 10:38:00 +00:00
Riley Bruins
1d5b3b5b4c feat(treesitter)!: apply offset! directive to all captures #34383
This commit changes the `offset!` directive so that instead of setting a
`metadata.range` value for the entire pattern, it will set a
`metadata.offset` value. This offset will be applied to the range only
in `vim.treesitter.get_range()`, rather than at directive application
time. This allows the offset to be applied to any and all nodes captured
by the given pattern, and removes the requirement that `#offset!` be
applied to only a single node.

The downside of this change is that plugins which read from
`metadata.range` may be thrown off course, but such plugins should
prefer `vim.treesitter.get_range()` when retrieving ranges anyway.

Note that `#trim!` still sets `metadata.range`, and
`vim.treesitter.get_range()` still reads from `metadata.range`, if it
exists.
2025-06-13 06:42:10 -07:00
notomo
58d85cd03d fix(treesitter): ensure window is valid in async parsing #34385
Problem: Error occurs if window is invalid in the middle of parsing.

Solution: Check if window is valid in parsing.

- Error
```
vim.schedule callback: ...im/share/nvim/runtime/lua/vim/treesitter/highlighter.lua:485: Invalid window id: 1037
stack traceback:
	[C]: in function 'nvim__redraw'
	...im/share/nvim/runtime/lua/vim/treesitter/highlighter.lua:485: in function 'cb'
	...m/share/nvim/runtime/lua/vim/treesitter/languagetree.lua:494: in function '_run_async_callbacks'
	...m/share/nvim/runtime/lua/vim/treesitter/languagetree.lua:550: in function <...m/share/nvim/runtime/lua/vim/treesitter/languagetree.lua:529>
```

- Reproduce script
```lua
local bufnr = vim.api.nvim_create_buf(false, true)
local many_lines = vim.fn["repeat"]({ "local test = 'a'" }, 100000)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, many_lines)
local window = vim.api.nvim_open_win(bufnr, true, {
  relative = "editor",
  row = 0,
  col = 0,
  width = 10,
  height = 10,
})
vim.bo.filetype = "lua"
vim.schedule(function()
  vim.api.nvim_win_close(window, true)
end)
```
2025-06-08 16:44:40 -07:00
Riley Bruins
8b41df185c fix(treesitter): support multiple @injection.content captures
Before, only the last capture's range would be counted for injection.
Now all captured ranges will be counted in the ranges array. This is
more intuitive, and also provides a nice solution/alternative to the
"scoped injections" issue.
2025-06-08 18:23:22 +02:00
Riley Bruins
faae1e72a2 fix(treesitter): scope highlight state per window #34347
**Problem:** There is a lot of distracting highlight flickering when
editing a buffer with multiple open windows. This is because the
parsing/highlighting state is shared across all windows.

**Solution:** Greatly reduce flicker in window splits by scoping the
highlighter state object and the `parsing` state object to each
individual window, so there is no cross-window interference.
2025-06-07 09:27:46 -07:00
Lewis Russell
3b6084ddf4 fix: type fixes
Type fixes caught by emmylua
2025-06-06 15:36:48 +01:00