docs(treesitter): generate TSNode, TSTree docs #30643

**Problem:** The documentation for `TSNode` and `TSTree` methods is
incomplete from the LSP perspective. This is because they are written
directly to the vimdoc, rather than in Lua and generated to vimdoc.

**Solution:** Migrate the docs to Lua and generate them into the vimdoc.
This requires breaking up the `treesitter/_meta.lua` file into a
directory with a few different modules.

This commit also makes the vimdoc generator slightly more robust with
regard to sections that have multiple help tags (e.g. `*one* *two*`)
This commit is contained in:
Riley Bruins
2024-10-03 16:57:19 -07:00
committed by GitHub
parent 385fbfb3e7
commit f62728cd80
6 changed files with 598 additions and 268 deletions

View File

@@ -1,119 +0,0 @@
---@meta
error('Cannot require a meta file')
---@class TSNode: userdata
---@field id fun(self: TSNode): string
---@field tree fun(self: TSNode): TSTree
---@field range fun(self: TSNode, include_bytes: false?): integer, integer, integer, integer
---@field range fun(self: TSNode, include_bytes: true): integer, integer, integer, integer, integer, integer
---@field start fun(self: TSNode): integer, integer, integer
---@field end_ fun(self: TSNode): integer, integer, integer
---@field type fun(self: TSNode): string
---@field symbol fun(self: TSNode): integer
---@field named fun(self: TSNode): boolean
---@field missing fun(self: TSNode): boolean
---@field extra fun(self: TSNode): boolean
---@field child_count fun(self: TSNode): integer
---@field named_child_count fun(self: TSNode): integer
---@field child fun(self: TSNode, index: integer): TSNode?
---@field named_child fun(self: TSNode, index: integer): TSNode?
---@field descendant_for_range fun(self: TSNode, start_row: integer, start_col: integer, end_row: integer, end_col: integer): TSNode?
---@field named_descendant_for_range fun(self: TSNode, start_row: integer, start_col: integer, end_row: integer, end_col: integer): TSNode?
---@field parent fun(self: TSNode): TSNode?
---@field child_containing_descendant fun(self: TSNode, descendant: TSNode): TSNode?
---@field next_sibling fun(self: TSNode): TSNode?
---@field prev_sibling fun(self: TSNode): TSNode?
---@field next_named_sibling fun(self: TSNode): TSNode?
---@field prev_named_sibling fun(self: TSNode): TSNode?
---@field named_children fun(self: TSNode): TSNode[]
---@field has_changes fun(self: TSNode): boolean
---@field has_error fun(self: TSNode): boolean
---@field sexpr fun(self: TSNode): string
---@field equal fun(self: TSNode, other: TSNode): boolean
---@field iter_children fun(self: TSNode): fun(): TSNode, string
---@field field fun(self: TSNode, name: string): TSNode[]
---@field byte_length fun(self: TSNode): integer
---@field __has_ancestor fun(self: TSNode, node_types: string[]): boolean
local TSNode = {}
---@alias TSLoggerCallback fun(logtype: 'parse'|'lex', msg: string)
---@class TSParser: userdata
---@field parse fun(self: TSParser, tree: TSTree?, source: integer|string, include_bytes: boolean): TSTree, (Range4|Range6)[]
---@field reset fun(self: TSParser)
---@field included_ranges fun(self: TSParser, include_bytes: boolean?): integer[]
---@field set_included_ranges fun(self: TSParser, ranges: (Range6|TSNode)[])
---@field set_timeout fun(self: TSParser, timeout: integer)
---@field timeout fun(self: TSParser): integer
---@field _set_logger fun(self: TSParser, lex: boolean, parse: boolean, cb: TSLoggerCallback)
---@field _logger fun(self: TSParser): TSLoggerCallback
---@class TSTree: userdata
---@field root fun(self: TSTree): TSNode
---@field edit fun(self: TSTree, _: integer, _: integer, _: integer, _: integer, _: integer, _: integer, _: integer, _: integer, _:integer)
---@field copy fun(self: TSTree): TSTree
---@field included_ranges fun(self: TSTree, include_bytes: true): Range6[]
---@field included_ranges fun(self: TSTree, include_bytes: false): Range4[]
---@class TSQuery: userdata
---@field inspect fun(self: TSQuery): TSQueryInfo
---@class (exact) TSQueryInfo
---@field captures string[]
---@field patterns table<integer, (integer|string)[][]>
--- @param lang string
--- @return table
vim._ts_inspect_language = function(lang) end
---@return integer
vim._ts_get_language_version = function() end
--- @param path string
--- @param lang string
--- @param symbol_name? string
vim._ts_add_language_from_object = function(path, lang, symbol_name) end
--- @param path string
--- @param lang string
vim._ts_add_language_from_wasm = function(path, lang) end
---@return integer
vim._ts_get_minimum_language_version = function() end
---@param lang string Language to use for the query
---@param query string Query string in s-expr syntax
---@return TSQuery
vim._ts_parse_query = function(lang, query) end
---@param lang string
---@return TSParser
vim._create_ts_parser = function(lang) end
--- @class TSQueryMatch: userdata
--- @field captures fun(self: TSQueryMatch): table<integer,TSNode[]>
local TSQueryMatch = {}
--- @return integer match_id
--- @return integer pattern_index
function TSQueryMatch:info() end
--- @class TSQueryCursor: userdata
--- @field remove_match fun(self: TSQueryCursor, id: integer)
local TSQueryCursor = {}
--- @return integer capture
--- @return TSNode captured_node
--- @return TSQueryMatch match
function TSQueryCursor:next_capture() end
--- @return TSQueryMatch match
function TSQueryCursor:next_match() end
--- @param node TSNode
--- @param query TSQuery
--- @param start integer?
--- @param stop integer?
--- @param opts? { max_start_depth?: integer, match_limit?: integer}
--- @return TSQueryCursor
function vim._create_ts_querycursor(node, query, start, stop, opts) end

