mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 10:45:16 -07:00
feat(lsp): highlight hover target/range #31110
**Problem:** Despite the LSP providing the option for language servers to specify a range with a hover response (for highlighting), Neovim does not give the option to highlight this range. **Solution:** Add an option to `buf.hover()` which causes this range to be highlighted. Co-authored-by: Mathias Fußenegger <mfussenegger@users.noreply.github.com>
This commit is contained in:
parent
235cb5bc5f
commit
44229bb85b
@ -338,13 +338,16 @@ Highlight groups that are meant to be used by |vim.lsp.buf.document_highlight()|
|
|||||||
You can see more about the differences in types here:
|
You can see more about the differences in types here:
|
||||||
https://microsoft.github.io/language-server-protocol/specification#textDocument_documentHighlight
|
https://microsoft.github.io/language-server-protocol/specification#textDocument_documentHighlight
|
||||||
|
|
||||||
*hl-LspReferenceText*
|
*hl-LspReferenceText*
|
||||||
LspReferenceText used for highlighting "text" references
|
LspReferenceText used for highlighting "text" references
|
||||||
*hl-LspReferenceRead*
|
*hl-LspReferenceRead*
|
||||||
LspReferenceRead used for highlighting "read" references
|
LspReferenceRead used for highlighting "read" references
|
||||||
*hl-LspReferenceWrite*
|
*hl-LspReferenceWrite*
|
||||||
LspReferenceWrite used for highlighting "write" references
|
LspReferenceWrite used for highlighting "write" references
|
||||||
*hl-LspInlayHint*
|
*hl-LspReferenceTarget*
|
||||||
|
LspReferenceTarget used for highlighting reference targets (e.g. in a
|
||||||
|
hover range)
|
||||||
|
*hl-LspInlayHint*
|
||||||
LspInlayHint used for highlighting inlay hints
|
LspInlayHint used for highlighting inlay hints
|
||||||
|
|
||||||
|
|
||||||
@ -1335,6 +1338,14 @@ hover({config}) *vim.lsp.buf.hover()*
|
|||||||
mappings are available as usual, except that "q" dismisses the window. You
|
mappings are available as usual, except that "q" dismisses the window. You
|
||||||
can scroll the contents the same as you would any other buffer.
|
can scroll the contents the same as you would any other buffer.
|
||||||
|
|
||||||
|
Note: to disable hover highlights, add the following to your config: >lua
|
||||||
|
vim.api.nvim_create_autocmd('ColorScheme', {
|
||||||
|
callback = function()
|
||||||
|
vim.api.nvim_set_hl(0, 'LspReferenceTarget', {})
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
<
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {config} (`vim.lsp.buf.hover.Opts?`) See |vim.lsp.buf.hover.Opts|.
|
• {config} (`vim.lsp.buf.hover.Opts?`) See |vim.lsp.buf.hover.Opts|.
|
||||||
|
|
||||||
|
@ -216,6 +216,8 @@ LSP
|
|||||||
• |vim.lsp.buf.signature_help()| can now cycle through different signatures
|
• |vim.lsp.buf.signature_help()| can now cycle through different signatures
|
||||||
using `<C-s>` and also support multiple clients.
|
using `<C-s>` and also support multiple clients.
|
||||||
• The client now supports `'utf-8'` and `'utf-32'` position encodings.
|
• The client now supports `'utf-8'` and `'utf-32'` position encodings.
|
||||||
|
• |vim.lsp.buf.hover()| now highlights hover ranges using the
|
||||||
|
|hl-LspReferenceTarget| highlight group.
|
||||||
|
|
||||||
LUA
|
LUA
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ local function client_positional_params(params)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local hover_ns = api.nvim_create_namespace('vim_lsp_hover_range')
|
||||||
|
|
||||||
--- @class vim.lsp.buf.hover.Opts : vim.lsp.util.open_floating_preview.Opts
|
--- @class vim.lsp.buf.hover.Opts : vim.lsp.util.open_floating_preview.Opts
|
||||||
--- @field silent? boolean
|
--- @field silent? boolean
|
||||||
|
|
||||||
@ -30,13 +32,24 @@ end
|
|||||||
--- In the floating window, all commands and mappings are available as usual,
|
--- In the floating window, all commands and mappings are available as usual,
|
||||||
--- except that "q" dismisses the window.
|
--- except that "q" dismisses the window.
|
||||||
--- You can scroll the contents the same as you would any other buffer.
|
--- You can scroll the contents the same as you would any other buffer.
|
||||||
|
---
|
||||||
|
--- Note: to disable hover highlights, add the following to your config:
|
||||||
|
---
|
||||||
|
--- ```lua
|
||||||
|
--- vim.api.nvim_create_autocmd('ColorScheme', {
|
||||||
|
--- callback = function()
|
||||||
|
--- vim.api.nvim_set_hl(0, 'LspReferenceTarget', {})
|
||||||
|
--- end,
|
||||||
|
--- })
|
||||||
|
--- ```
|
||||||
--- @param config? vim.lsp.buf.hover.Opts
|
--- @param config? vim.lsp.buf.hover.Opts
|
||||||
function M.hover(config)
|
function M.hover(config)
|
||||||
config = config or {}
|
config = config or {}
|
||||||
config.focus_id = ms.textDocument_hover
|
config.focus_id = ms.textDocument_hover
|
||||||
|
|
||||||
lsp.buf_request_all(0, ms.textDocument_hover, client_positional_params(), function(results, ctx)
|
lsp.buf_request_all(0, ms.textDocument_hover, client_positional_params(), function(results, ctx)
|
||||||
if api.nvim_get_current_buf() ~= ctx.bufnr then
|
local bufnr = assert(ctx.bufnr)
|
||||||
|
if api.nvim_get_current_buf() ~= bufnr then
|
||||||
-- Ignore result since buffer changed. This happens for slow language servers.
|
-- Ignore result since buffer changed. This happens for slow language servers.
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -67,9 +80,10 @@ function M.hover(config)
|
|||||||
local format = 'markdown'
|
local format = 'markdown'
|
||||||
|
|
||||||
for client_id, result in pairs(results1) do
|
for client_id, result in pairs(results1) do
|
||||||
|
local client = assert(lsp.get_client_by_id(client_id))
|
||||||
if nresults > 1 then
|
if nresults > 1 then
|
||||||
-- Show client name if there are multiple clients
|
-- Show client name if there are multiple clients
|
||||||
contents[#contents + 1] = string.format('# %s', lsp.get_client_by_id(client_id).name)
|
contents[#contents + 1] = string.format('# %s', client.name)
|
||||||
end
|
end
|
||||||
if type(result.contents) == 'table' and result.contents.kind == 'plaintext' then
|
if type(result.contents) == 'table' and result.contents.kind == 'plaintext' then
|
||||||
if #results1 == 1 then
|
if #results1 == 1 then
|
||||||
@ -87,6 +101,22 @@ function M.hover(config)
|
|||||||
else
|
else
|
||||||
vim.list_extend(contents, util.convert_input_to_markdown_lines(result.contents))
|
vim.list_extend(contents, util.convert_input_to_markdown_lines(result.contents))
|
||||||
end
|
end
|
||||||
|
local range = result.range
|
||||||
|
if range then
|
||||||
|
local start = range.start
|
||||||
|
local end_ = range['end']
|
||||||
|
local start_idx = util._get_line_byte_from_position(bufnr, start, client.offset_encoding)
|
||||||
|
local end_idx = util._get_line_byte_from_position(bufnr, end_, client.offset_encoding)
|
||||||
|
|
||||||
|
vim.hl.range(
|
||||||
|
bufnr,
|
||||||
|
hover_ns,
|
||||||
|
'LspReferenceTarget',
|
||||||
|
{ start.line, start_idx },
|
||||||
|
{ end_.line, end_idx },
|
||||||
|
{ priority = vim.hl.priorities.user }
|
||||||
|
)
|
||||||
|
end
|
||||||
contents[#contents + 1] = '---'
|
contents[#contents + 1] = '---'
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -100,7 +130,16 @@ function M.hover(config)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
lsp.util.open_floating_preview(contents, format, config)
|
local _, winid = lsp.util.open_floating_preview(contents, format, config)
|
||||||
|
|
||||||
|
api.nvim_create_autocmd('WinClosed', {
|
||||||
|
pattern = tostring(winid),
|
||||||
|
once = true,
|
||||||
|
callback = function()
|
||||||
|
api.nvim_buf_clear_namespace(bufnr, hover_ns, 0, -1)
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
})
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -215,6 +215,7 @@ static const char *highlight_init_both[] = {
|
|||||||
"default link LspReferenceRead LspReferenceText",
|
"default link LspReferenceRead LspReferenceText",
|
||||||
"default link LspReferenceText Visual",
|
"default link LspReferenceText Visual",
|
||||||
"default link LspReferenceWrite LspReferenceText",
|
"default link LspReferenceWrite LspReferenceText",
|
||||||
|
"default link LspReferenceTarget LspReferenceText",
|
||||||
"default link LspSignatureActiveParameter Visual",
|
"default link LspSignatureActiveParameter Visual",
|
||||||
"default link SnippetTabstop Visual",
|
"default link SnippetTabstop Visual",
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user