update lsp

main
maye 2025-08-25 16:05:40 +08:00
parent e1614703fd
commit 1089d6af1e
11 changed files with 326 additions and 17 deletions

63
CLAUDE.md Normal file
View File

@ -0,0 +1,63 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Architecture Overview
This is a modern Neovim configuration built around the lazy.nvim plugin manager. The configuration follows a modular structure:
- **Entry point**: `init.lua` loads core modules in sequence: options, mappings, lazy.nvim setup, and autocmds
- **Plugin management**: Uses lazy.nvim with plugins defined in `lua/plugins/` directory
- **LSP configuration**: Centralized in `lua/functions/lsp.lua` with server-specific settings in `lua/lsp/`
- **Shared utilities**: Common constants and tools in `lua/commons/init.lua`
- **Configuration modules**: Core settings split into separate files in `lua/configs/`
## Key Components
### LSP Setup
- Supports both Neovim 0.11+ new LSP config API and legacy setup
- LSP servers are defined in `commons.servers` array
- Server-specific settings live in `lua/lsp/{server}.lua` files
- Uses blink.cmp for completion capabilities
- Mason.nvim auto-installs: stylua, lua-language-server, gopls, pyright
### Plugin Architecture
- All plugins defined as lazy.nvim specs in `lua/plugins/`
- Custom lazy file event handling in `utils/plugins.lua`
- Key plugins: blink.cmp (completion), conform.nvim (formatting), fzf-lua (fuzzy finding), treesitter, lspconfig
### Formatting
- Conform.nvim handles formatting with `<leader>ff` keybind
- Format-on-save enabled with 500ms timeout
- Configured formatters: stylua (Lua), black (Python), rustfmt (Rust), prettier (JS), shfmt (shell)
## Common Development Tasks
### Adding New LSP Server
1. Add server name to `commons.servers` array in `lua/commons/init.lua`
2. Create server config file at `lua/lsp/{server}.lua` with settings table
3. Ensure server is installed via Mason or system package manager
### Adding New Plugin
1. Create plugin spec file in `lua/plugins/{name}.lua`
2. Return lazy.nvim spec table with plugin URL and configuration
3. Plugin will be auto-loaded by lazy.nvim
### Key Mappings
- Leader key: `<Space>`
- Save: `<leader>s`
- Buffer delete: `<leader>q`
- Quit: `<leader>qq` (force quit: `<leader>qqq`)
- Format code: `<leader>ff`
- Toggle comment: `mm` (normal/visual mode)
### File Structure Conventions
- Plugin configs: `lua/plugins/{plugin-name}.lua`
- LSP server configs: `lua/lsp/{server-name}.lua`
- Shared utilities: `lua/commons/` and `lua/utils/`
- Core configuration: `lua/configs/`
## Version Compatibility
- Uses `commons.tools.is_version_gte_0_11()` to detect Neovim 0.11+ for new LSP API
- Maintains backward compatibility with older Neovim versions
- Big file handling configured for files >50KB

View File

@ -1,22 +1,22 @@
{
"Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" },
"blink.cmp": { "branch": "main", "commit": "022521a8910a5543b0251b21c9e1a1e989745796" },
"blink.cmp": { "branch": "main", "commit": "bae4bae0eedd1fa55f34b685862e94a222d5c6f8" },
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
"conform.nvim": { "branch": "master", "commit": "6feb2f28f9a9385e401857b21eeac3c1b66dd628" },
"conform.nvim": { "branch": "master", "commit": "a0ab60ed666c56b37fd7ed1847d2ac52f2482ce0" },
"friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" },
"fzf-lua": { "branch": "main", "commit": "97f665a38d73a6541d98b542c79b4bead8e85d4c" },
"gitsigns.nvim": { "branch": "main", "commit": "8b729e489f1475615dc6c9737da917b3bc163605" },
"gruvbox.nvim": { "branch": "main", "commit": "00e38a379bab3389e187b3953566d67d494dfddd" },
"fzf-lua": { "branch": "main", "commit": "7d66cd81cf485fb17c22d82021cc166ce332a14c" },
"gitsigns.nvim": { "branch": "main", "commit": "6e3c66548035e50db7bd8e360a29aec6620c3641" },
"gruvbox.nvim": { "branch": "main", "commit": "12c2624287dc827edb5d72b2bc4c9619e692a554" },
"lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" },
"lualine.nvim": { "branch": "master", "commit": "0c6cca9f2c63dadeb9225c45bc92bb95a151d4af" },
"mason.nvim": { "branch": "main", "commit": "8024d64e1330b86044fed4c8494ef3dcd483a67c" },
"nvim-autopairs": { "branch": "master", "commit": "4d74e75913832866aa7de35e4202463ddf6efd1b" },
"lualine.nvim": { "branch": "master", "commit": "b8c23159c0161f4b89196f74ee3a6d02cdc3a955" },
"mason.nvim": { "branch": "main", "commit": "7dc4facca9702f95353d5a1f87daf23d78e31c2a" },
"nvim-autopairs": { "branch": "master", "commit": "23320e75953ac82e559c610bec5a90d9c6dfa743" },
"nvim-colorizer.lua": { "branch": "master", "commit": "a065833f35a3a7cc3ef137ac88b5381da2ba302e" },
"nvim-lspconfig": { "branch": "master", "commit": "3ea99227e316c5028f57a4d86a1a7fd01dd876d0" },
"nvim-lspconfig": { "branch": "master", "commit": "e844850b3143a1627437f811549fc7d70cfedf05" },
"nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
"nvim-web-devicons": { "branch": "master", "commit": "1fb58cca9aebbc4fd32b086cb413548ce132c127" },
"plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" },
"nvim-web-devicons": { "branch": "master", "commit": "81b37d7937953b50e5fd8d9d7dfe2c6d0088fde1" },
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
"snacks.nvim": { "branch": "main", "commit": "bc0630e43be5699bb94dadc302c0d21615421d93" },
"tiny-code-action.nvim": { "branch": "main", "commit": "6bfecd218c617e125e69731033fb0d695b8b5144" },
"tiny-code-action.nvim": { "branch": "main", "commit": "6f02cc30685c76812cdaa1bf1dc5f712d2265b14" },
"which-key.nvim": { "branch": "main", "commit": "370ec46f710e058c9c1646273e6b225acf47cbed" }
}

