From 5948aba886e8aad26043402684cf85c307813c4d Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Sat, 22 Aug 2020 20:46:40 +0200 Subject: feat(refactor.navigation): add navigation.goto_{next,previous}_usage --- lua/nvim-treesitter/configs.lua | 4 +++- lua/nvim-treesitter/refactor/navigation.lua | 25 ++++++++++++++++++++----- lua/nvim-treesitter/textobjects/move.lua | 16 ++-------------- lua/nvim-treesitter/ts_utils.lua | 20 ++++++++++++++++++++ lua/nvim-treesitter/utils.lua | 8 ++++++++ 5 files changed, 53 insertions(+), 20 deletions(-) (limited to 'lua') diff --git a/lua/nvim-treesitter/configs.lua b/lua/nvim-treesitter/configs.lua index 51d982c79..5fba72348 100644 --- a/lua/nvim-treesitter/configs.lua +++ b/lua/nvim-treesitter/configs.lua @@ -75,7 +75,9 @@ local builtin_modules = { is_supported = queries.has_locals, keymaps = { goto_definition = "gnd", - list_definitions = "gnD" + list_definitions = "gnD", + goto_next_usage = "", + goto_previous_usage = "", } } }, diff --git a/lua/nvim-treesitter/refactor/navigation.lua b/lua/nvim-treesitter/refactor/navigation.lua index 185cce89f..98ef37802 100644 --- a/lua/nvim-treesitter/refactor/navigation.lua +++ b/lua/nvim-treesitter/refactor/navigation.lua @@ -12,14 +12,10 @@ function M.goto_definition(bufnr) local bufnr = bufnr or api.nvim_get_current_buf() local node_at_point = ts_utils.get_node_at_cursor() - utils.set_jump() - if not node_at_point then return end local definition, _ = locals.find_definition(node_at_point, bufnr) - local start_row, start_col, _ = definition:start() - - api.nvim_win_set_cursor(0, { start_row + 1, start_col }) + ts_utils.goto_node(definition) end function M.list_definitions(bufnr) @@ -48,6 +44,25 @@ function M.list_definitions(bufnr) api.nvim_command('copen') end +function M.goto_adjacent_usage(bufnr, delta) + local bufnr = bufnr or api.nvim_get_current_buf() + local node_at_point = ts_utils.get_node_at_cursor() + if not node_at_point then return end + + local def_node, scope = locals.find_definition(node_at_point, bufnr) + local usages = locals.find_usages(def_node, scope, bufnr) + + local index = utils.index_of(usages, node_at_point) + if not index then return end + + local target_index = (index + delta + #usages - 1) % #usages + 1 + ts_utils.goto_node(usages[target_index]) + return usages[target_index] +end + +function M.goto_next_usage(bufnr) return M.goto_adjacent_usage(bufnr, 1) end +function M.goto_previous_usage(bufnr) return M.goto_adjacent_usage(bufnr, -1) end + function M.attach(bufnr) local config = configs.get_module('refactor.navigation') diff --git a/lua/nvim-treesitter/textobjects/move.lua b/lua/nvim-treesitter/textobjects/move.lua index 8cfb71188..1dd2f132d 100644 --- a/lua/nvim-treesitter/textobjects/move.lua +++ b/lua/nvim-treesitter/textobjects/move.lua @@ -1,7 +1,6 @@ -local utils = require'nvim-treesitter.utils' +local ts_utils = require'nvim-treesitter.ts_utils' local shared = require'nvim-treesitter.textobjects.shared' local attach = require'nvim-treesitter.textobjects.attach' -local api = vim.api local M = {} @@ -9,18 +8,7 @@ function M.goto_adjacent(query_string, forward, start, same_parent, overlapping_ local bufnr, _, node = shared.textobject_at_point(query_string) local adjacent = shared.get_adjacent(forward, node, query_string, same_parent, overlapping_range_ok, bufnr) - if adjacent then - utils.set_jump() - - local adjacent_textobject_range = {adjacent:range()} - local position - if start then - position = { adjacent_textobject_range[1] + 1, adjacent_textobject_range[2] } - else - position = { adjacent_textobject_range[3] + 1, adjacent_textobject_range[4] } - end - api.nvim_win_set_cursor(api.nvim_get_current_win(), position) - end + ts_utils.goto_node(adjacent, not start) end -- luacheck: push ignore 631 diff --git a/lua/nvim-treesitter/ts_utils.lua b/lua/nvim-treesitter/ts_utils.lua index 52fdd0fc8..6647cc968 100644 --- a/lua/nvim-treesitter/ts_utils.lua +++ b/lua/nvim-treesitter/ts_utils.lua @@ -276,4 +276,24 @@ function M.swap_nodes(node_or_range1, node_or_range2, bufnr, cursor_to_second) end end +function M.goto_node(node, goto_end, avoid_set_jump) + if not node then return end + if not avoid_set_jump then + utils.set_jump() + end + local range = {node:range()} + local position + if not goto_end then + position = { range[1], range[2] } + else + -- ranges are exclusive: -1 character! + if range[4] == 0 then + position = { range[3] - 1, -1 } + else + position = { range[3], range[4] - 1 } + end + end + api.nvim_win_set_cursor(0, { position[1] + 1, position[2] }) +end + return M diff --git a/lua/nvim-treesitter/utils.lua b/lua/nvim-treesitter/utils.lua index 101bfafab..c080c2a91 100644 --- a/lua/nvim-treesitter/utils.lua +++ b/lua/nvim-treesitter/utils.lua @@ -67,4 +67,12 @@ function M.set_jump() vim.cmd "normal! m'" end +function M.index_of(tbl, obj) + for i, o in ipairs(tbl) do + if o == obj then + return i + end + end +end + return M -- cgit v1.2.3-70-g09d2