fix(lsp): added a-n, a-p for document highlights and cycling. Closes #3320

This commit is contained in:
Folke Lemaitre 2024-05-26 16:03:13 +02:00
parent c9ab8224f5
commit b3373f3428
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
2 changed files with 38 additions and 28 deletions

View file

@ -3,8 +3,8 @@ local M = {}
---@type LazyKeysLspSpec[]|nil ---@type LazyKeysLspSpec[]|nil
M._keys = nil M._keys = nil
---@alias LazyKeysLspSpec LazyKeysSpec|{has?:string} ---@alias LazyKeysLspSpec LazyKeysSpec|{has?:string, cond?:fun():boolean}
---@alias LazyKeysLsp LazyKeys|{has?:string} ---@alias LazyKeysLsp LazyKeys|{has?:string, cond?:fun():boolean}
---@return LazyKeysLspSpec[] ---@return LazyKeysLspSpec[]
function M.get() function M.get()
@ -40,8 +40,14 @@ function M.get()
desc = "Source Action", desc = "Source Action",
has = "codeAction", has = "codeAction",
}, },
{ "]]", function() LazyVim.lsp.words.jump(vim.v.count1) end, has = "documentHighlight", desc = "Next Reference" }, { "]]", function() LazyVim.lsp.words.jump(vim.v.count1) end, has = "documentHighlight",
{ "[[", function() LazyVim.lsp.words.jump(-vim.v.count1) end, has = "documentHighlight", desc = "Prev Reference" }, desc = "Next Reference", cond = function() return LazyVim.lsp.words.enabled end },
{ "[[", function() LazyVim.lsp.words.jump(-vim.v.count1) end, has = "documentHighlight",
desc = "Prev Reference", cond = function() return LazyVim.lsp.words.enabled end },
{ "<a-n>", function() LazyVim.lsp.words.jump(vim.v.count1, true) end, has = "documentHighlight",
desc = "Next Reference", cond = function() return LazyVim.lsp.words.enabled end },
{ "<a-p>", function() LazyVim.lsp.words.jump(-vim.v.count1, true) end, has = "documentHighlight",
desc = "Prev Reference", cond = function() return LazyVim.lsp.words.enabled end },
} }
if LazyVim.has("inc-rename.nvim") then if LazyVim.has("inc-rename.nvim") then
M._keys[#M._keys + 1] = { M._keys[#M._keys + 1] = {
@ -72,7 +78,7 @@ function M.has(buffer, method)
return false return false
end end
---@return (LazyKeys|{has?:string})[] ---@return LazyKeysLsp[]
function M.resolve(buffer) function M.resolve(buffer)
local Keys = require("lazy.core.handler.keys") local Keys = require("lazy.core.handler.keys")
if not Keys.resolve then if not Keys.resolve then
@ -93,8 +99,12 @@ function M.on_attach(_, buffer)
local keymaps = M.resolve(buffer) local keymaps = M.resolve(buffer)
for _, keys in pairs(keymaps) do for _, keys in pairs(keymaps) do
if not keys.has or M.has(buffer, keys.has) then local has = not keys.has or M.has(buffer, keys.has)
local cond = not (keys.cond == false or ((type(keys.cond) == "function") and not keys.cond()))
if has and cond then
local opts = Keys.opts(keys) local opts = Keys.opts(keys)
opts.cond = nil
opts.has = nil opts.has = nil
opts.silent = opts.silent ~= false opts.silent = opts.silent ~= false
opts.buffer = buffer opts.buffer = buffer

View file

@ -210,8 +210,9 @@ function M.format(opts)
end end
end end
---@alias LspWord {from:{[1]:number, [2]:number}, to:{[1]:number, [2]:number}, current?:boolean} 1-0 indexed ---@alias LspWord {from:{[1]:number, [2]:number}, to:{[1]:number, [2]:number}} 1-0 indexed
M.words = {} M.words = {}
M.words.enabled = false
M.words.ns = vim.api.nvim_create_namespace("vim_lsp_references") M.words.ns = vim.api.nvim_create_namespace("vim_lsp_references")
---@param opts? {enabled?: boolean} ---@param opts? {enabled?: boolean}
@ -220,11 +221,13 @@ function M.words.setup(opts)
if not opts.enabled then if not opts.enabled then
return return
end end
M.words.enabled = true
local handler = vim.lsp.handlers["textDocument/documentHighlight"] local handler = vim.lsp.handlers["textDocument/documentHighlight"]
vim.lsp.handlers["textDocument/documentHighlight"] = function(err, result, ctx, config) vim.lsp.handlers["textDocument/documentHighlight"] = function(err, result, ctx, config)
if not vim.api.nvim_buf_is_loaded(ctx.bufnr) then if not vim.api.nvim_buf_is_loaded(ctx.bufnr) then
return return
end end
vim.lsp.buf.clear_references()
return handler(err, result, ctx, config) return handler(err, result, ctx, config)
end end
@ -233,7 +236,7 @@ function M.words.setup(opts)
group = vim.api.nvim_create_augroup("lsp_word_" .. buf, { clear = true }), group = vim.api.nvim_create_augroup("lsp_word_" .. buf, { clear = true }),
buffer = buf, buffer = buf,
callback = function(ev) callback = function(ev)
if not M.words.at() then if not ({ M.words.get() })[2] then
if ev.event:find("CursorMoved") then if ev.event:find("CursorMoved") then
vim.lsp.buf.clear_references() vim.lsp.buf.clear_references()
else else
@ -245,38 +248,35 @@ function M.words.setup(opts)
end) end)
end end
---@return LspWord[] ---@return LspWord[] words, number? current
function M.words.get() function M.words.get()
local cursor = vim.api.nvim_win_get_cursor(0) local cursor = vim.api.nvim_win_get_cursor(0)
return vim.tbl_map(function(extmark) local current, ret = nil, {} ---@type number?, LspWord[]
local ret = { for _, extmark in ipairs(vim.api.nvim_buf_get_extmarks(0, M.words.ns, 0, -1, { details = true })) do
local w = {
from = { extmark[2] + 1, extmark[3] }, from = { extmark[2] + 1, extmark[3] },
to = { extmark[4].end_row + 1, extmark[4].end_col }, to = { extmark[4].end_row + 1, extmark[4].end_col },
} }
if cursor[1] >= ret.from[1] and cursor[1] <= ret.to[1] and cursor[2] >= ret.from[2] and cursor[2] <= ret.to[2] then ret[#ret + 1] = w
ret.current = true if cursor[1] >= w.from[1] and cursor[1] <= w.to[1] and cursor[2] >= w.from[2] and cursor[2] <= w.to[2] then
end current = #ret
return ret
end, vim.api.nvim_buf_get_extmarks(0, M.words.ns, 0, -1, { details = true }))
end
---@param words? LspWord[]
---@return LspWord?, number?
function M.words.at(words)
for idx, word in ipairs(words or M.words.get()) do
if word.current then
return word, idx
end end
end end
return ret, current
end end
function M.words.jump(count) ---@param count number
local words = M.words.get() ---@param cycle? boolean
local _, idx = M.words.at(words) function M.words.jump(count, cycle)
local words, idx = M.words.get()
if not idx then if not idx then
return return
end end
local target = words[idx + count] idx = idx + count
if cycle then
idx = (idx - 1) % #words + 1
end
local target = words[idx]
if target then if target then
vim.api.nvim_win_set_cursor(0, target.from) vim.api.nvim_win_set_cursor(0, target.from)
end end