mirror of
https://github.com/nvim-treesitter/nvim-treesitter.git
synced 2026-07-05 21:10:15 -04:00
feat!: drop modules, general refactor and cleanup
This commit is contained in:
parent
310f0925ec
commit
692b051b09
1247 changed files with 6096 additions and 9074 deletions
|
|
@ -1,29 +1,46 @@
|
|||
-- Functions to handle locals
|
||||
-- Locals are a generalization of definition and scopes
|
||||
-- its the way nvim-treesitter uses to "understand" the code
|
||||
-- it's the way nvim-treesitter uses to "understand" the code
|
||||
|
||||
local queries = require "nvim-treesitter.query"
|
||||
local ts_utils = require "nvim-treesitter.ts_utils"
|
||||
local ts = vim.treesitter
|
||||
local query = require('nvim-treesitter.query')
|
||||
local api = vim.api
|
||||
local ts = vim.treesitter
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.collect_locals(bufnr)
|
||||
return queries.collect_group_results(bufnr, "locals")
|
||||
local function get_named_children(node)
|
||||
local nodes = {} ---@type TSNode[]
|
||||
for i = 0, node:named_child_count() - 1, 1 do
|
||||
nodes[i + 1] = node:named_child(i)
|
||||
end
|
||||
return nodes
|
||||
end
|
||||
|
||||
---@param node TSNode
|
||||
---@return TSNode result
|
||||
local function get_root_for_node(node)
|
||||
local parent = node
|
||||
local result = node
|
||||
|
||||
while parent ~= nil do
|
||||
result = parent
|
||||
parent = result:parent()
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
-- Iterates matches from a locals query file.
|
||||
-- @param bufnr the buffer
|
||||
-- @param root the root node
|
||||
function M.iter_locals(bufnr, root)
|
||||
return queries.iter_group_results(bufnr, "locals", root)
|
||||
return query.iter_group_results(bufnr, 'locals', root)
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
---@return any
|
||||
function M.get_locals(bufnr)
|
||||
return queries.get_matches(bufnr, "locals")
|
||||
function M.collect_locals(bufnr)
|
||||
return query.collect_group_results(bufnr, 'locals')
|
||||
end
|
||||
|
||||
-- Creates unique id for a node based on text and range
|
||||
|
|
@ -32,17 +49,17 @@ end
|
|||
---@return string: a string id
|
||||
function M.get_definition_id(scope, node_text)
|
||||
-- Add a valid starting character in case node text doesn't start with a valid one.
|
||||
return table.concat({ "k", node_text or "", scope:range() }, "_")
|
||||
return table.concat({ 'k', node_text or '', scope:range() }, '_')
|
||||
end
|
||||
|
||||
function M.get_definitions(bufnr)
|
||||
local locals = M.get_locals(bufnr)
|
||||
local locals = M.collect_locals(bufnr)
|
||||
|
||||
local defs = {}
|
||||
|
||||
for _, loc in ipairs(locals) do
|
||||
if loc["local"]["definition"] then
|
||||
table.insert(defs, loc["local"]["definition"])
|
||||
if loc['local.definition'] then
|
||||
table.insert(defs, loc['local.definition'])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -50,13 +67,13 @@ function M.get_definitions(bufnr)
|
|||
end
|
||||
|
||||
function M.get_scopes(bufnr)
|
||||
local locals = M.get_locals(bufnr)
|
||||
local locals = M.collect_locals(bufnr)
|
||||
|
||||
local scopes = {}
|
||||
|
||||
for _, loc in ipairs(locals) do
|
||||
if loc["local"]["scope"] and loc["local"]["scope"].node then
|
||||
table.insert(scopes, loc["local"]["scope"].node)
|
||||
if loc['local.scope'] and loc['local.scope'].node then
|
||||
table.insert(scopes, loc['local.scope'].node)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -64,13 +81,13 @@ function M.get_scopes(bufnr)
|
|||
end
|
||||
|
||||
function M.get_references(bufnr)
|
||||
local locals = M.get_locals(bufnr)
|
||||
local locals = M.collect_locals(bufnr)
|
||||
|
||||
local refs = {}
|
||||
|
||||
for _, loc in ipairs(locals) do
|
||||
if loc["local"]["reference"] and loc["local"]["reference"].node then
|
||||
table.insert(refs, loc["local"]["reference"].node)
|
||||
if loc['local.reference'] and loc['local.reference'].node then
|
||||
table.insert(refs, loc['local.reference'].node)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -103,7 +120,7 @@ function M.iter_scope_tree(node, bufnr)
|
|||
return
|
||||
end
|
||||
|
||||
local scope = M.containing_scope(last_node, bufnr, false) or ts_utils.get_root_for_node(node)
|
||||
local scope = M.containing_scope(last_node, bufnr, false) or get_root_for_node(node)
|
||||
|
||||
last_node = scope:parent()
|
||||
|
||||
|
|
@ -117,8 +134,8 @@ end
|
|||
function M.get_local_nodes(local_def)
|
||||
local result = {}
|
||||
|
||||
M.recurse_local_nodes(local_def, function(def, _node, kind)
|
||||
table.insert(result, vim.tbl_extend("keep", { kind = kind }, def))
|
||||
M.recurse_local_nodes(local_def, function(def, _, kind)
|
||||
table.insert(result, vim.tbl_extend('keep', { kind = kind }, def))
|
||||
end)
|
||||
|
||||
return result
|
||||
|
|
@ -135,7 +152,7 @@ end
|
|||
---@param full_match? string The full match path to append to
|
||||
---@param last_match? string The last match
|
||||
function M.recurse_local_nodes(local_def, accumulator, full_match, last_match)
|
||||
if type(local_def) ~= "table" then
|
||||
if type(local_def) ~= 'table' then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -143,11 +160,36 @@ function M.recurse_local_nodes(local_def, accumulator, full_match, last_match)
|
|||
accumulator(local_def, local_def.node, full_match, last_match)
|
||||
else
|
||||
for match_key, def in pairs(local_def) do
|
||||
M.recurse_local_nodes(def, accumulator, full_match and (full_match .. "." .. match_key) or match_key, match_key)
|
||||
M.recurse_local_nodes(
|
||||
def,
|
||||
accumulator,
|
||||
full_match and (full_match .. '.' .. match_key) or match_key,
|
||||
match_key
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---Memoize a function using hash_fn to hash the arguments.
|
||||
---@generic F: function
|
||||
---@param fn F
|
||||
---@param hash_fn fun(...): any
|
||||
---@return F
|
||||
local function memoize(fn, hash_fn)
|
||||
local cache = setmetatable({}, { __mode = 'kv' }) ---@type table<any,any>
|
||||
|
||||
return function(...)
|
||||
local key = hash_fn(...)
|
||||
if cache[key] == nil then
|
||||
local v = fn(...) ---@type any
|
||||
cache[key] = v ~= nil and v or vim.NIL
|
||||
end
|
||||
|
||||
local v = cache[key]
|
||||
return v ~= vim.NIL and v or nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Get a single dimension table to look definition nodes.
|
||||
-- Keys are generated by using the range of the containing scope and the text of the definition node.
|
||||
-- This makes looking up a definition for a given scope a simple key lookup.
|
||||
|
|
@ -161,7 +203,7 @@ end
|
|||
--
|
||||
---@param bufnr integer: the buffer
|
||||
---@return table result: a table for looking up definitions
|
||||
M.get_definitions_lookup_table = ts_utils.memoize_by_buf_tick(function(bufnr)
|
||||
M.get_definitions_lookup_table = memoize(function(bufnr)
|
||||
local definitions = M.get_definitions(bufnr)
|
||||
local result = {}
|
||||
|
||||
|
|
@ -178,6 +220,8 @@ M.get_definitions_lookup_table = ts_utils.memoize_by_buf_tick(function(bufnr)
|
|||
end
|
||||
|
||||
return result
|
||||
end, function(bufnr)
|
||||
return tostring(bufnr)
|
||||
end)
|
||||
|
||||
-- Gets all the scopes of a definition based on the scope type
|
||||
|
|
@ -196,10 +240,10 @@ function M.get_definition_scopes(node, bufnr, scope_type)
|
|||
|
||||
-- Definition is valid for the containing scope
|
||||
-- and the containing scope of that scope
|
||||
if scope_type == "parent" then
|
||||
if scope_type == 'parent' then
|
||||
scope_count = 2
|
||||
-- Definition is valid in all parent scopes
|
||||
elseif scope_type == "global" then
|
||||
elseif scope_type == 'global' then
|
||||
scope_count = nil
|
||||
end
|
||||
|
||||
|
|
@ -235,7 +279,7 @@ function M.find_definition(node, bufnr)
|
|||
end
|
||||
end
|
||||
|
||||
return node, ts_utils.get_root_for_node(node), nil
|
||||
return node, get_root_for_node(node), nil
|
||||
end
|
||||
|
||||
-- Finds usages of a node in a given scope.
|
||||
|
|
@ -250,12 +294,15 @@ function M.find_usages(node, scope_node, bufnr)
|
|||
return {}
|
||||
end
|
||||
|
||||
local scope_node = scope_node or ts_utils.get_root_for_node(node)
|
||||
scope_node = scope_node or get_root_for_node(node)
|
||||
local usages = {}
|
||||
|
||||
for match in M.iter_locals(bufnr, scope_node) do
|
||||
match = match["local"]
|
||||
if match.reference and match.reference.node and ts.get_node_text(match.reference.node, bufnr) == node_text then
|
||||
if
|
||||
match.reference
|
||||
and match.reference.node
|
||||
and ts.get_node_text(match.reference.node, bufnr) == node_text
|
||||
then
|
||||
local def_node, _, kind = M.find_definition(match.reference.node, bufnr)
|
||||
|
||||
if kind == nil or def_node == node then
|
||||
|
|
@ -272,8 +319,8 @@ end
|
|||
---@param allow_scope? boolean
|
||||
---@return TSNode|nil
|
||||
function M.containing_scope(node, bufnr, allow_scope)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local allow_scope = allow_scope == nil or allow_scope == true
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
allow_scope = allow_scope == nil or allow_scope == true
|
||||
|
||||
local scopes = M.get_scopes(bufnr)
|
||||
if not node or not scopes then
|
||||
|
|
@ -301,7 +348,7 @@ function M.nested_scope(node, cursor_pos)
|
|||
local col = cursor_pos.col ---@type integer
|
||||
local scope = M.containing_scope(node)
|
||||
|
||||
for _, child in ipairs(ts_utils.get_named_children(scope)) do
|
||||
for _, child in ipairs(get_named_children(scope)) do
|
||||
local row_, col_ = child:start()
|
||||
if vim.tbl_contains(scopes, child) and ((row_ + 1 == row and col_ > col) or row_ + 1 > row) then
|
||||
return child
|
||||
|
|
@ -318,6 +365,9 @@ function M.next_scope(node)
|
|||
end
|
||||
|
||||
local scope = M.containing_scope(node)
|
||||
if not scope then
|
||||
return
|
||||
end
|
||||
|
||||
local parent = scope:parent()
|
||||
if not parent then
|
||||
|
|
@ -325,7 +375,7 @@ function M.next_scope(node)
|
|||
end
|
||||
|
||||
local is_prev = true
|
||||
for _, child in ipairs(ts_utils.get_named_children(parent)) do
|
||||
for _, child in ipairs(get_named_children(parent)) do
|
||||
if child == scope then
|
||||
is_prev = false
|
||||
elseif not is_prev and vim.tbl_contains(scopes, child) then
|
||||
|
|
@ -345,6 +395,9 @@ function M.previous_scope(node)
|
|||
end
|
||||
|
||||
local scope = M.containing_scope(node)
|
||||
if not scope then
|
||||
return
|
||||
end
|
||||
|
||||
local parent = scope:parent()
|
||||
if not parent then
|
||||
|
|
@ -352,7 +405,7 @@ function M.previous_scope(node)
|
|||
end
|
||||
|
||||
local is_prev = true
|
||||
local children = ts_utils.get_named_children(parent)
|
||||
local children = get_named_children(parent)
|
||||
for i = #children, 1, -1 do
|
||||
if children[i] == scope then
|
||||
is_prev = false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue