mirror of
https://github.com/neovim/neovim.git
synced 2025-10-21 09:12:07 +00:00
lsp: make tagstack smarter motion-wise (#12262)
This commit prevents two things regarding the tagstack and jumping to locations: - Pushing the same item twice in a row - Pushing an item where the destination is the same as the source Both prevent having to press CTRL-T additional times just to pop items that don't make the cursor move.
This commit is contained in:
@@ -914,6 +914,23 @@ function M.make_floating_popup_options(width, height, opts)
|
||||
}
|
||||
end
|
||||
|
||||
local function _should_add_to_tagstack(new_item)
|
||||
local stack = vim.fn.gettagstack()
|
||||
|
||||
-- Check if we're at the bottom of the tagstack.
|
||||
if stack.curidx <= 1 then return true end
|
||||
|
||||
local top_item = stack.items[stack.curidx-1]
|
||||
|
||||
-- Check if the item at the top of the tagstack is exactly the
|
||||
-- same as the one we want to push.
|
||||
if top_item.tagname ~= new_item.tagname then return true end
|
||||
for i, v in ipairs(top_item.from) do
|
||||
if v ~= new_item.from[i] then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Jumps to a location.
|
||||
---
|
||||
--@param location (`Location`|`LocationLink`)
|
||||
@@ -922,22 +939,33 @@ function M.jump_to_location(location)
|
||||
-- location may be Location or LocationLink
|
||||
local uri = location.uri or location.targetUri
|
||||
if uri == nil then return end
|
||||
local bufnr = vim.uri_to_bufnr(uri)
|
||||
-- Save position in jumplist
|
||||
vim.cmd "normal! m'"
|
||||
|
||||
-- Push a new item into tagstack
|
||||
local from = {vim.fn.bufnr('%'), vim.fn.line('.'), vim.fn.col('.'), 0}
|
||||
local items = {{tagname=vim.fn.expand('<cword>'), from=from}}
|
||||
vim.fn.settagstack(vim.fn.win_getid(), {items=items}, 't')
|
||||
local from_bufnr = vim.fn.bufnr('%')
|
||||
local from = {from_bufnr, vim.fn.line('.'), vim.fn.col('.'), 0}
|
||||
local item = {tagname=vim.fn.expand('<cword>'), from=from}
|
||||
|
||||
--- Jump to new location (adjusting for UTF-16 encoding of characters)
|
||||
local bufnr = vim.uri_to_bufnr(uri)
|
||||
api.nvim_set_current_buf(bufnr)
|
||||
api.nvim_buf_set_option(0, 'buflisted', true)
|
||||
local range = location.range or location.targetSelectionRange
|
||||
local row = range.start.line
|
||||
local col = get_line_byte_from_position(0, range.start)
|
||||
-- This prevents the tagstack to be filled with items that provide
|
||||
-- no motion when CTRL-T is pressed because they're both the source
|
||||
-- and the destination.
|
||||
local motionless =
|
||||
bufnr == from_bufnr and
|
||||
row+1 == from[2] and col+1 == from[3]
|
||||
if not motionless and _should_add_to_tagstack(item) then
|
||||
local winid = vim.fn.win_getid()
|
||||
local items = {item}
|
||||
vim.fn.settagstack(winid, {items=items}, 't')
|
||||
end
|
||||
|
||||
-- Jump to new location
|
||||
api.nvim_win_set_cursor(0, {row + 1, col})
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
Reference in New Issue
Block a user