diff options
Diffstat (limited to 'lua/nvim-treesitter/utils.lua')
| -rw-r--r-- | lua/nvim-treesitter/utils.lua | 162 |
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 |