View File

@ -1,14 +1,61 @@
local lspconfig = require("lspconfig")
-- Mason package name to LSP server name mapping
local mason_to_lsp = {
["lua-language-server"] = "lua_ls",
["typescript-language-server"] = "ts_ls",
["rust-analyzer"] = "rust_analyzer",
["gopls"] = "gopls",
["pyright"] = "pyright",
["clangd"] = "clangd",
["bash-language-server"] = "bashls",
["yaml-language-server"] = "yamlls",
}
-- Get installed LSP servers from Mason
local function get_mason_installed_servers()
local mason_registry = require("mason-registry")
local installed_servers = {}
for _, pkg in ipairs(mason_registry.get_installed_packages()) do
local lsp_name = mason_to_lsp[pkg.name]
if lsp_name then
table.insert(installed_servers, lsp_name)
end
end
return installed_servers
end
if require("commons").tools.is_version_gte_0_11() then
-- Neovim 0.11+ native LSP configuration
vim.lsp.config("*", {
capabilities = require("blink.cmp").get_lsp_capabilities(),
root_markers = { ".git" },
})
for _, server in pairs(require("commons").servers) do
-- Get installed servers from Mason
local installed_servers = get_mason_installed_servers()
-- Configure and enable installed servers
for _, server in ipairs(installed_servers) do
local ok, settings = pcall(require, "lsp." .. server)
if ok then vim.lsp.config(server, settings) end
if ok then
vim.lsp.config(server, settings)
else
-- Basic configuration for servers without custom config
vim.lsp.config(server, {})
end
vim.lsp.enable(server)
end
-- Also configure servers from commons.servers that have custom configs
for _, server in pairs(require("commons").servers) do
local ok, settings = pcall(require, "lsp." .. server)
if ok then
vim.lsp.config(server, settings)
vim.lsp.enable(server)
end
end
vim.diagnostic.config({
update_in_insert = true,
severity_sort = true,
@ -16,7 +63,26 @@ if require("commons").tools.is_version_gte_0_11() then
virtual_text = true,
})
else
-- Legacy nvim-lspconfig setup for Neovim < 0.11
local lspconfig = require("lspconfig")
local capabilities = require("blink.cmp").get_lsp_capabilities()
-- Get installed servers from Mason
local installed_servers = get_mason_installed_servers()
-- Configure installed servers
for _, server in ipairs(installed_servers) do
local ok, settings = pcall(require, "lsp." .. server)
if ok then
settings.capabilities = capabilities
lspconfig[server].setup(settings)
else
-- Basic configuration for servers without custom config
lspconfig[server].setup({ capabilities = capabilities })
end
end
-- Also configure servers from commons.servers
for _, server in pairs(require("commons").servers) do
local ok, settings = pcall(require, "lsp." .. server)
if ok then

84
lua/lsp/example.lua Normal file
View File

