-- ============================================================================ -- 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 -- Supporting 'lua_ls', -- Lua (für Neovim config) 'html', -- HTML 'cssls', -- CSS 'jsonls', -- JSON 'yamlls', -- YAML 'dockerls', -- Dockerfile 'docker_compose_language_service', -- Docker Compose }, }) -- 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 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', }, }, }, }) -- 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 ========== vim.diagnostic.config({ virtual_text = { prefix = '●', source = 'if_many', }, signs = true, underline = true, update_in_insert = false, severity_sort = true, float = { border = 'rounded', source = 'always', header = '', prefix = '', }, }) -- 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 = '' }) end -- LSP Hover border vim.lsp.handlers['textDocument/hover'] = vim.lsp.with( vim.lsp.handlers.hover, { border = 'rounded' } ) vim.lsp.handlers['textDocument/signatureHelp'] = vim.lsp.with( vim.lsp.handlers.signature_help, { border = 'rounded' } ) end, }, -- SchemaStore für JSON/YAML { 'b0o/schemastore.nvim', lazy = true, }, }