From 553935a90b902bf03706cb09a517d00cc77f289d Mon Sep 17 00:00:00 2001 From: Walter Jenkins Date: Sun, 7 Sep 2025 12:37:51 -0400 Subject: [PATCH] attempt to fix lsp --- lua/core/keymaps.lua | 10 +-- lua/core/options.lua | 10 +++ lua/plugins/conform.lua | 7 +- lua/plugins/lsp.lua | 123 ++++++++++++++++++++++++++--- lua/plugins/none-ls.lua | 1 + lua/plugins/vim-tmux-navigator.lua | 31 ++++---- 6 files changed, 150 insertions(+), 32 deletions(-) diff --git a/lua/core/keymaps.lua b/lua/core/keymaps.lua index 812f257d..4e3801d8 100644 --- a/lua/core/keymaps.lua +++ b/lua/core/keymaps.lua @@ -59,11 +59,11 @@ vim.keymap.set('n', 'h', 's', opts) -- split window horizontally vim.keymap.set('n', 'se', '=', opts) -- make split windows equal width & height vim.keymap.set('n', 'xs', ':close', opts) -- close current split window --- Navigate between splits -vim.keymap.set('n', '', ':wincmd k', opts) -vim.keymap.set('n', '', ':wincmd j', opts) -vim.keymap.set('n', '', ':wincmd h', opts) -vim.keymap.set('n', '', ':wincmd l', opts) +-- Navigate between splits - DISABLED: Using Zellij navigation +-- vim.keymap.set('n', '', ':wincmd k', opts) +-- vim.keymap.set('n', '', ':wincmd j', opts) +-- vim.keymap.set('n', '', ':wincmd h', opts) +-- vim.keymap.set('n', '', ':wincmd l', opts) -- Tabs vim.keymap.set('n', 'to', ':tabnew', opts) -- open new tab diff --git a/lua/core/options.lua b/lua/core/options.lua index 07ceb0b5..5a009864 100644 --- a/lua/core/options.lua +++ b/lua/core/options.lua @@ -69,3 +69,13 @@ vim.api.nvim_create_autocmd("FileType", { vim.bo.expandtab = true end, }) + +vim.api.nvim_create_autocmd("FileType", { + pattern = { "typescript", "typescriptreact", "javascript", "javascriptreact" }, + callback = function() + vim.bo.tabstop = 2 + vim.bo.shiftwidth = 2 + vim.bo.softtabstop = 2 + vim.bo.expandtab = true + end, +}) diff --git a/lua/plugins/conform.lua b/lua/plugins/conform.lua index 44db35ee..3f7a0a51 100644 --- a/lua/plugins/conform.lua +++ b/lua/plugins/conform.lua @@ -22,6 +22,11 @@ return { args = { "fmt", "-stdin-filepath", "$FILENAME", "-stdout" }, stdin = true, }, + goimports = { + command = "goimports", + args = {}, + stdin = true, + }, }, formatters_by_ft = { templ = { "templ_fmt" }, -- ✅ only templ fmt for .templ @@ -35,7 +40,7 @@ return { html = { "prettier" }, css = { "prettier" }, lua = { "stylua" }, - go = { "gofmt" }, + go = { "goimports", "gofmt" }, }, format_on_save = function(bufnr) if vim.bo[bufnr].filetype == "templ" then diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index 25866c45..08a6df5e 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -11,8 +11,52 @@ return { extension = { templ = "templ" }, }) - -- Example setup for Go, TS, etc. - lspconfig.gopls.setup({}) + -- Go LSP with import organization + lspconfig.gopls.setup({ + root_dir = function(fname) + return util.root_pattern("go.work", "go.mod", ".git")(fname) + or util.path.dirname(fname) + end, + 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", "-dist", "-build", "-out", "-coverage", "-tmp", "-.cache" }, + semanticTokens = true, + -- Performance optimizations for large repositories + memoryMode = "DegradeClosed", + symbolMatcher = "FastFuzzy", + }, + }, + }) -- TypeScript (make sure you don't also set this up elsewhere to avoid duplicates) lspconfig.ts_ls.setup({}) @@ -25,6 +69,64 @@ return { single_file_support = true, }) + -- LSP client monitoring helper + vim.api.nvim_create_user_command('LspClients', function() + local clients = vim.lsp.get_clients() + local client_counts = {} + + for _, client in ipairs(clients) do + client_counts[client.name] = (client_counts[client.name] or 0) + 1 + end + + print("=== Active LSP Clients ===") + for name, count in pairs(client_counts) do + local status = count > 1 and " ⚠️ DUPLICATE" or " ✅" + print(string.format("%s: %d client(s)%s", name, count, status)) + end + + if next(client_counts) == nil then + print("No active LSP clients") + end + end, { desc = "Show active LSP clients and detect duplicates" }) + + -- Command to kill duplicate gopls clients (keep only the one with settings) + vim.api.nvim_create_user_command('LspKillDuplicates', function() + local gopls_clients = vim.lsp.get_clients({ name = "gopls" }) + if #gopls_clients <= 1 then + print("No duplicate gopls clients found") + return + end + + local client_to_keep = nil + local clients_to_kill = {} + + -- Find the client with the most settings (should be our configured one) + for _, client in ipairs(gopls_clients) do + local settings_count = 0 + if client.config.settings and client.config.settings.gopls then + for _ in pairs(client.config.settings.gopls) do + settings_count = settings_count + 1 + end + end + + if settings_count > 0 and not client_to_keep then + client_to_keep = client + else + table.insert(clients_to_kill, client) + end + end + + -- Kill the duplicates + for _, client in ipairs(clients_to_kill) do + print(string.format("Killing duplicate gopls client (id: %d)", client.id)) + client.stop(true) + end + + if client_to_keep then + print(string.format("Kept gopls client (id: %d) with settings", client_to_keep.id)) + end + end, { desc = "Kill duplicate gopls clients" }) + -- Safe hover helper local function has_hover(bufnr) for _, c in pairs(vim.lsp.get_active_clients({ bufnr = bufnr })) do @@ -35,15 +137,20 @@ return { return false end - -- Keymaps + -- LSP keymaps are handled in lsp-keymaps.lua vim.api.nvim_create_autocmd("LspAttach", { callback = function(args) local bufnr = args.buf + + -- Use the centralized keymap system + local lsp_keymaps = require('plugins.lsp-keymaps') + lsp_keymaps.on_attach(nil, bufnr) + + -- Safe hover (keeping this custom logic) local function buf_map(mode, lhs, rhs, desc) vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, desc = desc }) end - - -- SAFE Hover + buf_map("n", "K", function() if not has_hover(bufnr) then return @@ -55,12 +162,6 @@ return { pcall(vim.lsp.buf.hover) end end, "LSP: Hover (safe)") - - -- Usual LSP keymaps - buf_map("n", "gd", vim.lsp.buf.definition, "Goto Definition") - buf_map("n", "gr", vim.lsp.buf.references, "Goto References") - buf_map("n", "gi", vim.lsp.buf.implementation, "Goto Implementation") - buf_map("n", "rn", vim.lsp.buf.rename, "Rename Symbol") end, }) end, diff --git a/lua/plugins/none-ls.lua b/lua/plugins/none-ls.lua index 94f5a65f..cf75d956 100644 --- a/lua/plugins/none-ls.lua +++ b/lua/plugins/none-ls.lua @@ -32,6 +32,7 @@ return { formatting.shfmt.with { args = { '-i', '4' } }, require('none-ls.formatting.ruff').with { extra_args = { '--extend-select', 'I' } }, require 'none-ls.formatting.ruff_format', + formatting.goimports, -- Add goimports for Go files } local augroup = vim.api.nvim_create_augroup('LspFormatting', {}) diff --git a/lua/plugins/vim-tmux-navigator.lua b/lua/plugins/vim-tmux-navigator.lua index beee1418..de4da7fc 100644 --- a/lua/plugins/vim-tmux-navigator.lua +++ b/lua/plugins/vim-tmux-navigator.lua @@ -1,18 +1,19 @@ -- Copied config from https://github.com/christoomey/vim-tmux-navigator +-- DISABLED: Using Zellij navigation instead return { - 'christoomey/vim-tmux-navigator', - cmd = { - 'TmuxNavigateLeft', - 'TmuxNavigateDown', - 'TmuxNavigateUp', - 'TmuxNavigateRight', - 'TmuxNavigatePrevious', - }, - keys = { - { '', 'TmuxNavigateLeft' }, - { '', 'TmuxNavigateDown' }, - { '', 'TmuxNavigateUp' }, - { '', 'TmuxNavigateRight' }, - { '', 'TmuxNavigatePrevious' }, - }, + -- 'christoomey/vim-tmux-navigator', + -- cmd = { + -- 'TmuxNavigateLeft', + -- 'TmuxNavigateDown', + -- 'TmuxNavigateUp', + -- 'TmuxNavigateRight', + -- 'TmuxNavigatePrevious', + -- }, + -- keys = { + -- { '', 'TmuxNavigateLeft' }, + -- { '', 'TmuxNavigateDown' }, + -- { '', 'TmuxNavigateUp' }, + -- { '', 'TmuxNavigateRight' }, + -- { '', 'TmuxNavigatePrevious' }, + -- }, }