Refactoring code across multiple files or large codebases can quickly become error-prone when done via manual find-and-replace. Modern Language Server Protocol (LSP) integrations solve this by providing AST-aware symbol renaming across your entire workspace.
In this post, I will walk through my newly updated
nvim-lspconfig configuration using
lazy.nvim,
mason.nvim, and native LSP keymaps like <Leader>rn for symbol
renaming.
You can view my complete, live Neovim configuration on GitHub:
๐ VincentTam/nvim-config: lua/plugins/lspconfig.lua
Core Plugin Architecture
My LSP stack uses a clean, lightweight combination of three plugins:
neovim/nvim-lspconfig: Provides default configurations for official language servers.williamboman/mason.nvim: Manages external LSP servers, linters, and formatters directly within Neovim.williamboman/mason-lspconfig.nvim: Bridgesmason.nvimandnvim-lspconfigto ensure smooth server installation and loading.
Configuring <Leader>rn for Symbol Renaming
Rather than globally setting LSP keybindings that apply even in buffers without
an active language server, I map them dynamically inside an LspAttach
autocommand. This ensures keymaps are bound only when an LSP client
successfully attaches to the current buffer.
-- Keymaps to set when an LSP server attaches to a buffer
vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup("UserLspConfig", {}),
callback = function(ev)
local opts = { buffer = ev.buf, desc = "LSP: Rename Symbol" }
vim.keymap.set("n", "<Leader>rn", vim.lsp.buf.rename, opts)
end,
})
How to Use It:
- Place your cursor on any variable, function, parameter, or type name.
- Press
<Leader>rn. - Type the new symbol name in the prompt and press Enter.
- The LSP will update all references across your project workspace automatically.
Active Language Servers
I keep my mason-lspconfig configuration explicitly defined with servers
tailored to my frequent development stacks:
| Server | Primary Language / Format | Special Configuration / Notes |
|---|---|---|
clangd |
C / C++ | Full support for project-wide symbol renames and header/source navigation. |
tinymist |
Typst | Configured with semanticTokens = "enable" for rich syntax highlights. |
ts_ls |
JavaScript / TypeScript | Provides TypeScript language server capabilities. |
html |
HTML | Standard markup language support. |
cssls |
CSS | Auto-completion and linting for stylesheet files. |
marksman |
Markdown | Workspace cross-references and heading navigation for documentation. |