aboutsummaryrefslogtreecommitdiff
path: root/test/functional/treesitter
Commit message (Collapse)AuthorAge
* feat(treesitter): show which nodes are missing in InspectTreeRiley Bruins2025-02-05
| | | | | | | | Now `:InspectTree` will show missing nodes as e.g. `(MISSING identifier)` or `(MISSING ";")` rather than just `(identifier)` or `";"`. This is doable because the `MISSING` keyword is now valid query syntax. Co-authored-by: Christian Clason <c.clason@uni-graz.at>
* feat(treesitter): allow LanguageTree:is_valid() to accept a rangeRiley Bruins2025-02-02
| | | | | | When given, only that range will be checked for validity rather than the entire tree. This is used in the highlighter to save CPU cycles since we only need to parse a certain region at a time anyway.
* fix(treesitter): nil access when running string parser asyncRiley Bruins2025-02-01
|
* feat(treesitter): support modelines in `query.set()` (#30257)Maria José Solano2025-01-29
|
* build(deps)!: bump tree-sitter to HEAD, wasmtime to v29.0.1 (#32200)Christian Clason2025-01-27
| | | | | Breaking change: `ts_node_child_containing_descendant()` was removed Breaking change: tree-sitter 0.25 (HEAD) required
* test: use temp file #31907Guilherme Soares2025-01-13
|
* feat(treesitter)!: don't parse tree in get_parser() or start()Riley Bruins2025-01-12
| | | | | | | | | | **Problem:** `vim.treesitter.get_parser()` and `vim.treesitter.start()` both parse the tree before returning it. This is problematic because if this is a sync parse, it will stall the editor on large files. If it is an async parse, the functions return stale trees. **Solution:** Remove this parsing side effect and leave it to the user to parse the returned trees, either synchronously or asynchronously.
* feat(treesitter): async parsingRiley Bruins2025-01-12
| | | | | | | | | | | | **Problem:** Parsing can be slow for large files, and it is a blocking operation which can be disruptive and annoying. **Solution:** Provide a function for asynchronous parsing, which accepts a callback to be run after parsing completes. Co-authored-by: Lewis Russell <lewis6991@gmail.com> Co-authored-by: Luuk van Baal <luukvbaal@gmail.com> Co-authored-by: VanaIgr <vanaigranov@gmail.com>
* perf(treesitter): cache queries stronglyRiley Bruins2025-01-12
| | | | | | | | | | **Problem:** Query parsing uses a weak cache which is invalidated frequently **Solution:** Make the cache strong, and invalidate it manually when necessary (that is, when `rtp` is changed or `query.set()` is called) Co-authored-by: Christian Clason <c.clason@uni-graz.at>
* test(treesitter): inspect_tree #31182Guilherme Soares2025-01-08
| | | To prevent #30986 and #31198 regression update inspect_tree tests
* perf(treesitter): don't fetch parser for each fold lineRiley Bruins2025-01-07
| | | | | | | | | | | | | | **Problem:** The treesitter `foldexpr` calls `get_parser()` for each line in the buffer when calculating folds. This can be incredibly slow for buffers where a parser cannot be found (because the result is not cached), and exponentially more so when the user has many `runtimepath`s. **Solution:** Only fetch the parser when it is needed; that is, only when initializing fold data for a buffer. Co-authored-by: Jongwook Choi <wookayin@gmail.com> Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* refactor: split predicates and directivesvanaigr2025-01-06
|
* feat(treesitter): include capture id in return value of ↵Riley Bruins2024-12-11
| | | | | | | | | | | | | | | `get_captures_at_pos()` #30559 **Problem:** Currently, it is difficult to get node(s)-level metadata for a capture returned by `get_captures_at_pos()`. This is because it is stored in `metadata[id]` and we do not have access to the value of `id`, so to get this value we have to iterate over the keys of `metadata`. See [this commit](https://github.com/neovim/neovim/commit/d63622930001b39b12f14112fc3abb55b760c447#diff-8bd4742121c2f359d0345f3c6c253a58220f1a28670cc4e1c957992232059a6cR16). Things would be much simpler if we were given the `id` of the capture so we could use it to just index `metadata` directly. **Solution:** Include `id` in the data returned by `get_captures_at_pos()`
* fix(treesitter): #trim! range for nodes ending at col 0 #31488Riley Bruins2024-12-07
| | | | | | | | | Problem: char-wise folding for `#trim!` ranges are improperly calculated for nodes that end at column 0, due to the way `get_node_text` works. Solution: Add the blank line that `get_node_text` removes for for nodes ending at column 0. Also properly set column positions when performing linewise trims.
* test(treesitter): add a simple testutil fileRiley Bruins2024-12-06
| | | | The util file, for now, just abstracts the common `run_query` function.
* feat(treesitter): #trim! can trim all whitespaceRiley Bruins2024-12-06
| | | | | | | | | | This commit also implements more generic trimming, acting on all whitespace (charwise) rather than just empty lines. It will unblock https://github.com/nvim-treesitter/nvim-treesitter/pull/3442 and allow for properly concealing markdown bullet markers regardless of indent width, e.g.
* test(screen): adjust screen state per stylua #31441luukvbaal2024-12-04
| | | | | | | | | | | | | | | | | | | | | | | | | Before: screen:expect({ | screen:expect({ grid = [[ | grid = [[ {10:>!}a | | line ^1 | {7: }b | | {1:~ }|*4 {10:>>}c | | ]], messages={ { {7: }^ | | content = { { "\ntest\n[O]k: ", 6, 11 } }, {1:~ }|*9 | kind = "confirm" | | } } ]] | }) }) After: screen:expect([[ | screen:expect({ {10:>!}a | | grid = [[ {7: }b | | line ^1 | {10:>>}c | | {1:~ }|*4 {7: }^ | | ]], {1:~ }|*9 | messages = { { | | content = { { "\ntest\n[O]k: ", 6, 11 } }, ]]) | kind = "confirm" | } }, | })
* test(treesitter): global highlight definitions and fold test #31407luukvbaal2024-12-02
| | | | Add test for foldtext= highlighting. Change file to global highlight definitions while at it.
* fix(treesitter): update queriesChristian Clason2024-11-22
|
* fix(tests): needing two calls to setup a screen is cringebfredl2024-11-14
| | | | | | | | | | Before calling "attach" a screen object is just a dummy container for (row, col) values whose purpose is to be sent as part of the "attach" function call anyway. Just create the screen in an attached state directly. Keep the complete (row, col, options) config together. It is still completely valid to later detach and re-attach as needed, including to another session.
* fix(treesitter): show proper node name error messagesRiley Bruins2024-11-13
| | | | | | | | | | | **Problem:** Currently node names with non-alphanumeric, non underscore/hyphen characters (only possible with anonymous nodes) are not given a proper error message. See tree-sitter issue 3892 for more details. **Solution:** Apply a different scanning logic to anonymous nodes to correctly identify the entire node name (i.e., up until the final double quote)
* fix(treesitter): mark supertype nodes as namedRiley Bruins2024-10-12
| | | | | | | | | | | **Problem:** Tree-sitter 0.24.0 introduced a new symbol type to denote supertype nodes (`TSSymbolTypeSupertype`). Now, `language.inspect()` (and the query `omnifunc`) return supertype symbols, but with double quotes around them. **Solution:** Mark a symbol as "named" based on it *not* being an anonymous node, rather than checking that it is a regular node (which a supertype also is not).
* fix(treesitter): remove duplicate symbol names in language.inspect()Riley Bruins2024-10-11
| | | | | | | | | | | | | | | | | **Problems:** - `vim.treesitter.language.inspect()` returns duplicate symbol names, sometimes up to 6 of one kind in the case of `markdown` - The list-like `symbols` table can have holes and is thus not even a valid msgpack table anyway, mentioned in a test **Solution:** Return symbols as a map, rather than a list, where field names are the names of the symbol. The boolean value associated with the field encodes whether or not the symbol is named. Note that anonymous nodes are surrounded with double quotes (`"`) to prevent potential collisions with named counterparts that have the same identifier.
* feat(treesitter): introduce child_with_descendant()Riley Bruins2024-10-11
| | | | | | This commit also marks `child_containing_descendant()` as deprecated (per upstream's documentation), and uses `child_with_descendant()` in its place. Minimum required tree-sitter version will now be `0.24`.
* feat(treesitter)!: use return values in `language.add()`Christian Clason2024-09-29
| | | | | | | | | Problem: No clear way to check whether parsers are available for a given language. Solution: Make `language.add()` return `true` if a parser was successfully added and `nil` otherwise. Use explicit `assert` instead of relying on thrown errors.
* fix(treesitter): suppress get_parser warnings via opts.errorRiley Bruins2024-09-28
|
* feat(defaults): pretty :help headings #30544Justin M. Keyes2024-09-27
| | | | | | | | | | | | | | Problem: Headings in :help do not stand out visually. Solution: Define a non-standard `@markup.heading.1.delimiter` group and special-case it in `highlight_group.c`. FUTURE: This is a cheap workaround until we have #25718 which will enable: - fully driven by `vimdoc/highlights.scm` instead of using highlight tricks (`guibg=bg guifg=bg guisp=fg`) - better support of "cterm" ('notermguicolors')
* perf(treesitter): use `child_containing_descendant()` in `is_ancestor()`Riley Bruins2024-09-25
| | | | | | | | **Problem:** `is_ancestor()` uses a slow, bottom-up parent lookup which has performance pitfalls detailed in #28512. **Solution:** Take `is_ancestor()` from $O(n^2)$ to $O(n)$ by incorporating the use of the `child_containing_descendant()` function
* test: support upvalues in exec_luaLewis Russell2024-09-21
|
* feat(treesitter): start moving get_parser to return nil #30313Riley Bruins2024-09-13
| | | | | | | | | | | | | | | | | | | **Problem:** `vim.treesitter.get_parser` will throw an error if no parser can be found. - This means the caller is responsible for wrapping it in a `pcall`, which is easy to forget - It also makes it slightly harder to potentially memoize `get_parser` in the future - It's a bit unintuitive since many other `get_*` style functions conventionally return `nil` if no object is found (e.g. `get_node`, `get_lang`, `query.get`, etc.) **Solution:** Return `nil` if no parser can be found or created - This requires a function signature change, and some new assertions in places where the parser will always (or should always) be found. - This commit starts by making this change internally, since it is breaking. Eventually it will be rolled out to the public API.
* feat(treesitter)!: default to correct behavior for quantified captures (#30193)Gregory Anders2024-09-01
| | | | | | | | | | | | For context, see https://github.com/neovim/neovim/pull/24738. Before that PR, Nvim did not correctly handle captures with quantifiers. That PR made the correct behavior opt-in to minimize breaking changes, with the intention that the correct behavior would eventually become the default. Users can still opt-in to the old (incorrect) behavior for now, but this option will eventually be removed completely. BREAKING CHANGE: Any plugin which uses `Query:iter_matches()` must update their call sites to expect an array of nodes in the `match` table, rather than a single node.
* feat(treesitter): add support for wasm parsersLewis Russell2024-08-26
| | | | | | | | | | | | | | | | | | | | Problem: Installing treesitter parser is hard (harder than climbing to heaven). Solution: Add optional support for wasm parsers with `wasmtime`. Notes: * Needs to be enabled by setting `ENABLE_WASMTIME` for tree-sitter and Neovim. Build with `make CMAKE_EXTRA_FLAGS=-DENABLE_WASMTIME=ON DEPS_CMAKE_FLAGS=-DENABLE_WASMTIME=ON` * Adds optional Rust (obviously) and C11 dependencies. * Wasmtime comes with a lot of features that can negatively affect Neovim performance due to library and symbol table size. Make sure to build with minimal features and full LTO. * To reduce re-compilation times, install `sccache` and build with `RUSTC_WRAPPER=<path/to/sccache> make ...`
* test: allow exec_lua to handle functionsLewis Russell2024-08-02
| | | | | | | | | | | Problem: Tests have lots of exec_lua calls which input blocks of code provided as unformatted strings. Solution: Teach exec_lua how to handle functions.
* feat(treesitter): allow get_node to return anonymous nodesRiley Bruins2024-07-29
| | | | | Adds a new field `include_anonymous` to the `get_node` options to allow anonymous nodes to be returned.
* feat(treesitter): add node_for_range functionRiley Bruins2024-07-29
| | | | | | This is identical to `named_node_for_range` except that it includes anonymous nodes. This maintains consistency in the API because we already have `descendant_for_range` and `named_descendant_for_range`.
* fix(runtime): sync bundled treesitter queriesChristian Clason2024-07-24
|
* build(deps): drop unused bundled bash, python parsers and queriesChristian Clason2024-07-09
| | | | | | | | | | Problem: Neovim bundles treesitter parsers for bash and python but does not use them by default. This dilutes the messaging about the bundled parsers being required for functionality or reasonable out-of-the-box experience. It also increases the risk of query incompatibilities for no gain. Solution: Stop bundling bash and python parser and queries.
* fix(treesitter): display fields for anonymous nodes in :InspectTreeRiley Bruins2024-07-05
|
* test: starting and stopping treesitter highlight (#29546)zeertzjq2024-07-03
|
* fix(treesitter): ensure syntaxset augroup exists (#29542)zeertzjq2024-07-03
| | | | | | | | Problem: Error when calling vim.treesitter.start() and vim.treesitter.stop() in init.lua. Solution: Ensure syntaxset augroup exists after loading synload.vim.
* perf(treesitter): remove unnecessary foldexpr loopRiley Bruins2024-06-24
| | | | | | Instead of looping over all captured nodes, just take the end range from the last node in the list. This uses the fact that nodes returned by iter_matches are ordered by their range (earlier to later).
* fix(treesitter): do not modify highlight state for _on_spell_navLuuk van Baal2024-06-24
| | | | | | | | Problem: Treesitter highlighter clears the already populated highlight state when performing spell checking while drawing a smoothscrolled topline. Solution: Save and restore the highlight state in the highlighter's _on_spell_nav callback.
* fix(treesitter): don't open fold when o/O adds a line below #28709Jaehwang Jung2024-06-20
| | | | | | | | | | | Problem: `o`-ing on a folded line opens the fold, because the new line gets the fold level from the above line (level '='), which extends the fold to the new line. `O` has a similar problem when run on the line below a fold. Solution: Use -1 for the added line to get the lower level from the above/below line.
* fix(treesitter): find buffer in multiple windows #28922Guilherme Soares2024-05-27
| | | | | | | | | | | | | Problem: 1. When interacting with multiple :InspectTree and the source buffer windows there is a high chance of errors due to the window ids not being updated and validated. 2. Not all InspectTree windows were closed when the source buffer was closed. Solution: 1. Update InspectTree window id on `CursorMoved` event and validate source buffer window id before trying to navigate to it. 2. Close all InspectTree windows
* perf(treesitter): use child_containing_descendant() in has-ancestor? (#28512)vanaigr2024-05-16
| | | | | | | | | Problem: `has-ancestor?` is O(n²) for the depth of the tree since it iterates over each of the node's ancestors (bottom-up), and each ancestor takes O(n) time. This happens because tree-sitter's nodes don't store their parent nodes, and the tree is searched (top-down) each time a new parent is requested. Solution: Make use of new `ts_node_child_containing_descendant()` in tree-sitter v0.22.6 (which is now the minimum required version) to rewrite the `has-ancestor?` predicate in C to become O(n). For a sample file, decreases the time taken by `has-ancestor?` from 360ms to 6ms.
* fix(treesitter): allow optional directive captures (#28664)Riley Bruins2024-05-14
|
* fix(treesitter): make tests for memoize more robustbfredl2024-04-29
| | | | | | | | | | | | Instead of painfully messing with timing to determine if queries were reparsed, we can simply keep a counter next to the call to ts_query_new Also memoization had a hidden dependency on the garbage collection of the the key, a hash value which never is kept around in memory. this was done intentionally as the hash does not capture all relevant state for the query (external included files) even if actual query objects still would be reachable in memory. To make the test fully deterministic in CI, we explicitly control GC.
* fix(treesitter): enforce lowercase language names (#28546)Christian Clason2024-04-28
| | | | | | | | | | | * fix(treesitter): enforce lowercase language names Problem: On case-insensitive file systems (e.g., macOS), `has_parser` will return `true` for uppercase aliases, which will then try to inject the uppercase language unsuccessfully. Solution: Enforce and assume parser names to be lowercase when resolving language names.
* test: improve test conventionsdundargoc2024-04-23
| | | | | | | | | Specifically, functions that are run in the context of the test runner are put in module `test/testutil.lua` while the functions that are run in the context of the test session are put in `test/functional/testnvim.lua`. Closes https://github.com/neovim/neovim/issues/27004.
* feat(treesitter): handle quantified fold capturesRiley Bruins2024-04-20
|