View File

@@ -0,0 +1,78 @@
---@meta
-- luacheck: no unused args
error('Cannot require a meta file')
---@alias TSLoggerCallback fun(logtype: 'parse'|'lex', msg: string)
---@class TSParser: userdata
---@field parse fun(self: TSParser, tree: TSTree?, source: integer|string, include_bytes: boolean): TSTree, (Range4|Range6)[]
---@field reset fun(self: TSParser)
---@field included_ranges fun(self: TSParser, include_bytes: boolean?): integer[]
---@field set_included_ranges fun(self: TSParser, ranges: (Range6|TSNode)[])
---@field set_timeout fun(self: TSParser, timeout: integer)
---@field timeout fun(self: TSParser): integer
---@field _set_logger fun(self: TSParser, lex: boolean, parse: boolean, cb: TSLoggerCallback)
---@field _logger fun(self: TSParser): TSLoggerCallback
---@class TSQuery: userdata
---@field inspect fun(self: TSQuery): TSQueryInfo
---@class (exact) TSQueryInfo
---@field captures string[]
---@field patterns table<integer, (integer|string)[][]>
--- @param lang string
--- @return table
vim._ts_inspect_language = function(lang) end
---@return integer
vim._ts_get_language_version = function() end
--- @param path string
--- @param lang string
--- @param symbol_name? string
vim._ts_add_language_from_object = function(path, lang, symbol_name) end
--- @param path string
--- @param lang string
vim._ts_add_language_from_wasm = function(path, lang) end
---@return integer
vim._ts_get_minimum_language_version = function() end
---@param lang string Language to use for the query
---@param query string Query string in s-expr syntax
---@return TSQuery
vim._ts_parse_query = function(lang, query) end
---@param lang string
---@return TSParser
vim._create_ts_parser = function(lang) end
--- @class TSQueryMatch: userdata
--- @field captures fun(self: TSQueryMatch): table<integer,TSNode[]>
local TSQueryMatch = {} -- luacheck: no unused
--- @return integer match_id
--- @return integer pattern_index
function TSQueryMatch:info() end
--- @class TSQueryCursor: userdata
--- @field remove_match fun(self: TSQueryCursor, id: integer)
local TSQueryCursor = {} -- luacheck: no unused
--- @return integer capture
--- @return TSNode captured_node
--- @return TSQueryMatch match
function TSQueryCursor:next_capture() end
--- @return TSQueryMatch match
function TSQueryCursor:next_match() end
--- @param node TSNode
--- @param query TSQuery
--- @param start integer?
--- @param stop integer?
--- @param opts? { max_start_depth?: integer, match_limit?: integer}
--- @return TSQueryCursor
function vim._create_ts_querycursor(node, query, start, stop, opts) end

View File

