From 8876413e2dcc6e14071e79fb73a5f32736aaf94c Mon Sep 17 00:00:00 2001 From: Yi Ming Date: Sat, 24 Jan 2026 03:02:56 +0800 Subject: [PATCH] feat(lsp): highlighting the symbol being renamed (#37390) --- runtime/doc/news.txt | 2 ++ runtime/lua/vim/lsp/buf.lua | 33 +++++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index f1995fcfe0..52f88bb621 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -296,6 +296,8 @@ LSP • Support for `workspace/diagnostic/refresh`: https://microsoft.github.io/language-server-protocol/specification/#diagnostic_refresh • Support for dynamic registration for `textDocument/diagnostic` +• |vim.lsp.buf.rename()| now highlights the symbol being renamed using the + |hl-LspReferenceTarget| highlight group. LUA diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index b463d36647..9f04c4fbbc 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -23,6 +23,7 @@ local function client_positional_params(params) end local hover_ns = api.nvim_create_namespace('nvim.lsp.hover_range') +local rename_ns = api.nvim_create_namespace('nvim.lsp.rename_range') --- @class vim.lsp.buf.hover.Opts : vim.lsp.util.open_floating_preview.Opts --- @field silent? boolean @@ -743,6 +744,7 @@ function M.rename(new_name, opts) if client:supports_method('textDocument/prepareRename') then local params = util.make_position_params(win, client.offset_encoding) + ---@param result? lsp.Range|{ range: lsp.Range, placeholder: string } client:request('textDocument/prepareRename', params, function(err, result) if err or result == nil then if next(clients, idx) then @@ -760,10 +762,33 @@ function M.rename(new_name, opts) return end + local range ---@type lsp.Range? + if result.start then + ---@cast result lsp.Range + range = result + elseif result.range then + ---@cast result { range: lsp.Range, placeholder: string } + range = result.range + end + 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, + rename_ns, + 'LspReferenceTarget', + { start.line, start_idx }, + { end_.line, end_idx }, + { priority = vim.hl.priorities.user } + ) + end + local prompt_opts = { prompt = 'New Name: ', } - -- result: Range | { range: Range, placeholder: string } if result.placeholder then prompt_opts.default = result.placeholder elseif result.start then @@ -774,10 +799,10 @@ function M.rename(new_name, opts) prompt_opts.default = cword end vim.ui.input(prompt_opts, function(input) - if not input or #input == 0 then - return + if input and #input ~= 0 then + rename(input) end - rename(input) + api.nvim_buf_clear_namespace(bufnr, rename_ns, 0, -1) end) end, bufnr) else