aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter/languagetree.lua
Commit message (Collapse)AuthorAge
* fix(treesitter): remove redundant on_bytes callback #31041luukvbaal2024-11-16
| | | | | | | Problem: Treesitter highlighter implements an on_bytes callback that just re-marks a buffer range for redraw. The edit that prompted the callback will already have done that. Solution: Remove redundant on_bytes callback from the treesitter highlighter module.
* 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.
* 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.
* docs(treesitter): generate inline docs for `Range`sYi Ming2024-08-06
| | | | | | | | docs(treesitter): in-place parameter description docs(treesitter): remove internal type names docs(treesitter): add missing private annotation
* 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`.
* refactor(lua): improve type annotationsLewis Russell2024-06-11
|
* feat: remove deprecated featuresdundargoc2024-05-16
| | | | | | | | | | | | | | | | | | | Remove following functions: - vim.lsp.util.extract_completion_items - vim.lsp.util.get_progress_messages - vim.lsp.util.parse_snippet() - vim.lsp.util.text_document_completion_list_to_complete_items - LanguageTree:for_each_child - health#report_error - health#report_info - health#report_ok - health#report_start - health#report_warn - vim.health.report_error - vim.health.report_info - vim.health.report_ok - vim.health.report_start - vim.health.report_warn
* docs: newsJustin M. Keyes2024-05-15
| | | | Set dev_xx.txt help files to use "flow" layout.
* 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.
* fix(treesitter): use tree range instead of tree root node rangealtermo2024-04-10
|
* feat(treesitter): add `@injection.filename`Christian Clason2024-04-02
| | | | | | | | | | | | | Problem: Injecting languages for file redirects (e.g., in bash) is not possible. Solution: Add `@injection.filename` capture that is piped through `vim.filetype.match({ filename = node_text })`; the resulting filetype (if not `nil`) is then resolved as a language (either directly or through the list maintained via `vim.treesitter.language.register()`). Note: `@injection.filename` is a non-standard capture introduced by Helix; having two editors implement it makes it likely to be upstreamed.
* refactor(lua): type annotationsLewis Russell2024-03-16
|
* fix(treesitter): highlight injections properlyLewis Russell2024-03-14
| | | | | `on_line_impl` doesn't highlight single lines, so using pattern indexes to offset priority doesn't work.
* docs: support inline markdownLewis Russell2024-03-09
| | | | | | - Tags are now created with `[tag]()` - References are now created with `[tag]` - Code spans are no longer wrapped
* refactor(types): more fixes (2)Lewis Russell2024-03-06
|
* docs: improve/add documentation of Lua typesLewis Russell2024-03-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - Added `@inlinedoc` so single use Lua types can be inlined into the functions docs. E.g. ```lua --- @class myopts --- @inlinedoc --- --- Documentation for some field --- @field somefield integer --- @param opts myOpts function foo(opts) end ``` Will be rendered as ``` foo(opts) Parameters: - {opts} (table) Object with the fields: - somefield (integer) Documentation for some field ``` - Marked many classes with with `@nodoc` or `(private)`. We can eventually introduce these when we want to.
* feat(docs): replace lua2dox.luaLewis Russell2024-02-27
| | | | | | | | | | | | | | | | | | | | | | | | | | Problem: The documentation flow (`gen_vimdoc.py`) has several issues: - it's not very versatile - depends on doxygen - doesn't work well with Lua code as it requires an awkward filter script to convert it into pseudo-C. - The intermediate XML files and filters makes it too much like a rube goldberg machine. Solution: Re-implement the flow using Lua, LPEG and treesitter. - `gen_vimdoc.py` is now replaced with `gen_vimdoc.lua` and replicates a portion of the logic. - `lua2dox.lua` is gone! - No more XML files. - Doxygen is now longer used and instead we now use: - LPEG for comment parsing (see `scripts/luacats_grammar.lua` and `scripts/cdoc_grammar.lua`). - LPEG for C parsing (see `scripts/cdoc_parser.lua`) - Lua patterns for Lua parsing (see `scripts/luacats_parser.lua`). - Treesitter for Markdown parsing (see `scripts/text_utils.lua`). - The generated `runtime/doc/*.mpack` files have been removed. - `scripts/gen_eval_files.lua` now instead uses `scripts/cdoc_parser.lua` directly. - Text wrapping is implemented in `scripts/text_utils.lua` and appears to produce more consistent results (the main contributer to the diff of this change).
* fix(treesitter): correctly handle query quantifiers (#24738)Thomas Vigouroux2024-02-16
| | | | | | | | | | | | | | | | | | | Query patterns can contain quantifiers (e.g. (foo)+ @bar), so a single capture can map to multiple nodes. The iter_matches API can not handle this situation because the match table incorrectly maps capture indices to a single node instead of to an array of nodes. The match table should be updated to map capture indices to an array of nodes. However, this is a massively breaking change, so must be done with a proper deprecation period. `iter_matches`, `add_predicate` and `add_directive` must opt-in to the correct behavior for backward compatibility. This is done with a new "all" option. This option will become the default and removed after the 0.10 release. Co-authored-by: Christian Clason <c.clason@uni-graz.at> Co-authored-by: MDeiml <matthias@deiml.net> Co-authored-by: Gregory Anders <greg@gpanders.com>
* fix(treesitter): validate language alias for injectionsChristian Clason2024-01-18
| | | | | | | | Problem: Parsed language annotations can be random garbage so `nvim_get_runtime_file` throws an error. Solution: Validate that `alias` is a valid language name before trying to find a parser for it.
* fix(treesitter): outdated highlight due to tree with outdated regionJaehwang Jung2023-12-24
| | | | | | | | | | | | | Problem: A region managed by an injected parser may shrink after re-running the injection query. If the updated region goes out of the range to be parsed, then the corresponding tree will remain outdated, possibly retaining the nodes that shouldn't exist anymore. This results in outdated highlights. Solution: Re-parse an invalid tree if its region intersects the range to be parsed.
* fix(treesitter): don't invalidate parser when discovering injectionsDmytro Soltys2023-11-27
| | | | | | | | | When parsing with a range, languagetree looks up injections and adds them if needed. This explicitly invalidates parser, making `is_valid` report `false` both when including and excluding children. This is an attempt to describe desired behaviour of `is_valid` in tests, with what ended up being a single line change to satisfy them.
* fix(languagetree): don't treat unparsed nodes as occupying full rangeL Lllvvuu2023-09-22
| | | | | | | | | | | | | | | | | | | | | | | | | This is incorrect in the following scenario: 1. The language tree is Lua > Vim > Lua. 2. An edit simultaneously wipes out the `_regions` of all nodes, while taking the Vim injection off-screen. 3. The Vim injection is not re-parsed, so the child Lua `_regions` is still `nil`. 4. The child Lua is assumed, incorrectly, to occupy the whole document. 5. This causes the injections to be parsed again, resulting in Lua > Vim > Lua > Vim. 6. Now, by the same process, Vim ends up with its range assumed over the whole document. Now the parse is broken and results in broken highlighting and poor performance. It should be fine to instead treat an unparsed node as occupying nothing (i.e. effectively non-existent). Since, either: - The parent was just parsed, hence defining `_regions` - The parent was not just parsed, in which case this node doesn't need to be parsed either. Also, the name `has_regions` is confusing; it seems to simply mean the opposite of "root" or "full_document". However, this PR does not touch it.
* feat(lua): add vim.func._memoizeLewis Russell2023-09-20
| | | | | | | | | | | | | | | Memoizes a function, using a custom function to hash the arguments. Private for now until: - There are other places in the codebase that could benefit from this (e.g. LSP), but might require other changes to accommodate. - Invalidation of the cache needs to be controllable. Using weak tables is an acceptable invalidation policy, but it shouldn't be the only one. - I don't think the story around `hash_fn` is completely thought out. We may be able to have a good default hash_fn by hashing each argument, so basically a better 'concat'.
* fix(treesitter): _trees may not be list-likeJaehwang Jung2023-09-17
| | | | | | | | | | | Problem: With incremental injection parsing, injected languages' parsers parse only the relevant regions and stores the result in _trees with the index of the corresponding region. Therefore, there can be holes in _trees. Solution: * Use generic table functions where appropriate. * Fix type annotations and docs.
* fix(treesitter): properly combine injection.combined regionsJaehwang Jung2023-09-16
| | | | | | | | | Problem: It doesn't make much sense to flatten each region (= list of ranges). This coincidentally worked for region with a single range. Solution: Custom function for combining regions.
* fix(languagetree): apply `resolve_lang` to `metadata['injection.language']`L Lllvvuu2023-09-16
| | | | | | | | | | | | | `resolve_lang` is applied to `@injection.language` when it's supplied as a capture: https://github.com/neovim/neovim/blob/f5953edbac14febce9d4f8a3c35bdec1eae26fbe/runtime/lua/vim/treesitter/languagetree.lua#L766-L768 If we want to support `metadata['injection.language']` (as per #22518 and [tree-sitter upstream](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection)) then the behavior should be consistent. Fixes: nvim-treesitter/nvim-treesitter#4918
* docs: replace <pre> with ``` (#25136)Gregory Anders2023-09-14
|
* refactor(treesitter): deprecate for_each_child #25118LW2023-09-14
| | | | | | | The name for_each_child is misleading and caused bugs. After #25111, #25115, there are no more usages of `for_each_child` in Nvim. In the future if we want to restore this functionality we can consider a generalized vim.traverse(node, key, visitor) function.
* fix(treesitter): remove more double recursionLewis Russell2023-09-12
| | | | Do not call `for_each_child` in functions that are already recursive.
* fix(languagetree): remove double recursion in LanguageTree:parseL Lllvvuu2023-09-12
| | | | | | | | | | | | | | | | `LanguageTree:parse` is recursive, and calls `LanguageTree:for_each_child`, which is also recursive. That means that, starting from the third level (child of child of root), nodes will be parsed twice. Which then means that if the tree is N layers deep, there will be ~2^N parses even if the branching factor is 1. Now, why was the tree deepening with each character inserted? And why did this only regress in #24647? These are mysteries for another time. Fixes: #25104
* feat(treesitter): add 'injection.self' and 'injection.parent'Amaan Qureshi2023-08-24
| | | | Co-authored-by: ObserverOfTime <chronobserver@disroot.org>
* fix(treesitter)!: remove deprecated legacy injection formatChristian Clason2023-08-14
|
* fix(treesitter): logger memory leakLewis Russell2023-08-13
|
* feat(treesitter)!: incremental injection parsingLewis Russell2023-08-12
| | | | | | | | | | | | | | | | | | | | | Problem: Treesitter highlighting is slow for large files with lots of injections. Solution: Only parse injections we are going to render during a redraw cycle. --- - `LanguageTree:parse()` will no longer parse injections by default and now requires an explicit range argument to be passed. - `TSHighlighter` now parses injections incrementally during on_win callbacks for the line range being rendered. - Plugins which require certain injections to be parsed must run `parser:parse({ start_row, end_row })` before using the tree.
* feat(treesitter): add injection language fallback (#24659)Christian Clason2023-08-11
| | | | | | | | | | | | * feat(treesitter): add injection language fallback Problem: injection languages are often specified via aliases (e.g., filetype or in upper case), requiring custom directives. Solution: include lookup logic (try as parser name, then filetype, then lowercase) in LanguageTree itself and remove `#inject-language` directive. Co-authored-by: Lewis Russell <me@lewisr.dev>
* fix(treesitter): make sure injections don't return empty ranges (#24595)Lewis Russell2023-08-07
| | | | | | | | | | | | | | | | | | | | When an injection has not set include children, make sure not to add the injection if no ranges are determined. This could happen when there is an injection with a child that has the same range as itself. e.g. consider this Makefile snippet ```make foo: $(VAR) ``` Line 2 has an injection for bash and a make variable reference. If include-children isn't set (default), then there is no range on line 2 to inject since the variable reference needs to be excluded. This caused the language tree to return an empty range, which the parser now interprets to mean the full buffer. This caused makefiles to have completely broken highlighting.
* docs(lua): more improvements (#24387)Lewis Russell2023-07-18
| | | | | | | | | | | | | | | | | * docs(lua): teach lua2dox how to table * docs(lua): teach gen_vimdoc.py about local functions No more need to mark local functions with @private * docs(lua): mention @nodoc and @meta in dev-lua-doc * fixup! Co-authored-by: Justin M. Keyes <justinkz@gmail.com> --------- Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* fix(treesitter): handle empty region when logging (#24173)Jaehwang Jung2023-06-27
|
* feat(lua): rename vim.loop -> vim.uv (#22846)Lewis Russell2023-06-03
|
* fix: function was renamed (#23772)Matthieu Coudron2023-05-26
|
* feat(treesitter): improved logging (#23638)Lewis Russell2023-05-17
| | | | | | - Add bindings to Treesitter ts_parser_set_logger and ts_parser_logger - Add logfile with path STDPATH('log')/treesitter.c - Rework existing LanguageTree loggin to use logfile - Begin implementing log levels for vim.g.__ts_debug
* docs: small fixesdundargoc2023-05-13
| | | | | | | | | Co-authored-by: Christian Clason <c.clason@uni-graz.at> Co-authored-by: Gregory Anders <greg@gpanders.com> Co-authored-by: HiPhish <hiphish@posteo.de> Co-authored-by: Julio B <julio.bacel@gmail.com> Co-authored-by: T727 <74924917+T-727@users.noreply.github.com> Co-authored-by: camoz <camoz@users.noreply.github.com> Co-authored-by: champignoom <66909116+champignoom@users.noreply.github.com>
* fix(treesitter): foldexpr tweaksLewis Russell2023-05-01
| | | Some small general fixes found working on developing async parsing.
* fix(treesitter): redraw added/removed injections properly (#23287)Lewis Russell2023-04-30
| | | | | | When injections are added or removed make sure to: - invoke 'changedtree' callbacks for when new trees are added. - invoke 'changedtree' callbacks for when trees are invalidated - redraw regions when languagetree children are removed
* fix(treesitter): do not track ranges of the root tree (#22912)Lewis Russell2023-04-06
| | | Fixes #22911
* refactor: rename local API alias from a to apiLewis Russell2023-04-05
| | | | | | | | Problem: Codebase inconsistently binds vim.api onto a or api. Solution: Use api everywhere. a as an identifier is too short to have at the module level.
* refactor(treesitter): delegate region calculation to treesitter (#22576)Lewis Russell2023-04-04
|
* feat: add `vim.treesitter.language.get_filetypes()` (#22643)Lewis Russell2023-03-30
|
* feat(treesitter)!: deprecate top level indexes to modules (#22761)Lewis Russell2023-03-24
| | | | | | | | | | | | | | | | | The following top level Treesitter functions have been moved: - vim.treesitter.inspect_language() -> vim.treesitter.language.inspect() - vim.treesitter.get_query_files() -> vim.treesitter.query.get_files() - vim.treesitter.set_query() -> vim.treesitter.query.set() - vim.treesitter.query.set_query() -> vim.treesitter.query.set() - vim.treesitter.get_query() -> vim.treesitter.query.get() - vim.treesitter.query.get_query() -> vim.treesitter.query.get() - vim.treesitter.parse_query() -> vim.treesitter.query.parse() - vim.treesitter.query.parse_query() -> vim.treesitter.query.parse() - vim.treesitter.add_predicate() -> vim.treesitter.query.add_predicate() - vim.treesitter.add_directive() -> vim.treesitter.query.add_directive() - vim.treesitter.list_predicates() -> vim.treesitter.query.list_predicates() - vim.treesitter.list_directives() -> vim.treesitter.query.list_directives() - vim.treesitter.query.get_range() -> vim.treesitter.get_range() - vim.treesitter.query.get_node_text() -> vim.treesitter.get_node_text()
* fix(treesitter): annotationsLewis Russell2023-03-23
| | | | | | - Begin using `@package` in place of `@private` for functions that are accessed internally but outside their defined class. - Rename Node -> TSP.Node