Interactive LSP configuration for specific languages with Mason integration
Configures LSP servers for specific languages with Mason integration and keybindings.
/plugin marketplace add kriscard/kriscard-claude-plugins/plugin install neovim-advisor@kriscard[language]Interactive LSP (Language Server Protocol) configuration for specific languages with proper Mason, nvim-lspconfig, and nvim-cmp integration.
Configure LSP servers for specified languages with proper installation, keybindings, completion integration, and formatting setup.
If language argument provided, use it. Otherwise ask:
Which language(s) would you like to set up LSP for? (select multiple)
- TypeScript/JavaScript
- Python
- Rust
- Go
- Lua
- C/C++
- Java
- Other (specify)
Use AskUserQuestion tool.
Look for existing LSP configuration:
# Check for lspconfig
find ~/.config/nvim -name "*lsp*.lua"
Use Glob and Read tools to check:
Check if base LSP plugins exist:
Required plugins:
If missing, offer to add them first.
For each selected language, provide:
Server: tsserver Mason name: typescript-language-server
Configuration:
return {
"neovim/nvim-lspconfig",
ft = { "typescript", "javascript", "typescriptreact", "javascriptreact" },
dependencies = {
"williamboman/mason.nvim",
"williamboman/mason-lspconfig.nvim",
"hrsh7th/cmp-nvim-lsp",
},
config = function()
require("mason").setup()
require("mason-lspconfig").setup({
ensure_installed = { "tsserver" },
})
local capabilities = require("cmp_nvim_lsp").default_capabilities()
require("lspconfig").tsserver.setup({
capabilities = capabilities,
on_attach = function(client, bufnr)
-- Disable tsserver formatting (use prettier/biome instead)
client.server_capabilities.documentFormattingProvider = false
-- Keybindings
local opts = { buffer = bufnr, silent = true }
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts)
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
end,
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayFunctionParameterTypeHints = true,
},
},
},
})
end,
}
Additional recommendations:
Server: pyright or pylsp Mason name: pyright
Configuration:
require("lspconfig").pyright.setup({
capabilities = capabilities,
settings = {
python = {
analysis = {
typeCheckingMode = "basic",
diagnosticMode = "workspace",
inlayHints = {
variableTypes = true,
functionReturnTypes = true,
},
},
},
},
})
Additional setup:
Server: rust-analyzer Mason name: rust-analyzer
Configuration:
require("lspconfig").rust_analyzer.setup({
capabilities = capabilities,
settings = {
["rust-analyzer"] = {
checkOnSave = {
command = "clippy",
},
cargo = {
allFeatures = true,
},
procMacro = {
enable = true,
},
},
},
})
Recommended plugin:
Server: gopls Mason name: gopls
Configuration:
require("lspconfig").gopls.setup({
capabilities = capabilities,
settings = {
gopls = {
analyses = {
unusedparams = true,
},
staticcheck = true,
gofumpt = true,
},
},
})
Additional:
Server: lua_ls (formerly sumneko_lua) Mason name: lua-language-server
Configuration:
require("lspconfig").lua_ls.setup({
capabilities = capabilities,
settings = {
Lua = {
runtime = {
version = "LuaJIT",
},
diagnostics = {
globals = { "vim" }, -- Recognize vim global for Neovim config
},
workspace = {
library = vim.api.nvim_get_runtime_file("", true),
checkThirdParty = false,
},
telemetry = {
enable = false,
},
},
},
})
Server: clangd Mason name: clangd
Configuration:
require("lspconfig").clangd.setup({
capabilities = capabilities,
cmd = {
"clangd",
"--background-index",
"--clang-tidy",
"--header-insertion=iwyu",
"--completion-style=detailed",
},
})
Additional:
Server: jdtls Mason name: jdtls
Note: Java LSP is complex, recommend nvim-jdtls plugin:
return {
"mfussenegger/nvim-jdtls",
ft = "java",
}
Check if LSP file exists:
lua/plugins/lsp.luaCreate complete LSP configuration:
-- lua/plugins/lsp.lua
return {
"neovim/nvim-lspconfig",
ft = { [languages from selection] },
dependencies = {
"williamboman/mason.nvim",
"williamboman/mason-lspconfig.nvim",
"hrsh7th/cmp-nvim-lsp",
},
config = function()
-- Mason setup
require("mason").setup({
ui = { border = "rounded" },
})
require("mason-lspconfig").setup({
ensure_installed = { [servers for selected languages] },
automatic_installation = true,
})
-- Capabilities
local capabilities = require("cmp_nvim_lsp").default_capabilities()
-- Common on_attach function
local on_attach = function(client, bufnr)
local opts = { buffer = bufnr, silent = true }
-- Navigation
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts)
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
-- Information
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, opts)
-- Actions
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts)
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
-- Formatting
vim.keymap.set("n", "<leader>f", function()
vim.lsp.buf.format({ async = true })
end, opts)
-- Diagnostics
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, opts)
vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts)
vim.keymap.set("n", "<leader>e", vim.diagnostic.open_float, opts)
end
-- Configure each server
local lspconfig = require("lspconfig")
[Server configurations for each language]
end,
}
Use Write tool to create file.
Use Edit tool to add new server configurations.
Add diagnostic configuration if not present:
-- In config function
vim.diagnostic.config({
virtual_text = {
prefix = "●",
},
signs = true,
underline = true,
update_in_insert = false,
severity_sort = true,
float = {
border = "rounded",
source = "always",
},
})
-- Diagnostic signs
local signs = { Error = " ", Warn = " ", Hint = " ", Info = " " }
for type, icon in pairs(signs) do
local hl = "DiagnosticSign" .. type
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl })
end
Ensure nvim-cmp is configured with LSP source:
Check lua/plugins/cmp.lua includes:
sources = {
{ name = "nvim_lsp" }, -- LSP completions
{ name = "buffer" },
{ name = "path" },
}
If not configured, offer to set it up.
Ask user about formatting:
Would you like to set up formatting?
- Use LSP formatter
- Use external formatter (prettier, black, etc.)
- Set up later
If external formatter, recommend conform.nvim:
return {
"stevearc/conform.nvim",
event = "BufWritePre",
config = function()
require("conform").setup({
formatters_by_ft = {
typescript = { "prettierd", "prettier" },
python = { "black", "isort" },
rust = { "rustfmt" },
go = { "goimports", "gofumpt" },
},
format_on_save = {
timeout_ms = 500,
lsp_fallback = true,
},
})
end,
}
After configuration, guide user to verify:
# Restart Neovim
# Open a file in the configured language
# Check LSP is working:
:LspInfo
:checkhealth lsp
# Test features:
# - Hover over a symbol (K)
# - Go to definition (gd)
# - Trigger completion (Ctrl+Space)
Show what was configured:
## LSP Setup Complete
### Configured Languages
- TypeScript/JavaScript (tsserver)
- Python (pyright)
### Files Created/Modified
- lua/plugins/lsp.lua (created)
- lua/plugins/cmp.lua (verified)
### Installed via Mason
- typescript-language-server
- pyright
### Keybindings Added
- `gd` - Go to definition
- `K` - Hover documentation
- `<leader>ca` - Code actions
- `<leader>rn` - Rename symbol
- `<leader>f` - Format buffer
- `[d` / `]d` - Navigate diagnostics
### Next Steps
1. Restart Neovim
2. Open a TypeScript or Python file
3. Run `:checkhealth lsp` to verify
4. Try the keybindings
### Additional Recommendations
- Add prettier for TypeScript formatting
- Add black for Python formatting
- Consider typescript-tools.nvim for better performance
Would you like me to set up formatting or add any recommended plugins?
For each language, mention:
Check .claude/neovim-advisor.local.md:
---
tech_stack:
- typescript
- python
---
Auto-suggest LSP for listed languages.
If Neovim 0.10+, enable inlay hints:
local on_attach = function(client, bufnr)
-- Enable inlay hints
if vim.lsp.inlay_hint and client.server_capabilities.inlayHintProvider then
vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })
end
end
Help users get fully functional LSP setup with minimal friction.