summaryrefslogtreecommitdiff
path: root/lua/nvim-treesitter/utils.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/nvim-treesitter/utils.lua')
-rw-r--r--lua/nvim-treesitter/utils.lua162
1 files changed, 37 insertions, 125 deletions
diff --git a/lua/nvim-treesitter/utils.lua b/lua/nvim-treesitter/utils.lua
index 9d591eab..9dc5d17b 100644
--- a/lua/nvim-treesitter/utils.lua
+++ b/lua/nvim-treesitter/utils.lua
@@ -1,69 +1,10 @@
--- Utils collection for nvim-treesitter
local api = vim.api
-local parsers = require'nvim-treesitter.parsers'
-local locals = require'nvim-treesitter.locals'
+local fn = vim.fn
+local luv = vim.loop
+local ts = vim.treesitter
local M = {}
---- Gets the smallest expression containing the current cursor position
-function M.expression_at_point(bufnr, lang)
- local bufnr = bufnr or api.nvim_get_current_buf()
- local lang = lang or api.nvim_buf_get_option(bufnr, 'ft')
-
- local parser = parsers.get_parser(bufnr, lang)
- if not parser then return end
-
- local tsroot = parser:parse():root()
- if not tsroot then return end
-
- local curwin = api.nvim_get_current_win()
-
- if api.nvim_win_get_buf(curwin) == bufnr then
- local cursor = vim.api.nvim_win_get_cursor(curwin)
- local current_node = tsroot:named_descendant_for_range(cursor[1] - 1, cursor[2], cursor[1] - 1, cursor[2])
- return current_node
- end
-end
-
---- Gets the actual text content of a node
--- @param node the node to get the text from
--- @param bufnr the buffer containing the node
--- @return list of lines of text of the node
-function M.get_node_text(node, bufnr)
- local bufnr = bufnr or api.nvim_get_current_buf()
- if not node then return {} end
-
- -- We have to remember that end_col is end-exclusive
- local start_row, start_col, end_row, end_col = node:range()
- if start_row ~= end_row then
- local lines = api.nvim_buf_get_lines(bufnr, start_row, end_row+1, false)
- lines[1] = string.sub(lines[1], start_col+1)
- lines[#lines] = string.sub(lines[#lines], 1, end_col)
- return lines
- else
- local line = api.nvim_buf_get_lines(bufnr, start_row, start_row+1, true)[1]
- return { string.sub(line, start_col+1, end_col) }
- end
-end
-
---- Determines wether a node is the parent of another
--- @param dest the possible parent
--- @param source the possible child node
-function M.is_parent(dest, source)
- if not (dest and source) then return false end
-
- local current = source
- while current ~= nil do
- if current == dest then
- return true
- end
-
- current = current:parent()
- end
-
- return false
-end
-
function M.setup_commands(mod, commands)
for command_name, def in pairs(commands) do
local call_fn = string.format("lua require'nvim-treesitter.%s'.commands.%s.run(<f-args>)", mod, command_name)
@@ -77,79 +18,50 @@ function M.setup_commands(mod, commands)
end
end
---- Gets the smallest scope which contains @param node
-function M.smallest_containing_scope(node, bufnr)
- local bufnr = bufnr or api.nvim_get_current_buf()
-
- local root = parsers.get_parser(bufnr):parse():root()
- if not node then return root end
-
- local scopes = locals.get_scopes(bufnr)
- local current = node
- while current ~= nil and not vim.tbl_contains(scopes, current) do
- current = current:parent()
+function M.get_package_path()
+ for _, path in pairs(api.nvim_list_runtime_paths()) do
+ if string.match(path, '.*/nvim%-treesitter') then
+ return path
+ end
end
- return current or root
+ return nil, 'Plugin runtime path not found.'
end
---- Get next node with same parent
--- @param node node
--- @param allow_switch_parents allow switching parents if last node
--- @param allow_next_parent allow next parent if last node and next parent without children
-function M.get_next_node(node, allow_switch_parents, allow_next_parent)
- local destination_node
- local parent = node:parent()
+function M.get_cache_dir()
+ local home = fn.get(fn.environ(), 'HOME')
+ local xdg_cache = fn.get(fn.environ(), 'XDG_CACHE_HOME')
- if parent then
- local found_pos = 0
- for i = 0,parent:named_child_count()-1,1 do
- if parent:named_child(i) == node then
- found_pos = i
- break
- end
- end
- if parent:named_child_count() > found_pos + 1 then
- destination_node = parent:named_child(found_pos + 1)
- elseif allow_switch_parents then
- local next_node = M.get_next_node(node:parent())
- if next_node and next_node:named_child_count() > 0 then
- destination_node = next_node:named_child(0)
- elseif next_node and allow_next_parent then
- destination_node = next_node
- end
- end
+ if xdg_cache == 0 then
+ xdg_cache = home .. '/.cache'
+ end
+
+ if luv.fs_access(xdg_cache, 'RW') then
+ return xdg_cache
+ elseif luv.fs_access('/tmp', 'RW') then
+ return '/tmp'
end
- return destination_node
+
+ return nil, 'Invalid cache rights, $XDG_CACHE_HOME or /tmp should be read/write'
end
---- Get previous node with same parent
--- @param node node
--- @param allow_switch_parents allow switching parents if first node
--- @param allow_previous_parent allow previous parent if first node and previous parent without children
-function M.get_previous_node(node, allow_switch_parents, allow_previous_parent)
- local destination_node
- local parent = node:parent()
- if parent then
- local found_pos = 0
- for i = 0,parent:named_child_count()-1,1 do
- if parent:named_child(i) == node then
- found_pos = i
- break
- end
+function M.has_parser(lang)
+ local lang = lang or api.nvim_buf_get_option(0, 'filetype')
+ return #api.nvim_get_runtime_file('parser/' .. lang .. '.so', false) > 0
+end
+
+function M.get_parser(bufnr, lang)
+ if M.has_parser() then
+ local buf = bufnr or api.nvim_get_current_buf()
+ local lang = lang or api.nvim_buf_get_option(buf, 'ft')
+ if not M[buf] then
+ M[buf] = {}
+ end
+ if not M[buf][lang] then
+ M[buf][lang] = ts.get_parser(buf, lang)
end
- if 0 < found_pos then
- destination_node = parent:named_child(found_pos - 1)
- elseif allow_switch_parents then
- local previous_node = M.get_previous_node(node:parent())
- if previous_node and previous_node:named_child_count() > 0 then
- destination_node = previous_node:named_child(previous_node:named_child_count() - 1)
- elseif previous_node and allow_previous_parent then
- destination_node = previous_node
- end
- end
+ return M[buf][lang]
end
- return destination_node
end
return M