-- ============================================================================ -- 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('D', require('telescope.builtin').lsp_type_definitions, 'Type Definition') -- Documentation map('K', vim.lsp.buf.hover, 'Hover Documentation') map('', vim.lsp.buf.signature_help, 'Signature Help') -- Actions map('ca', vim.lsp.buf.code_action, 'Code Action') map('rn', vim.lsp.buf.rename, 'Rename') -- Workspace map('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, }, }