43
loading...
This website collects cookies to deliver better user experience
coc.nvim
and I'm quite used to the nice and simple UIs it provides to interact with the LSP client. So I wanted something similar for the built-in LSP client too.popup.nvim
or neovim-ui
project. But those projects have different goals than what I had in mind. What I want is to have a high-level API with a lot of sugar for doing repetitive things. Those projects are focused more on low-level stuffs.nui.nvim
textDocument/rename
operation using nui.nvim
.local curr_name = vim.fn.expand("<cword>")
local params = vim.lsp.util.make_position_params()
on_submit
callback function that is expected to be called with the new name:local function on_submit(new_name)
if not new_name or #new_name == 0 or curr_name == new_name then
-- do nothing if `new_name` is empty or not changed.
return
end
-- add `newName` property to `params`.
-- this is needed for making `textDocument/rename` request.
params.newName = new_name
-- send the `textDocument/rename` request to LSP server
vim.lsp.buf_request(0, "textDocument/rename", params, function(_, result, _, _)
if not result then
-- do nothing if server returns empty result
return
end
-- the `result` contains all the places we need to update the
-- name of the identifier. so we apply those edits.
vim.lsp.util.apply_workspace_edit(result)
-- after the edits are applied, the files are not saved automatically.
-- let's remind ourselves to save those...
local total_files = vim.tbl_count(result.changes)
print(
string.format(
"Changed %s file%s. To save them run ':wa'",
total_files,
total_files > 1 and "s" or ""
)
)
end)
end
local Input = require("nui.input")
local popup_options = {
-- border for the window
border = {
style = "rounded",
text = {
top = "[Rename]",
top_align = "left"
},
},
-- highlight for the window.
highlight = "Normal:Normal",
-- place the popup window relative to the
-- buffer position of the identifier
relative = {
type = "buf",
position = {
-- this is the same `params` we got earlier
row = params.position.line,
col = params.position.character,
}
},
-- position the popup window on the line below identifier
position = {
row = 1,
col = 0,
},
-- 25 cells wide, should be enough for most identifier names
size = {
width = 25,
height = 1,
},
}
local input = Input(popup_options, {
-- set the default value to current name
default_value = curr_name,
-- pass the `on_submit` callback function we wrote earlier
on_submit = on_submit,
prompt = "",
})
input:mount()
on_submit
callback function will be invoked with the input value and the popup window will be closed.-- close on <esc> in normal mode
input:map("n", "<esc>", input.input_props.on_close, { noremap = true })
local event = require("nui.utils.autocmd").event
-- close when cursor leaves the buffer
input:on(event.BufLeave, input.input_props.on_close, { once = true })
nui_lsp_rename
in a separate file and map your keys to start the renaming.~/.config/nvim/lua/config/nui_lsp.lua
:-- file: ~/.config/nvim/lua/config/nui_lsp.lua
local function nui_lsp_rename()
-- ... the implementation from above
end
return {
lsp_rename = nui_lsp_rename,
}
-- file: ~/.config/nvim/init.lua
-- you probably want to put this inside the `on_attach` callback function
-- of your lsp server config and use `vim.api.nvim_buf_set_keymap` instead.
vim.api.nvim_set_keymap(
"n",
"<Leader>rn",
"<cmd>lua require('config.nui_lsp').lsp_rename()<CR>",
{ noremap = true, silent = true }
)
nui.nvim
, let's Discuss at GitHub.