LSP Configurations
This page details the Language Server Protocol (LSP) setup and configurations for various programming languages in the LLawn Neovim configuration.
LSP Architecture
The configuration leverages Neovim 0.11+'s built-in LSP capabilities with
vim.lsp.enable for efficient, modern language support.
Core Components
- Language Server Management: Mason handles automatic installation
- Completion Integration: nvim-cmp provides intelligent code completion
- Linting: nvim-lint provides asynchronous linting with Mason integration
- Formatting: conform provides formatting with Mason integration and LSP fallback
- Custom Configurations: Language-specific fine-tuning in
after/lsp/
LSP Setup
Server Configuration
LSP servers are organized by language and enabled automatically:
local servers = {
lua = { "lua_ls" },
dart = { "flutter_ls" },
cpp = { "clangd" },
go = { "gopls" },
python = { "ty", "ruff" },
fortran = { "fortls" },
}
for _, group in pairs(servers) do
for _, server in ipairs(group) do
vim.lsp.enable(server)
end
end
Linting and Formatting
Linting with nvim-lint
The configuration uses mfussenegger/nvim-lint for asynchronous linting, integrated with Mason for automatic tool installation.
Key Features:
- Automatic linter detection from Mason registry
- Filters out linters that are also LSP servers to avoid duplication
- Runs on buffer enter, write, and insert leave
- Manual trigger with
<leader>pl
Configuration (lua/llawn/plugins/lsp/linting.lua):
-- Manual overrides for linters by filetype
local linters_by_ft_manual = {
-- Add linters manually if needed
}
-- Get merged linters from Mason and manual overrides
local function get_merged_linters()
local mason_utils = require("llawn.utils.mason")
local mason_linters = mason_utils.get_mason_tools("Linter")
local lsp_tools = mason_utils.get_mason_tools("LSP")
-- Filter logic to avoid duplication with LSP servers
-- ... (filtered logic)
return vim.tbl_deep_extend('force', filtered_linters, linters_by_ft_manual)
end
return {
"mfussenegger/nvim-lint",
config = function()
local lint = require("lint")
lint.linters_by_ft = get_merged_linters()
-- Auto-trigger on events
vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, {
callback = function()
lint.try_lint()
end,
})
end,
}
Formatting with conform
stevearc/conform.nvim handles code formatting, prioritizing Mason formatters with LSP fallback.
Key Features:
- Integrates with Mason registry for formatter discovery
- Format on save disabled by default (manual trigger)
- Confirmation dialog with diff preview before applying changes
- Supports multiple formatters per filetype
Configuration (lua/llawn/plugins/lsp/conform.lua):
-- Override or supplement formatters from Mason registry
local formatters_by_ft = {
python = {
"ruff_format",
"ruff_organize_imports",
"ruff_fix",
},
make = { "bake" },
}
return {
{
"stevearc/conform.nvim",
opts = function()
local mason_utils = require("llawn.utils.mason")
local mason_formatters = mason_utils.get_mason_tools("Formatter")
local merged_formatters = vim.tbl_deep_extend('force', mason_formatters, formatters_by_ft)
return {
formatters_by_ft = merged_formatters,
format_on_save = false, -- Manual trigger preferred
}
end,
},
}
Formatting Utility (lua/llawn/utils/formatting.lua):
Provides a confirmation-based formatting function that shows diffs and allows approval/rejection:
function M.format_with_confirmation()
-- Check for available formatters (conform or LSP)
-- Apply formatting
-- Show diff for confirmation
-- Apply or reject based on user input
end
Mason Integration
The lua/llawn/utils/mason.lua provides utilities to bridge Mason tools with
Neovim configurations:
get_mason_tools(category): Get tools by Mason category (LSP, Linter, Formatter)- Handles language name mapping (e.g., makefile → make)
- Filters tools based on categories
Mason Auto-Installation
The following servers are automatically installed via Mason:
Supported Languages
| Language | LSP Server |
|---|---|
| C/C++ | clangd |
| Flutter/Dart | flutter_ls |
| Fortran | fortls |
| Go | gopls |
| Lua | lua_ls |
| Python | ty + ruff |
Language-Specific Configurations
Flutter/Dart (flutter_ls)
Location: after/lsp/flutter_ls.lua
Features:
- Custom Command: Uses Flutter SDK's analysis server
- Environment: Requires
FLUTTER_ROOTenvironment variable - Enhanced Features: Outline views, closing labels, Flutter-specific analysis
Configuration:
{
cmd = {
"dart",
flutter_sdk .. "/bin/cache/dart-sdk/bin/snapshots/analysis_server.dart.snapshot",
"--lsp",
},
filetypes = { "dart" },
root_markers = { "pubspec.yaml" },
init_options = {
onlyAnalyzeProjectsWithOpenFiles = true,
suggestFromUnimportedLibraries = true,
closingLabels = true,
outline = true,
flutterOutline = true,
},
settings = {
dart = {
completeFunctionCalls = true,
showTodos = true,
},
},
}
Setup Requirements:
- Install Flutter SDK
- Set
FLUTTER_ROOTenvironment variable - Ensure Dart analysis server is available
Lua (lua_ls)
Location: after/lsp/lua_ls.lua
Features:
- Lua language server configuration
- Custom diagnostics and settings for Neovim Lua development
Python Linter (ruff)
Location: after/lsp/ruff.lua
Features:
- Ruff linter integration
- Python code quality and style checking
LSP Features
See @docs/keymaps.md for LSP keymaps and features.
Formatting: <leader>pf triggers formatting with confirmation dialog
showing diff preview. Uses conform if available, falls back to LSP formatting.
Linting: Automatic linting on buffer events, manual trigger with
<leader>pl.
Lualine Integration: Active LSP clients shown in status line
Extending LSP Support
Adding New Languages
- Add to servers table in
lsp.lua:local servers = { -- existing servers... javascript = { "tsserver" }, } - Add to Mason ensure_installed in
mason.lua:ensure_installed = { -- existing servers... "tsserver", } - Create custom config (optional) in
after/lsp/:-- after/lsp/tsserver.lua return { -- custom configuration }
Custom Server Configuration
For servers requiring special setup, create files in after/lsp/ following the
Flutter example. This allows fine-tuning of:
- Command arguments
- Initialization options
- Server settings
- File type associations
- Root markers
Troubleshooting
Common Issues
- Server Not Starting: Check Mason installation status
- No Completion: Verify cmp-nvim-lsp capabilities setup
- Performance: Check for conflicting LSP configurations
Diagnostic Commands
-
:LspInfo- Show LSP client information -
:Mason- Open Mason UI -
:LspRestart- Restart all LSP clientsThis LSP setup provides a solid foundation for productive development across multiple languages while remaining lightweight and maintainable.