@@ -0,0 +1,185 @@
---@meta
-- luacheck: no unused args
error('Cannot require a meta file')
--- @brief A "treesitter node" represents one specific element of the parsed contents of a buffer,
--- which can be captured by a |Query| for, e.g., highlighting. It is a |userdata| reference to an
--- object held by the treesitter library.
---
--- An instance `TSNode` of a treesitter node supports the following methods.
---@nodoc
---@class TSNode: userdata
---@field named_children fun(self: TSNode): TSNode[]
---@field __has_ancestor fun(self: TSNode, node_types: string[]): boolean
local TSNode = {} -- luacheck: no unused
--- Get the node's immediate parent.
--- Prefer |TSNode:child_containing_descendant()|
--- for iterating over the node's ancestors.
--- @return TSNode?
function TSNode:parent() end
--- Get the node's next sibling.
--- @return TSNode?
function TSNode:next_sibling() end
--- Get the node's previous sibling.
--- @return TSNode?
function TSNode:prev_sibling() end
--- Get the node's next named sibling.
--- @return TSNode?
function TSNode:next_named_sibling() end
--- Get the node's previous named sibling.
--- @return TSNode?
function TSNode:prev_named_sibling() end
--- Iterates over all the direct children of {TSNode}, regardless of whether
--- they are named or not.
--- Returns the child node plus the eventual field name corresponding to this
--- child node.
--- @return fun(): TSNode, string
function TSNode:iter_children() end
--- Returns a table of the nodes corresponding to the {name} field.
--- @param name string
--- @return TSNode[]
function TSNode:field(name) end
--- Get the node's number of children.
--- @return integer
function TSNode:child_count() end
--- Get the node's child at the given {index}, where zero represents the first
--- child.
--- @param index integer
--- @return TSNode?
function TSNode:child(index) end
--- Get the node's number of named children.
--- @return integer
function TSNode:named_child_count() end
--- Get the node's named child at the given {index}, where zero represents the
--- first named child.
--- @param index integer
--- @return TSNode?
function TSNode:named_child(index) end
--- Get the node's child that contains {descendant}.
--- @param descendant TSNode
--- @return TSNode?
function TSNode:child_containing_descendant(descendant) end
--- Get the node's start position. Return three values: the row, column and
--- total byte count (all zero-based).
--- @return integer, integer, integer
function TSNode:start() end
--- Get the node's end position. Return three values: the row, column and
--- total byte count (all zero-based).
--- @return integer, integer, integer
function TSNode:end_() end
--- Get the range of the node.
---
--- Return four or six values:
---
--- - start row
--- - start column
--- - start byte (if {include_bytes} is `true`)
--- - end row
--- - end column
--- - end byte (if {include_bytes} is `true`)
--- @param include_bytes boolean?
function TSNode:range(include_bytes) end
--- @nodoc
--- @param include_bytes false?
--- @return integer, integer, integer, integer
function TSNode:range(include_bytes) end
--- @nodoc
--- @param include_bytes true
--- @return integer, integer, integer, integer, integer, integer
function TSNode:range(include_bytes) end
--- Get the node's type as a string.
--- @return string
function TSNode:type() end
--- Get the node's type as a numerical id.
--- @return integer
function TSNode:symbol() end
--- Check if the node is named. Named nodes correspond to named rules in the
--- grammar, whereas anonymous nodes correspond to string literals in the
--- grammar.
--- @return boolean
function TSNode:named() end
--- Check if the node is missing. Missing nodes are inserted by the parser in
--- order to recover from certain kinds of syntax errors.
--- @return boolean
function TSNode:missing() end
--- Check if the node is extra. Extra nodes represent things like comments,
--- which are not required by the grammar but can appear anywhere.
--- @return boolean
function TSNode:extra() end
--- Check if a syntax node has been edited.
--- @return boolean
function TSNode:has_changes() end
--- Check if the node is a syntax error or contains any syntax errors.
--- @return boolean
function TSNode:has_error() end
--- Get an S-expression representing the node as a string.
--- @return string
function TSNode:sexpr() end
--- Get a unique identifier for the node inside its own tree.
---
--- No guarantees are made about this identifier's internal representation,
--- except for being a primitive Lua type with value equality (so not a
--- table). Presently it is a (non-printable) string.
---
--- Note: The `id` is not guaranteed to be unique for nodes from different
--- trees.
--- @return string
function TSNode:id() end
--- Get the |TSTree| of the node.
--- @return TSTree
function TSNode:tree() end
--- Get the smallest node within this node that spans the given range of (row,
--- column) positions
--- @param start_row integer
--- @param start_col integer
--- @param end_row integer
--- @param end_col integer
--- @return TSNode?
function TSNode:descendant_for_range(start_row, start_col, end_row, end_col) end
--- Get the smallest named node within this node that spans the given range of
--- (row, column) positions
--- @param start_row integer
--- @param start_col integer
--- @param end_row integer
--- @param end_col integer
--- @return TSNode?
function TSNode:named_descendant_for_range(start_row, start_col, end_row, end_col) end
--- Check if {node} refers to the same node within the same tree.
--- @param node TSNode
--- @return boolean
function TSNode:equal(node) end
--- Return the number of bytes spanned by this node.
--- @return integer
function TSNode:byte_length() end

View File

@@ -0,0 +1,44 @@
---@meta
-- luacheck: no unused args
error('Cannot require a meta file')
--- @brief A "treesitter tree" represents the parsed contents of a buffer, which can be
--- used to perform further analysis. It is a |userdata| reference to an object
--- held by the treesitter library.
---
--- An instance `TSTree` of a treesitter tree supports the following methods.
---@nodoc
---@class TSTree: userdata
local TSTree = {} -- luacheck: no unused
--- Return the root node of this tree.
---@return TSNode
function TSTree:root() end
-- stylua: ignore
---@param start_byte integer
---@param end_byte_old integer
---@param end_byte_new integer
---@param start_row integer
---@param start_col integer
---@param end_row_old integer
---@param end_col_old integer
---@param end_row_new integer
---@param end_col_new integer
---@nodoc
function TSTree:edit(start_byte, end_byte_old, end_byte_new, start_row, start_col, end_row_old, end_col_old, end_row_new, end_col_new) end
--- Returns a copy of the `TSTree`.
---@return TSTree
function TSTree:copy() end
---@param include_bytes true
---@return Range6[]
---@nodoc
function TSTree:included_ranges(include_bytes) end
---@param include_bytes false
---@return Range4[]
---@nodoc
function TSTree:included_ranges(include_bytes) end