Files
dotfiles/.config/nvim/lua/plugins/lsp.lua
T

355 lines
11 KiB
Lua

-- ============================================================================
-- LSP Configuration - TypeScript/Playwright & Go optimiert
-- ============================================================================
return {
{
'neovim/nvim-lspconfig',
event = { 'BufReadPre', 'BufNewFile' },
dependencies = {
-- Mason: LSP Server installer
'williamboman/mason.nvim',
'williamboman/mason-lspconfig.nvim',
-- Status updates für LSP
{ 'j-hui/fidget.nvim', opts = {} },
-- Neodev für Neovim config entwicklung
{ 'folke/neodev.nvim', opts = {} },
},
config = function()
-- LSP Capabilities für completion
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities)
-- Mason Setup
require('mason').setup({
ui = {
border = 'rounded',
icons = {
package_installed = '✓',
package_pending = '➜',
package_uninstalled = '✗'
}
}
})
-- Mason-LSPConfig: Automatische Server Installation
require('mason-lspconfig').setup({
ensure_installed = {
-- Primary (TypeScript/Playwright)
'ts_ls', -- TypeScript/JavaScript
-- Secondary (Go)
'gopls', -- Go
-- Python (für Scripts/Workflows)
'pyright', -- Python
-- LaTeX
'texlab',
-- Supporting
'lua_ls', -- Lua (für Neovim config)
'html', -- HTML
'cssls', -- CSS
'jsonls', -- JSON
'yamlls', -- YAML
'dockerls', -- Dockerfile
'docker_compose_language_service', -- Docker Compose
'eslint', -- Eslinter
},
})
-- LSP Keybindings (nur wenn LSP attached)
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('lsp-attach', { clear = true }),
callback = function(event)
local map = function(keys, func, desc)
vim.keymap.set('n', keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc })
end
-- Navigation
map('gd', require('telescope.builtin').lsp_definitions, 'Goto Definition')
map('gr', require('telescope.builtin').lsp_references, 'Goto References')
map('gI', require('telescope.builtin').lsp_implementations, 'Goto Implementation')
map('gD', vim.lsp.buf.declaration, 'Goto Declaration')
map('<leader>D', require('telescope.builtin').lsp_type_definitions, 'Type Definition')
-- Documentation
map('K', vim.lsp.buf.hover, 'Hover Documentation')
map('<C-k>', vim.lsp.buf.signature_help, 'Signature Help')
-- Actions
map('<leader>ca', vim.lsp.buf.code_action, 'Code Action')
map('<leader>rn', vim.lsp.buf.rename, 'Rename')
-- Workspace
map('<leader>ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, 'Workspace Symbols')
-- Highlight references unter cursor
local client = vim.lsp.get_client_by_id(event.data.client_id)
if client and client.server_capabilities.documentHighlightProvider then
local highlight_augroup = vim.api.nvim_create_augroup('lsp-highlight', { clear = false })
vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
buffer = event.buf,
group = highlight_augroup,
callback = vim.lsp.buf.document_highlight,
})
vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, {
buffer = event.buf,
group = highlight_augroup,
callback = vim.lsp.buf.clear_references,
})
end
if client and client.name == 'eslint' then
vim.api.nvim_create_autocmd('BufWritePre', {
buffer = event.buf,
callback = function()
-- Statt vim.cmd('EslintFixAll') nutzen wir die direkte LSP-Aktion:
vim.lsp.buf.code_action({
context = { only = { "source.fixAll.eslint" } },
apply = true,
})
end,
desc = 'ESLint: Fixe alle Probleme beim Speichern (0.11 Style)',
})
end
end
})
-- ========== Server Configurations ==========
-- TypeScript/JavaScript (ts_ls)
vim.lsp.config('ts_ls', {
capabilities = capabilities,
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
javascript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
},
})
-- Go (gopls)
vim.lsp.config('gopls', {
capabilities = capabilities,
settings = {
gopls = {
gofumpt = true,
codelenses = {
gc_details = false,
generate = true,
regenerate_cgo = true,
run_govulncheck = true,
test = true,
tidy = true,
upgrade_dependency = true,
vendor = true,
},
hints = {
assignVariableTypes = true,
compositeLiteralFields = true,
compositeLiteralTypes = true,
constantValues = true,
functionTypeParameters = true,
parameterNames = true,
rangeVariableTypes = true,
},
analyses = {
fieldalignment = true,
nilness = true,
unusedparams = true,
unusedwrite = true,
useany = true,
},
usePlaceholders = true,
completeUnimported = true,
staticcheck = true,
directoryFilters = { '-.git', '-.vscode', '-.idea', '-.vscode-test', '-node_modules' },
semanticTokens = true,
},
},
})
-- Lua (lua_ls)
vim.lsp.config('lua_ls', {
capabilities = capabilities,
settings = {
Lua = {
completion = {
callSnippet = 'Replace',
},
diagnostics = {
globals = { 'vim' },
},
},
},
})
-- Python (pyright)
vim.lsp.config('pyright', {
capabilities = capabilities,
settings = {
python = {
analysis = {
autoSearchPaths = true,
diagnosticMode = 'workspace',
useLibraryCodeForTypes = true,
typeCheckingMode = 'basic',
},
},
},
})
-- Eslinter
vim.lsp.config('eslint', {
capabilities = capabilities,
settings = {
workingDirectory = { mode = 'auto' },
},
})
vim.lsp.enable('eslint')
-- LaTeX (texlab)
vim.lsp.config('texlab', {
capabilities = capabilities,
settings = {
texlab = {
build = {
executable = 'pdflatex',
args = { '%f' },
onSave = true, -- Auto-compile beim Speichern
forwardSearchAfter = false,
},
forwardSearch = {
executable = 'open',
args = { '%p' },
},
chktex = {
onOpenAndSave = true,
},
diagnosticsDelay = 300,
latexFormatter = 'latexindent',
latexindent = {
modifyLineBreaks = false,
},
},
},
})
-- JSON mit Schema Support
vim.lsp.config('jsonls', {
capabilities = capabilities,
settings = {
json = {
schemas = require('schemastore').json.schemas(),
validate = { enable = true },
},
},
})
-- YAML mit Schema Support
vim.lsp.config('yamlls', {
capabilities = capabilities,
settings = {
yaml = {
schemaStore = {
enable = false,
url = '',
},
schemas = require('schemastore').yaml.schemas(),
},
},
})
-- HTML
vim.lsp.config('html', {
capabilities = capabilities,
})
-- CSS
vim.lsp.config('cssls', {
capabilities = capabilities,
})
-- Docker
vim.lsp.config('dockerls', {
capabilities = capabilities,
})
vim.lsp.config('docker_compose_language_service', {
capabilities = capabilities,
})
-- ========== Diagnostics Configuration (Modern 0.11 Style) ==========
vim.diagnostic.config({
-- Hier werden die Zeichen jetzt direkt definiert (ersetzt sign_define)
signs = {
text = {
[vim.diagnostic.severity.ERROR] = '✘',
[vim.diagnostic.severity.WARN] = '▲',
[vim.diagnostic.severity.HINT] = '⚑',
[vim.diagnostic.severity.INFO] = '»',
},
},
virtual_text = {
prefix = '●',
source = 'if_many',
},
underline = true,
update_in_insert = false,
severity_sort = true,
float = {
border = 'rounded',
source = 'always',
header = '',
prefix = '',
},
})
-- LSP Hover & Signature Help Styling
local handlers = {
['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, { border = 'rounded' }),
['textDocument/signatureHelp'] = vim.lsp.with(vim.lsp.handlers.signature_help, { border = 'rounded' }),
}
-- Handlers registrieren
for method, handler in pairs(handlers) do
vim.lsp.handlers[method] = handler
end
-- Hover Popup Styling (Highlights)
vim.api.nvim_set_hl(0, 'NormalFloat', { bg = '#1e1e1e', fg = '#ffffff' })
vim.api.nvim_set_hl(0, 'FloatBorder', { fg = '#61afef', bg = '#1e1e1e' })
end, -- Hier endet die config-Funktion des Plugins
},
-- SchemaStore für JSON/YAML
{
'b0o/schemastore.nvim',
lazy = true,
},
}