@ -0,0 +1,84 @@
---@type vim.lsp.Config
--[[
Example LSP server configuration for Neovim 0.11+ native LSP API
This file demonstrates the structure and common patterns for configuring
LSP servers in the new vim.lsp.Config format. Copy this file and modify
it for your specific language server.
Key components:
- cmd: Command and arguments to start the server
- filetypes: File types that should trigger this LSP server
- root_markers: Files/directories that define project root (nested arrays = equal priority)
- settings: Server-specific configuration (schema varies by server)
For server-specific settings schemas, check the server's documentation:
- Language servers often provide JSON schemas for their settings
- Many examples can be found at: https://github.com/neovim/nvim-lspconfig
This configuration works with both Neovim 0.11+ (native vim.lsp.config)
and older versions (via nvim-lspconfig) thanks to the compatibility layer
in lua/functions/lsp.lua
--]]
return {
-- Command to start the language server
-- This should match the executable name installed by Mason or system package manager
cmd = { "language-server-executable" },
-- File types that should automatically attach this LSP server
filetypes = { "javascript", "typescript", "javascriptreact", "typescriptreact" },
-- Root directory markers - LSP will search for these files/directories
-- to determine the project root. Nested arrays indicate equal priority.
-- The first match wins within each priority level.
root_markers = {
{ "package.json", "tsconfig.json", "jsconfig.json" }, -- High priority
{ ".git", ".hg" } -- Fallback markers
},
-- Server-specific settings (varies by language server)
-- Check your language server's documentation for available options
settings = {
-- Example: TypeScript server settings
typescript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
suggest = {
includeCompletionsForModuleExports = true,
},
preferences = {
includePackageJsonAutoImports = "auto",
},
},
javascript = {
-- JavaScript-specific settings
suggest = {
includeCompletionsForModuleExports = true,
},
},
},
-- Optional: Additional capabilities (usually handled globally)
-- capabilities = require("blink.cmp").get_lsp_capabilities(),
-- Optional: Custom initialization options
-- init_options = {
-- hostInfo = "neovim",
-- },
-- Optional: Custom handlers for LSP methods
-- handlers = {
-- ["textDocument/hover"] = vim.lsp.with(
-- vim.lsp.handlers.hover,
-- { border = "rounded" }
-- ),
-- },
}

View File

@ -1,9 +1,25 @@
---@type vim.lsp.Config
return {
cmd = { "lua-language-server" },
filetypes = { "lua" },
root_markers = { ".luarc.json", ".luarc.jsonc", ".git" },
settings = {
Lua = {
diagnostics = {
globals = {'vim'},
}
},
runtime = {
version = 'LuaJIT',
},
workspace = {
checkThirdParty = false,
library = {
vim.env.VIMRUNTIME,
},
},
telemetry = {
enable = false,
},
}
}
}

44
lua/lsp/pyright.lua Normal file
View File

@ -0,0 +1,44 @@
return {
-- Command to start the language server
-- This should match the executable name installed by Mason or system package manager
cmd = { "pyright" },
-- File types that should automatically attach this LSP server
filetypes = { "python" },
-- Root directory markers - LSP will search for these files/directories
-- to determine the project root. Nested arrays indicate equal priority.
-- The first match wins within each priority level.
root_markers = {
{ "pyprojtect.toml", "setup.py", "setup.cfg", "requirements.txt", "pyrightconfig.json" }, -- High priority
{ ".git", ".hg" }, -- Fallback markers
},
-- Server-specific settings (varies by language server)
-- Check your language server's documentation for available options
settings = {
python = {
analysis = {
autoSearchPaths = true,
useLibraryCodeForTypes = true,
},
},
},
-- Optional: Additional capabilities (usually handled globally)
-- capabilities = require("blink.cmp").get_lsp_capabilities(),
-- Optional: Custom initialization options
-- init_options = {
-- hostInfo = "neovim",
-- },
-- Optional: Custom handlers for LSP methods
-- handlers = {
-- ["textDocument/hover"] = vim.lsp.with(
-- vim.lsp.handlers.hover,
-- { border = "rounded" }
-- ),
-- },
}

32
lua/lsp/rust-analyzer.lua Normal file
View File

@ -0,0 +1,32 @@
---@type vim.lsp.Config
return {
cmd = { "rust-analyzer" },
filetypes = { "rust" },
root_markers = {
"Cargo.toml",
},
settings = {
["rust-analyzer"] = {
cargo = {
allFeatures = true,
loadOutDirsFromCheck = true,
},
procMacro = {
enable = true,
},
checkOnSave = {
command = "clippy",
extraArgs = { "--no-deps" },
},
diagnostics = {
enable = true,
enableExperimental = true,
},
completion = {
postfix = {
enable = false,
},
},
},
},
}

View File

@ -2,6 +2,7 @@ return {
"akinsho/bufferline.nvim",
version = "*",
dependencies = "nvim-tree/nvim-web-devicons",
event = "VeryLazy",
config = function(_,opts)
require("bufferline").setup({
options = {

View File

@ -1,7 +1,8 @@
return {
"neovim/nvim-lspconfig",
-- event = "InsertEnter",
-- cond = not require("commons").tools.is_version_gte_0_11(),
-- cond = not require("commons").tools.is_version_gte_0_11(),
event = { "BufReadPre", "BufNewFile" },
dependencies = { { "saghen/blink.cmp" }, { "williamboman/mason.nvim" } },
config = function()
require("functions.lsp")

View File

@ -25,6 +25,7 @@ return {
-- Config
local config = {
options = {
refresh = { statusline = 100 },
component_separators = "",
section_separators = "",
theme = "auto",

View File

@ -4,6 +4,7 @@ return {
build = ":MasonUpdate",
opts_extend = { "ensure_installed" },
opts = { ensure_installed = { "stylua", "lua-language-server", "gopls", "pyright" } },
event = "VeryLazy",
config = function(_, opts)
require("mason").setup(opts)
local mr = require("mason-registry")