treesitter(docs): update and refresh docs

This commit is contained in:
Thomas Vigouroux
2020-07-16 17:17:42 +02:00
parent 613068071e
commit 18c0e77528
5 changed files with 70 additions and 25 deletions

View File

@@ -574,6 +574,14 @@ retained for the lifetime of a buffer but this is subject to change. A plugin
should keep a reference to the parser object as long as it wants incremental should keep a reference to the parser object as long as it wants incremental
updates. updates.
Parser files *treesitter-parsers*
Parsers are the heart of tree-sitter. They are libraries that tree-sitter will
search for in the `parsers` runtime directory.
For a parser to be available for a given language, there must be a file named
`{lang}.so` within the parser directory.
Parser methods *lua-treesitter-parser* Parser methods *lua-treesitter-parser*
tsparser:parse() *tsparser:parse()* tsparser:parse() *tsparser:parse()*
@@ -593,9 +601,9 @@ shouldn't be done directly in the change callback anyway as they will be very
frequent. Rather a plugin that does any kind of analysis on a tree should use frequent. Rather a plugin that does any kind of analysis on a tree should use
a timer to throttle too frequent updates. a timer to throttle too frequent updates.
tsparser:set_included_ranges(ranges) *tsparser:set_included_ranges()* tsparser:set_included_ranges({ranges}) *tsparser:set_included_ranges()*
Changes the ranges the parser should consider. This is used for Changes the ranges the parser should consider. This is used for
language injection. `ranges` should be of the form (all zero-based): > language injection. {ranges} should be of the form (all zero-based): >
{ {
{start_node, end_node}, {start_node, end_node},
... ...
@@ -617,15 +625,15 @@ tsnode:parent() *tsnode:parent()*
tsnode:child_count() *tsnode:child_count()* tsnode:child_count() *tsnode:child_count()*
Get the node's number of children. Get the node's number of children.
tsnode:child(N) *tsnode:child()* tsnode:child({index}) *tsnode:child()*
Get the node's child at the given index, where zero represents the Get the node's child at the given {index}, where zero represents the
first child. first child.
tsnode:named_child_count() *tsnode:named_child_count()* tsnode:named_child_count() *tsnode:named_child_count()*
Get the node's number of named children. Get the node's number of named children.
tsnode:named_child(N) *tsnode:named_child()* tsnode:named_child({index}) *tsnode:named_child()*
Get the node's named child at the given index, where zero represents Get the node's named child at the given {index}, where zero represents
the first named child. the first named child.
tsnode:start() *tsnode:start()* tsnode:start() *tsnode:start()*
@@ -661,12 +669,12 @@ tsnode:has_error() *tsnode:has_error()*
tsnode:sexpr() *tsnode:sexpr()* tsnode:sexpr() *tsnode:sexpr()*
Get an S-expression representing the node as a string. Get an S-expression representing the node as a string.
tsnode:descendant_for_range(start_row, start_col, end_row, end_col) tsnode:descendant_for_range({start_row}, {start_col}, {end_row}, {end_col})
*tsnode:descendant_for_range()* *tsnode:descendant_for_range()*
Get the smallest node within this node that spans the given range of Get the smallest node within this node that spans the given range of
(row, column) positions (row, column) positions
tsnode:named_descendant_for_range(start_row, start_col, end_row, end_col) tsnode:named_descendant_for_range({start_row}, {start_col}, {end_row}, {end_col})
*tsnode:named_descendant_for_range()* *tsnode:named_descendant_for_range()*
Get the smallest named node within this node that spans the given Get the smallest named node within this node that spans the given
range of (row, column) positions range of (row, column) positions
@@ -677,17 +685,17 @@ Tree-sitter queries are supported, with some limitations. Currently, the only
supported match predicate is `eq?` (both comparing a capture against a string supported match predicate is `eq?` (both comparing a capture against a string
and two captures against each other). and two captures against each other).
vim.treesitter.parse_query(lang, query) vim.treesitter.parse_query({lang}, {query})
*vim.treesitter.parse_query(()* *vim.treesitter.parse_query()*
Parse the query as a string. (If the query is in a file, the caller Parse {query} as a string. (If the query is in a file, the caller
should read the contents into a string before calling). should read the contents into a string before calling).
query:iter_captures(node, bufnr, start_row, end_row) query:iter_captures({node}, {bufnr}, {start_row}, {end_row})
*query:iter_captures()* *query:iter_captures()*
Iterate over all captures from all matches inside a `node`. Iterate over all captures from all matches inside {node}.
`bufnr` is needed if the query contains predicates, then the caller {bufnr} is needed if the query contains predicates, then the caller
must ensure to use a freshly parsed tree consistent with the current must ensure to use a freshly parsed tree consistent with the current
text of the buffer. `start_row` and `end_row` can be used to limit text of the buffer. {start_row} and {end_row} can be used to limit
matches inside a row range (this is typically used with root node matches inside a row range (this is typically used with root node
as the node, i e to get syntax highlight matches in the current as the node, i e to get syntax highlight matches in the current
viewport) viewport)
@@ -704,7 +712,7 @@ query:iter_captures(node, bufnr, start_row, end_row)
... use the info here ... ... use the info here ...
end end
< <
query:iter_matches(node, bufnr, start_row, end_row) query:iter_matches({node}, {bufnr}, {start_row}, {end_row})
*query:iter_matches()* *query:iter_matches()*
Iterate over all matches within a node. The arguments are the same as Iterate over all matches within a node. The arguments are the same as
for |query:iter_captures()| but the iterated values are different: for |query:iter_captures()| but the iterated values are different:

View File

@@ -10,6 +10,12 @@ local parsers = {}
local Parser = {} local Parser = {}
Parser.__index = Parser Parser.__index = Parser
--- Parses the buffer if needed and returns a tree.
--
-- Calling this will call the on_changedtree callbacks if the tree has changed.
--
-- @returns An up to date tree
-- @returns If the tree changed with this call, the changed ranges
function Parser:parse() function Parser:parse()
if self.valid then if self.valid then
return self.tree return self.tree
@@ -40,6 +46,9 @@ function Parser:_on_lines(bufnr, changed_tick, start_row, old_stop_row, stop_row
end end
end end
--- Sets the included ranges for the current parser
--
-- @param ranges A table of nodes that will be used as the ranges the parser should include.
function Parser:set_included_ranges(ranges) function Parser:set_included_ranges(ranges)
self._parser:set_included_ranges(ranges) self._parser:set_included_ranges(ranges)
-- The buffer will need to be parsed again later -- The buffer will need to be parsed again later

View File

@@ -7,9 +7,6 @@ local ts_hs_ns = a.nvim_create_namespace("treesitter_hl")
-- These are conventions defined by tree-sitter, though it -- These are conventions defined by tree-sitter, though it
-- needs to be user extensible also. -- needs to be user extensible also.
-- TODO(bfredl): this is very much incomplete, we will need to
-- go through a few tree-sitter provided queries and decide
-- on translations that makes the most sense.
TSHighlighter.hl_map = { TSHighlighter.hl_map = {
["error"] = "Error", ["error"] = "Error",
@@ -112,13 +109,10 @@ function TSHighlighter:set_query(query)
query = vim.treesitter.get_query(self.parser.lang, 'highlights') query = vim.treesitter.get_query(self.parser.lang, 'highlights')
if query == nil then if query == nil then
a.err_writeln("No highlights.scm query found for " .. self.parser.lang) a.nvim_err_writeln("No highlights.scm query found for " .. self.parser.lang)
if query == nil then
query = vim.treesitter.parse_query(self.parser.lang, "") query = vim.treesitter.parse_query(self.parser.lang, "")
end end
end end
end
self.query = query self.query = query

View File

@@ -2,6 +2,12 @@ local a = vim.api
local M = {} local M = {}
--- Asserts that the provided language is installed, and optionnaly provide a path for the parser
--
-- Parsers are searched in the `parser` runtime directory.
--
-- @param lang The language the parser should parse
-- @param path Optionnal path the parser is located at
function M.require_language(lang, path) function M.require_language(lang, path)
if vim._ts_has_language(lang) then if vim._ts_has_language(lang) then
return true return true
@@ -11,13 +17,18 @@ function M.require_language(lang, path)
local paths = a.nvim_get_runtime_file(fname, false) local paths = a.nvim_get_runtime_file(fname, false)
if #paths == 0 then if #paths == 0 then
-- TODO(bfredl): help tag? -- TODO(bfredl): help tag?
error("no parser for '"..lang.."' language") error("no parser for '"..lang.."' language, see :help treesitter-parsers")
end end
path = paths[1] path = paths[1]
end end
vim._ts_add_language(path, lang) vim._ts_add_language(path, lang)
end end
--- Inspects the provided language.
--
-- Inspecting provides some useful informations on the language like node names, ...
--
-- @param lang The language.
function M.inspect_language(lang) function M.inspect_language(lang)
M.require_language(lang) M.require_language(lang)
return vim._ts_inspect_language(lang) return vim._ts_inspect_language(lang)

View File

@@ -67,6 +67,11 @@ local predicate_handlers = {
end, end,
} }
--- Adds a new predicates to be used in queries
--
-- @param name the name of the predicate, without leading #
-- @param handler the handler function to be used
-- signature will be (match, pattern, bufnr, predicate)
function M.add_predicate(name, handler) function M.add_predicate(name, handler)
if predicate_handlers[name] then if predicate_handlers[name] then
a.nvim_err_writeln("It is recomended to not overwrite predicates.") a.nvim_err_writeln("It is recomended to not overwrite predicates.")
@@ -93,6 +98,15 @@ function Query:match_preds(match, pattern, bufnr)
return true return true
end end
--- Iterates of the captures of self on a given range.
--
-- @param node The node under witch the search will occur
-- @param buffer The source buffer to search
-- @param start The starting line of the search
-- @param stop The stoping line of the search (end-exclusive)
--
-- @returns The matching capture id
-- @returns The captured node
function Query:iter_captures(node, bufnr, start, stop) function Query:iter_captures(node, bufnr, start, stop)
if bufnr == 0 then if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf() bufnr = vim.api.nvim_get_current_buf()
@@ -112,6 +126,15 @@ function Query:iter_captures(node, bufnr, start, stop)
return iter return iter
end end
--- Iterates of the matches of self on a given range.
--
-- @param node The node under witch the search will occur
-- @param buffer The source buffer to search
-- @param start The starting line of the search
-- @param stop The stoping line of the search (end-exclusive)
--
-- @returns The matching pattern id
-- @returns The matching match
function Query:iter_matches(node, bufnr, start, stop) function Query:iter_matches(node, bufnr, start, stop)
if bufnr == 0 then if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf() bufnr = vim.api.nvim_get_current_buf()