aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter
Commit message (Collapse)AuthorAge
* ci(lua): enable annotation and style checksLewis Russell2026-09-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: - annotation-usage-error and code-style-check are disabled. - vim.inspect relies on a dummy self-assignment for docgen, and its help omits parameter and option details. - LuaLS fallback types obscure iterator inference. - Docgen hardcodes public function names and appends separately sorted files, leaving shared helpers under the inspector heading. Solution: - Enable annotation-usage-error and code-style-check, and fix misplaced annotations. - Document vim.inspect's callable module directly, removing the dummy assignment. Describe its parameters, option defaults and process callback. - Remove LuaLS iterator fallbacks, correct iterator signatures and check values that the improved inference identifies as optional. - Parse callable modules, require bindings and parent module references. Derive public names and inherited function docs from these links, including missing help for vim.async.semaphore() and vim.version(). - Export vim.lsp.tagfunc directly with lazy loading and document its implementation instead of maintaining a wrapper. - Group files in section_order, replacing append_only and merge_files. Merge declarations before sorting each section, placing shared helpers in the main vim section and keeping vim.inspect in alphabetical order. - Add basic parser coverage for callable modules and module links. AI-assisted
* fix(lua): enable param-type-mismatch diagnosticLewis Russell2026-09-28
| | | | | | | | | Problem: Argument type mismatches are excluded from EmmyLua checks. Solution: Correct runtime annotations and calls, document local checker workarounds, and enable the diagnostic. AI-assisted
* fix(lua): enable unnecessary-assert diagnosticLewis Russell2026-09-28
| | | | AI-assisted
* fix(editor)!: operator target/cgn modifies Visual marks #42119Justin M. Keyes2026-09-27
| | | | | | | | | | | | | | | | | | Problem: An operator on a target that creates a Visual selection (`cgn`, `d<C-v>j`, an omap text object like `:<C-U>normal! viw`) sets `'< '>`, `gv` and `visualmode()` to the operator target. This causes at least the following problems: - clobbers the user's previous `'< '>` (annoying and usually unwanted) - E.g. after a custom textobj, `:help text-object-define`. - "cgn" with a `\%V` pattern can't be dot-repeated (".") Solution: Don't save the Visual area if the operator target created it (operator was pending). Also fix `an`/`in` with `'selection'=exclusive` starting from an empty range.
* fix(lua): enable assignment type checking in runtime codeLewis Russell2026-09-25
| | | | | | | | | | | Enable EmmyLua's assign-type-mismatch diagnostic after correcting the runtime annotations and assignments it flags. Correct option, tuple, and return types, and use separate locals when a value changes representation. Add guards and narrow casts where needed so the runtime passes the stricter check. Regenerate the affected docs. AI-assisted
* fix(lua): enable nil-safety diagnostics in runtime codeLewis Russell2026-09-25
| | | | | | | | | | | | Enable EmmyLua's need-check-nil diagnostic and resolve nullable values through more precise types, explicit invariants, and guards for missing runtime state. Keep analyzer-specific workarounds local and update the affected API documentation. Exclude the bundled re.lua from analysis so its nil-check warnings do not fail CI. AI-assisted
* fix(treesitter): type synchronous parse results as non-nilLewis Russell2026-09-25
| | | | | | | | LanguageTree:parse() always returns trees when no callback is supplied, but its shared return type also permits nil for asynchronous parsing. Add the synchronous overload and document that distinction. AI-assisted
* fix(lua): add missing param annotations (#41911)Lewis Russell2026-09-15
|
* build: enable more EmmyLua checksLewis Russell2026-09-09
| | | | | | | | | | Enable checks for unused code, deprecated calls, return types, and annotations. Fix the warnings and replace the deprecated highlight function. Keep exceptions where old APIs are still needed or the checker gets it wrong. AI-assisted
* build: enable more EmmyLua checksLewis Russell2026-09-08
| | | | | | | | | | | | | | | | - call-non-callable - missing-fields - redefined-label - redefined-local - undefined-field - unreachable-code Promote redefined-local and unreachable-code to warnings. Fix DOS line-ending handling for multiline semantic tokens, and support intersection types in the help parser. AI-assisted
* build: replace LuaLS with EmmyLuaLewis Russell2026-09-07
| | | | | | | | | | | | | | | Problem: LuaLS struggles with the generics used in Nvim's runtime, requiring broad diagnostic suppressions. Indexing is also slow. Solution: Use EmmyLua for type checks in the build and CI. It offers more sophisticated type checking, substantially better support for generics, and much better flow analysis. Correct the affected annotations. Use `@internal`, supported directly by EmmyLua, instead of `@nodoc` for shared internal declarations, and support it in the help parser. AI-assisted
* fix(treesitter): conceal_lines is not applied to injected treesVolodymyr Chernetskyi2026-09-06
| | | | | | | | | | | | | | | | | | | | | Problem: TSHighlighter._on_conceal_line() parses with the range { row, row }. A Range2 has an exclusive end, so that is the empty range, and no injected region ever intercepts it. The root tree is parsed regardless, because its region is empty, so only injections are affected: conceal_lines metadata coming from an injected language's highlights query is dropped. on_range_impl() then records the row in _conceal_checked, so the miss persists until the buffer changes. For a markdown code block nested in a markdown code block, the inner fence delimiters stay visible and nvim_win_text_height() reports 5 rows where 3 are displayed. Solution: Pass the one-row range, as the on_range_impl() call below already does. AI-assisted
* fix(treesitter): #has-parent? errors on a node with no parentVolodymyr Chernetskyi2026-09-06
| | | | | | | | | | | | | | | | | Problem: The #has-parent? predicate indexes the result of node:parent() without checking it, so a capture that matches a tree's root node raises query.lua:600: attempt to index a nil value instead of simply not matching. In a highlights query that breaks highlighting for the whole buffer. The sibling #has-ancestor? predicate handles the same situation. Solution: Treat a missing parent as "does not match". AI-assisted
* fix(treesitter): accept a string title in inspect_tree() #41639Volodymyr Chernetskyi2026-09-02
| | | | | | | | | | Problem: `inspect_tree()` documents `title` as `string|fun(bufnr:integer):string|nil`, but the implementation handles only `nil` and function values. A string title leaves `title` unset and fails the assertion below. Solution: Use the string as the title.
* fix(treesitter): make TSHighlighter.new() idempotent for an active buffer #41090Freddie Haddad2026-08-02
| | | | | | | | | | | | | | | | | | | Problem: Calling vim.treesitter.start() a second time on a buffer that already has an active TSHighlighter creates a brand new instance instead of reusing it, whether the parser tree is unchanged (e.g. calling start() twice) or different (e.g. switching languages). Either way the old instance is silently discarded without calling :destroy() on it, so its on_bytes/on_changedtree/on_detach callbacks stay registered and its buffer-local state (spelloptions, decoration namespace) is never restored, both leaking indefinitely for an orphaned instance that nothing references anymore. Solution: Return the existing instance when TSHighlighter.active[source] is already set for the same parser tree, instead of unconditionally constructing a new one. When the tree differs instead (e.g. a language switch), destroy() the old instance first, matching stop() semantics, before constructing the new one.
* fix(treesitter): handle `&selection=exclusive`altermo2026-08-01
|
* refactor: combine all visual_selection funcionsaltermo2026-08-01
|
* feat(options): lua closure/function optionsJustin M. Keyes2026-07-31
| | | | | | | | | | | | | | | Problem: Cannot assign Lua functions/closures to "func" ('completefunc', 'tagfun', …) or "expr" ('foldexpr', 'indentexpr', …) options. Solution: - Store "func"/"expr" options as `Callback` instead of string. - Delete oceans of copy-pasted code. - BREAKING: LuaRef returned via RPC/Vimscript is now represented as `"<Lua N: file:line>"` (like what `:map` shows) instead of `nil`. - Note: `man.vim` still uses `v:lua` string, bc it's a vimscript ftplugin. Helped-by: Lewis Russell <lewis6991@gmail.com>
* fix(treesitter): incremental selection: "vin" not always starts "v" #41016altermo2026-07-28
|
* fix(treesitter): clamp unbounded fold rangesMilad Rashidikhah2026-07-28
| | | | | | | | | | Problem: Tree-sitter uses UINT32_MAX for full-document ranges, which becomes -1 on 32-bit platforms and reaches _foldupdate as an invalid end row. Solution: Treat negative changed-range end rows as unbounded and clamp them to the buffer line count. Add a regression test that simulates the 32-bit sentinel. AI-assisted: Codex
* refactor(api): omit optional paramJustin M. Keyes2026-07-13
|
* perf(treesitter): reduce memory usage of _select.lua #40409Dmytro Meleshko2026-06-25
| | | | | | | | | | Problem: The table `history` in treesitter/_select.lua stores references to previously selected TSNodes, but a TSNode needs to keep its whole TSTree alive in memory, which may be kept alive even after closing the buffer to which this history corresponds. Solution: Store just the bits of information from the TSNode we need to go back in selection history (the range and ID), without referencing the TSNode itself.
* fix(treesitter): incremental selection causes beeps when the bell is enabled ↵Dmytro Meleshko2026-06-25
| | | | | | | | | | | #40414 Problem: The function visual_select() in treesitter/_select.lua is executing `:normal! v<Esc>` to ensure that `gv` later goes back to character Visual mode, but doing so when mode() is already `v` first switches back to the Normal mode, then executes <Esc>, which causes a beep. Solution: Check if the mode() is already `v` and avoid any switching in that case.
* refactor: introduce nvim_on internally #39883Justin M. Keyes2026-05-20
| | | | | | | | | Problem: `nvim_create_autocmd` is too verbose and its `callback` requires extra "nesting". Solution: Introduce `nvim_on`. Start using it internally. Then we can get a feel for how it should look before making it public.
* Merge #39889 from ofseed/pos-utilJustin M. Keyes2026-05-20
|\ | | | | refactor(pos,range): drop `to_cursor`, extract `vim.pos._util`
| * refactor(pos,range): extract `vim.pos._util`Yi Ming2026-05-20
| | | | | | | | | | | | | | | | | | | | | | Problem: - To share logic, creating a `vim.Range` currently creates two `vim.Pos` values as intermediates, which causes unnecessary table allocations. - `pos.lua` and `range.lua` contain some overlapping logic. Solution: Add `vim.pos._util`, a module for handling positions represented directly by `row` and `col`.
* | fix(api): nvim_exec_autocmds({buf=x}) runs in buffer context #39061Barrett Ruth2026-05-20
|/ | | | | Problem: `nvim_exec_autocmds({ buf = ... })` matches the target buffer, but callbacks and modelines run with the caller buffer current rather than the target buffer. Solution: Execute the buffered path in prepared target-buffer context and restore the caller afterward.
* docs: dev, lsp, indent-guides #39756Justin M. Keyes2026-05-14
| | | | | | | - document "indent guides" https://github.com/neovim/neovim/issues/39726 - document guidance for "subcommands" https://github.com/neovim/neovim/issues/32263#issuecomment-4436002808 Co-authored-by: glepnir <glephunter@gmail.com> Co-authored-by: Noa Levi <275430404+lphuc2250gma@users.noreply.github.com>
* fix(treesitter): remove default match limit (#39696)Will Lillis2026-05-09
| | | | | | | | Problem: The default match limit of 256 can be too low for realistic use cases, but was necessary to guard against catastrophic performance cliffs. Solution: Performance cliffs were fixed in upstream tree-sitter 0.27+, so remove the fallback limit to return unlimited matches by default.
* feat(lua)!: vim.isnil, vim.nonnil, deprecate vim.F #39495Olivia Kinnear2026-05-06
|
* fix(treesitter): get_node_text() inconsistent trailing newline #39409David Balatero2026-05-03
| | | | | | | | | | | | | | | | | | Problem: `get_node_text()` returned inconsistent results between buffer and string sources when a node's range ends at `end_col == 0` (i.e. the node ends with a newline). The buffer path dropped the trailing newline; the string path included it correctly. Solution: Append `'\n'` in `buf_range_get_text()` when `end_col == 0` and `start_row ~= end_row`. The `start_row ~= end_row` guard excludes zero-width nodes at column 0, which should return `""`. Remove the workaround in the `#trim!` directive that manually compensated for the missing newline. Strip whitespace in `resolve_lang()` so injection language nodes ending at `end_col == 0` (e.g. `">lua\n"`) still resolve correctly.
* build(lint): allow "bufnr" as positional param #39515Justin M. Keyes2026-04-30
| | | | | Allow `bufnr` as a positional param name because it is very common. However as a field name, or part of a function name, it is usually a mistake.
* perf(treesitter): reuse edited tree ranges for callbacksLewis Russell2026-04-28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | After an edit, LanguageTree:_edit() updates the current trees. When the LanguageTree manages explicit regions, _edit() also refreshes _regions from tree:included_ranges(true), so those regions have the edited byte offsets. A later injection pass may call set_included_regions() with a different number of child regions. That path discards the old trees and emits changedtree callbacks for them. invalidate(true) does the same when a buffer is reloaded. Before this change, both discard paths called tree:included_ranges(true) for every old tree, even if _edit() had just collected those exact ranges. That duplicate range extraction is expensive with many injection trees. Realistic shapes include generated C files with many macro bodies parsed by the C preproc_arg injection, Markdown documents with many fenced blocks of the same language, and template files with many embedded-language islands. The stock highlighter registers recursive changedtree callbacks, so this is on the normal highlighting edit path. Track whether _regions currently came from tree:included_ranges(true) with _regions_from_tree_ranges. _do_changedtree_callbacks() reuses _regions only in that state; otherwise it falls back to calling tree:included_ranges(true). Clear the marker when regions are replaced by injection ranges, when a tree is reparsed, or when trees are discarded. This avoids keeping a second copy of the ranges while preserving callback precision: changedtree still receives tree:included_ranges(true) for the old tree, not the broader managed region. Benchmark on 100k C macro injections, one-line edit, recursive changedtree callback: - HEAD median: edited parse 84.2 ms, child region replacement 58.7 ms - This change: edited parse 34.6 ms, child region replacement 8.5 ms That is about 2.4x faster for the edit parse and 6.9x faster for child region replacement in this workload. Add a regression test that replacing injection regions still fires changedtree and still reports the old tree's exact included ranges. AI-assisted: Codex
* docs: sort quasi-keysetsJustin M. Keyes2026-04-26
|
* feat(treesitter/extmark): support removing a conceal highlight #35087Peter Cardenas2026-04-25
| | | | | | | | | Problem: Cannot remove a `@conceal` highlight when defined in highlights.scm. Solution: Support a `@noconceal` highlight that works similarly to `@nospell` where it overrides the conceal set on the range to remove it. Additionally, can set the conceal metadata field to false for the same behavior.
* feat(treesitter): expand selection to sibling node #38938altermo2026-04-22
| | | | | | | | | Problem: Can't expand treesitter-incremental-selection to the next and previous sibling nodes. Solution: Pressing `]N` in visual mode will expand the selection to the next sibling node, and `[N` will do the same with the previous node.
* fix(treesitter): TSNode:id() with NUL byte causes unreliable select() #39134altermo2026-04-16
| | | | | | | | | | | Problem: `TSNode:id()` returns the underlying c pointer as a string, which may include NUL bytes. In PUC Lua, `('%s'):format('\0a\0')` returns `''` and not `'\0a\0'` (i.e. treats the string as a c-string (which terminates at the NUL byte)). This resulted in two different nodes being able to have the same id. Solution: Use concatenation `..` instead of `string.format()`.
* feat(api): rename buffer to buf #35330Jordan2026-04-08
| | | | | | | | | | | | Problem: `:help dev-name-common` states that "buf" should be used instead of "buffer" but there are cases where buffer is mentioned in the lua API. Solution: - Rename occurrences of "buffer" to "buf" for consistency with the documentation. - Support (but deprecate) "buffer" for backwards compatibility. Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* fix(treesitter): select reset to "v" visualmode()altermo2026-04-02
|
* fix(treesitter): select with node ending with unicode char (#38557)altermo2026-03-31
| | | Co-authored-by: zeertzjq <zeertzjq@outlook.com>
* docs: fix syntax errors in examples #38606skewb1k2026-03-30
|
* fix(treesitter): ignore stale fold refresh callbacksLewis Russell2026-03-25
| | | | | | | | | | | | | | | | | | | | | Problem: The fold refresh path for foldminlines/foldnestmax creates a new FoldInfo and starts an async parse. If FileType or BufUnload re-enters before that callback returns, foldinfos[bufnr] can be cleared or replaced. The callback then indexes a stale slot and raises an "attempt to index a nil value" error. Solution: Capture the FoldInfo created for the refresh and carry that object through the async callback. Before calling foldupdate(), verify that the buffer still points at the same FoldInfo generation; otherwise ignore the stale callback. AI-assisted: Codex Fixes #38461
* refactor(treesitter): use same visual-select as lsp #38475altermo2026-03-25
| | | | | | | Problem treesitter select over-complicates visual selection. Solution make it use same visual selection logic as lsp.
* refactor(treesitter)!: remove "all" option of Query:iter_matches #33070Gregory Anders2026-03-23
| | | | | 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.
* docs: miscJustin M. Keyes2026-03-20
|
* refactor(treesitter): move range related functionsaltermo2026-03-14
|
* refactor(treesitter)!: get_parser return nil on error #37276nikolightsaber2026-03-13
|
* refactor: rename _ensure_integer => _assert_integerJustin M. Keyes2026-03-13
|
* refactor: integer functions, optimize asserts #34112Lewis Russell2026-03-12
| | | | | | | | | | | | 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
* docs: api, messages, lsp, trustJustin M. Keyes2026-03-11
| | | | | gen_vimdoc.lua: In prepare for the upcoming release, comment-out the "Experimental" warning for prerelease features.