-
-
Save MunifTanjim/8d9498c096719bdf4234321230fe3dc7 to your computer and use it in GitHub Desktop.
| local Input = require("nui.input") | |
| local event = require("nui.utils.autocmd").event | |
| local function nui_lsp_rename() | |
| local curr_name = vim.fn.expand("<cword>") | |
| local params = vim.lsp.util.make_position_params() | |
| 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, ctx, _) | |
| 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. | |
| local client = vim.lsp.get_client_by_id(ctx.client_id) | |
| vim.lsp.util.apply_workspace_edit(result, client.offset_encoding) | |
| -- 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 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() | |
| -- close on <esc> in normal mode | |
| input:map("n", "<esc>", input.input_props.on_close, { noremap = true }) | |
| -- close when cursor leaves the buffer | |
| input:on(event.BufLeave, input.input_props.on_close, { once = true }) | |
| end | |
| return { | |
| lsp_rename = nui_lsp_rename, | |
| } |
would it be possible to set the initial state to NORMAL mode instead of INSERT mode? I tried adding vim.cmd('stopinsert') after input:mount() but that didn't work.
Hey @disrupted, you can do this after mounting:
vim.schedule(function()
vim.api.nvim_command("stopinsert")
end)This is how it runs:
inputis mounted- It enters INSERT mode
- The
default_value(i.e. the current name of the variable you're renaming) is inserted to the prompt - After vim is done with all those, it'll run your scheduled callback, so it'll exit INSERT mode.
Just curious, what is your usecase for doing this? π€
Hi @MunifTanjim, thanks for the explanation. That did the trick!
When renaming a symbol I usually don't append something to the name, more often than not I want to change the whole name or parts of it.
This is part of some other small tweaks I made to my config.
Since I am working with snake-case languages (Python, Rust, Lua) for the most part, temporarily changing the iskeyword setting makes it possible to move around and change parts of long_variable_name more easily.
Also made it so the window width is set dynamically depending on the string length.
neovim updated the lsp-handler, line 20 must now be
vim.lsp.buf_request(0, "textDocument/rename", lsp_params, function(_, result, _, _)neovim updated the
lsp-handler, line 20 must now bevim.lsp.buf_request(0, "textDocument/rename", lsp_params, function(_, result, _, _)
Thanks @RaafatTurki!!! I was wondering why rename was not working on my setup, I thought something was wrong with the lsp server π
I just tried your suggestion and it's working again! π
would it be possible to set the initial state to NORMAL mode instead of INSERT mode? I tried adding
vim.cmd('stopinsert')afterinput:mount()but that didn't work.