From 3bab6822738724b980778747b9d00605174e8faf Mon Sep 17 00:00:00 2001 From: dlond Date: Thu, 29 May 2025 20:29:10 +1200 Subject: [PATCH] changing kick overrides pattern --- init.lua | 13 +- lua/custom/keymaps.lua | 22 +-- lua/custom/plugins/debug.lua | 7 +- lua/custom/plugins/init.lua | 14 +- lua/custom/plugins/lsp.lua | 200 ++++-------------------- lua/custom/plugins/lsp/clangd.lua | 62 ++++++++ lua/custom/plugins/statusline.lua | 8 +- lua/custom/utils.lua | 242 +++++++++--------------------- 8 files changed, 189 insertions(+), 379 deletions(-) create mode 100644 lua/custom/plugins/lsp/clangd.lua diff --git a/init.lua b/init.lua index 1f1d2276..29f39c87 100644 --- a/init.lua +++ b/init.lua @@ -167,6 +167,7 @@ vim.o.scrolloff = 10 vim.o.confirm = true require 'custom.options' + -- [[ Basic Keymaps ]] -- See `:help vim.keymap.set()` @@ -249,7 +250,6 @@ rtp:prepend(lazypath) -- -- NOTE: Here is where you install your plugins. require('lazy').setup({ - { import = 'custom.plugins' }, -- NOTE: Plugins can be added with a link (or for a github repo: 'owner/repo' link). 'NMAC427/guess-indent.nvim', -- Detect tabstop and shiftwidth automatically @@ -381,6 +381,9 @@ require('lazy').setup({ end, }, { 'nvim-telescope/telescope-ui-select.nvim' }, + + -- Useful for getting pretty icons, but requires a Nerd Font. + { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font }, }, config = function() -- Telescope is a fuzzy finder that comes with a lot of different things that @@ -690,6 +693,11 @@ require('lazy').setup({ }, }, } + + for server_name, server in pairs(servers) do + server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) + require('lspconfig')[server_name].setup(server) + end end, }, @@ -941,6 +949,7 @@ require('lazy').setup({ -- This is the easiest way to modularize your config. -- -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. + { import = 'custom.plugins' }, -- -- For additional information with loading, sourcing and examples see `:help lazy.nvim-🔌-plugin-spec` -- Or use telescope! @@ -968,7 +977,5 @@ require('lazy').setup({ }, }) -require 'custom.utils' - -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et diff --git a/lua/custom/keymaps.lua b/lua/custom/keymaps.lua index dd8d311e..cac73572 100644 --- a/lua/custom/keymaps.lua +++ b/lua/custom/keymaps.lua @@ -1,28 +1,10 @@ -- [[ Basic Keymaps ]] -- See `:help vim.keymap.set()` --- Clear highlights on search when pressing in normal mode --- See `:help hlsearch` -vim.keymap.set('n', '', 'nohlsearch', { desc = 'Clear Search Highlight' }) - --- Diagnostic keymaps (These might also be set by LSP config, but having them here is fine) -vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) - --- Exit terminal mode in the builtin terminal -vim.keymap.set('t', '', '', { desc = 'Exit terminal mode' }) - --- Keybinds to make split navigation easier. --- Use CTRL+ to switch between windows --- See `:help wincmd` -vim.keymap.set('n', '', '', { desc = 'Move focus to the left window' }) -vim.keymap.set('n', '', '', { desc = 'Move focus to the right window' }) -vim.keymap.set('n', '', '', { desc = 'Move focus to the lower window' }) -vim.keymap.set('n', '', '', { desc = 'Move focus to the upper window' }) - -- Add any other general-purpose keymaps you want here vim.keymap.set('n', 'T', function() - require('custom.utils'):pick_target() -end, {desc = "Choose [T]arget"}) + require('custom.lsp.clangd'):pick_target() +end, { desc = 'Choose [T]arget' }) -- Standard practice for Lua modules that don't need to return complex data return {} diff --git a/lua/custom/plugins/debug.lua b/lua/custom/plugins/debug.lua index d2e896a7..7471cb99 100644 --- a/lua/custom/plugins/debug.lua +++ b/lua/custom/plugins/debug.lua @@ -74,9 +74,10 @@ return { type = 'lldb', request = 'launch', program = function() - local utils = require 'custom.utils' - local target = utils:get_target() - return utils.pick_executable(vim.fn.getcwd() .. '/' .. target) + return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file') + -- local utils = require 'custom.utils' + -- local target = utils:get_target() + -- return utils.pick_executable(vim.fn.getcwd() .. '/' .. target) end, cwd = '${workspaceFolder}', stopOnEntry = false, diff --git a/lua/custom/plugins/init.lua b/lua/custom/plugins/init.lua index 1241e745..b73c04ef 100644 --- a/lua/custom/plugins/init.lua +++ b/lua/custom/plugins/init.lua @@ -11,12 +11,12 @@ return { require('nvim-web-devicons').setup() end, }, - { import = 'custom.plugins.completion' }, - { import = 'custom.plugins.debug' }, - { import = 'custom.plugins.formatting' }, + -- { import = 'custom.plugins.completion' }, + -- { import = 'custom.plugins.debug' }, + -- { import = 'custom.plugins.formatting' }, { import = 'custom.plugins.lsp' }, - { import = 'custom.plugins.nvim-tmux-navigator' }, - { import = 'custom.plugins.telescope' }, - { import = 'custom.plugins.theme' }, - { import = 'custom.plugins.treesitter' }, + -- { import = 'custom.plugins.nvim-tmux-navigator' }, + -- { import = 'custom.plugins.telescope' }, + -- { import = 'custom.plugins.theme' }, + -- { import = 'custom.plugins.treesitter' }, } diff --git a/lua/custom/plugins/lsp.lua b/lua/custom/plugins/lsp.lua index 71ddae6c..4af7e87d 100644 --- a/lua/custom/plugins/lsp.lua +++ b/lua/custom/plugins/lsp.lua @@ -1,176 +1,38 @@ -- ~/dlond/nvim/lua/custom/plugins/lsp.lua -- LSP configuration, assuming LSP servers are installed via Nix/Home Manager -return { - -- ======================================== - -- LSP Configuration (LSP servers provided by Nix/Home Manager) - -- ======================================== - { - 'neovim/nvim-lspconfig', - event = { 'BufReadPre', 'BufNewFile' }, -- Load LSP config early - dependencies = { - { 'j-hui/fidget.nvim', opts = {} }, -- Useful status updates for LSP - 'hrsh7th/cmp-nvim-lsp', -- LSP completion source for nvim-cmp +local lspconfig = require 'lspconfig' +local capabilities = require('blink.cmp').get_lsp_capabilities() + +local servers = { + pyright = { + settings = { + python = { + analysis = { + autoSearchPaths = true, + diagnosticMode = 'openFilesOnly', + useLibraryCodeForTypes = true, + typeCheckingMode = 'basic', + }, + }, + positionEncoding = 'utf-8', }, - config = function(_, opts) - -- This config function runs AFTER the plugin and its dependencies are loaded. - -- It sets up the LSP servers. - - -- Get LSP capabilities, augmented by nvim-cmp - local capabilities = require('cmp_nvim_lsp').default_capabilities(vim.lsp.protocol.make_client_capabilities()) - - -- Define the list of LSP servers you want to configure. - -- These servers must be installed via Nix/Home Manager and be in your PATH. - local utils = require 'custom.utils' - local target = utils:get_target() - local servers = { - lua_ls = { - -- cmd = { ... } - -- filetypes = { ... } - -- capabilities = {} - settings = { - Lua = { - completion = { - callSnippet = 'Replace', - }, - diagnostics = { disable = { 'missing-fields' } }, - }, - }, - }, - clangd = { - cmd = utils.make_clangd_cmd(target), - filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' }, - root_dir = require('lspconfig.util').root_pattern('CMakeLists.txt', '.git'), - }, - pyright = { - settings = { - python = { - analysis = { - autoSearchPaths = true, - diagnosticMode = 'openFilesOnly', - useLibraryCodeForTypes = true, - typeCheckingMode = 'basic', - }, - }, - positionEncoding = 'utf-8', - }, - }, - nixd = {}, - ruff = {}, - texlab = {}, - cmake = { - cmd = { 'cmake-language-server' }, - filetypes = { 'cmake' }, - root_dir = require('lspconfig.util').root_pattern('CMakeLists.txt', '.git'), - }, - } - - -- Iterate through the defined servers list and set them up with lspconfig - for server_name, server_config_override in pairs(servers) do - local server_ops = { - capabilities = capabilities, - } - server_ops = vim.tbl_deep_extend('force', server_ops, server_config_override or {}) - local setup_ok, setup_err = pcall(require('lspconfig')[server_name].setup, server_ops) - if not setup_ok then - vim.notify("Error setting up LSP server '" .. server_name .. "': " .. tostring(setup_err), vim.log.levels.ERROR) - else - end - end - - -- Setup keymaps and diagnostics based on kickstart's original init.lua LSP section - vim.api.nvim_create_autocmd('LspAttach', { - group = vim.api.nvim_create_augroup('kickstart-lsp-attach-override', { clear = true }), - callback = function(event) - local map = function(keys, func, desc, mode) - mode = mode or 'n' - vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc }) - end - - -- Standard LSP keymaps - map('grn', vim.lsp.buf.rename, '[R]e[n]ame') - map('gra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' }) - map('grr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') - map('gri', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') - map('grd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') - map('grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') - map('gO', require('telescope.builtin').lsp_document_symbols, 'Open Document Symbols') - map('gW', require('telescope.builtin').lsp_dynamic_workspace_symbols, 'Open Workspace Symbols') - map('grt', require('telescope.builtin').lsp_type_definitions, '[G]oto [T]ype Definition') - - -- Highlight references - local client = vim.lsp.get_client_by_id(event.data.client_id) - local function client_supports_method(client, method, bufnr) - if vim.fn.has 'nvim-0.11' == 1 then - return client:supports_method(method, { bufnr = bufnr }) - else - return client.supports_method(method, { bufnr = bufnr }) - end - end - if client and client_supports_method(client, 'textDocument/documentHighlight', event.buf) then - local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight-override', { 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 } - ) - vim.api.nvim_create_autocmd('LspDetach', { - group = vim.api.nvim_create_augroup('kickstart-lsp-detach-override', { clear = true }), - callback = function(event2) - vim.lsp.buf.clear_references() - vim.api.nvim_clear_autocmds { group = 'kickstart-lsp-highlight-override', buffer = event2.buf } - end, - }) - end - - -- Inlay hints toggle - if client and client_supports_method(client, 'textDocument/inlayHint', event.buf) then - map('th', function() - vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf }) - end, '[T]oggle Inlay [H]ints') - end - end, - }) - - -- Diagnostic configuration - vim.diagnostic.config { - severity_sort = true, - float = { border = 'rounded', source = 'if_many' }, - underline = { severity = vim.diagnostic.severity.ERROR }, - signs = vim.g.have_nerd_font and { - text = { - [vim.diagnostic.severity.ERROR] = '󰅚 ', - [vim.diagnostic.severity.WARN] = '󰀪 ', - [vim.diagnostic.severity.INFO] = '󰋽 ', - [vim.diagnostic.severity.HINT] = '󰌶 ', - }, - } or {}, - virtual_text = { - source = 'if_many', - spacing = 2, - format = function(diagnostic) - local diagnostic_message = { - [vim.diagnostic.severity.ERROR] = diagnostic.message, - [vim.diagnostic.severity.WARN] = diagnostic.message, - [vim.diagnostic.severity.INFO] = diagnostic.message, - [vim.diagnostic.severity.HINT] = diagnostic.message, - } - return diagnostic_message[diagnostic.severity] - end, - }, - } - end, -- End of config function }, - - -- lazydev setup (still useful for Neovim Lua development) - { - 'folke/lazydev.nvim', - ft = 'lua', - opts = { - library = { { path = 'luvit-meta/library', words = { 'vim%.uv' } } }, - }, + nixd = {}, + ruff = {}, + texlab = {}, + cmake = { + cmd = { 'cmake-language-server' }, + filetypes = { 'cmake' }, + root_dir = require('lspconfig.util').root_pattern('CMakeLists.txt', '.git'), }, } + +for server_name, server in pairs(servers) do + server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) + require('lspconfig')[server_name].setup(server) +end + +require('custom.plugins.lsp.clangd').setup() + +return {} diff --git a/lua/custom/plugins/lsp/clangd.lua b/lua/custom/plugins/lsp/clangd.lua new file mode 100644 index 00000000..fe5571bf --- /dev/null +++ b/lua/custom/plugins/lsp/clangd.lua @@ -0,0 +1,62 @@ +local M = {} + +local lspconfig = require 'lspconfig' +local capabilities = require('blink.cmp').get_lsp_capabilities() +local Path = require 'plenary.path' +local pickers = require 'telescope.pickers' +local finders = require 'telescope.finders' +local conf = require('telescope.config').values + +local current_target = './build/debug' + +local function make_clangd_cmd() + return { + 'clangd', + '--background-index', + '--clang-tidy', + '--header-insertion=never', + '--query-driver=' .. vim.fn.exepath 'clang++', + '--resource-dir=' .. vim.fn.trim(vim.fn.system 'clang++ --print-resource-dir', + '--compile-commands-dir=' .. current_target, + } +end + +local function reload_clangd() + for _, client in pairs(vim.lsp.get_active_clients()) do + if client.name == 'clangd' then + client.stop() + end + end + M.setup() +end + +function M.pick_target() + pickers + .new({}, { + prompt_title = 'Choose build target', + finder = finders.new_oneshot_job { 'fd', '-u', 'compile_commands.json', '-x', 'dirname', '{}' }, + sorter = conf.generic_sorter {}, + attach_mappings = function(_, map) + map('i', '', function(prompt_bufnr) + local entry = require('telescope.actions.state').get_selected_entry() + current_target = entry[1] + require('telescope.actions').close(prompt_bufnr) + reload_clangd() + end) + return true + end, + }) + :find() +end + +function M.setup() + lspconfig.clangd.setup { + cmd = make_clangd_cmd(), + filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' }; + root_dir = lspconfig.util.root_pattern('.git'), + single_file_support = true, + capabilities = capabilities, + } +end + +return M diff --git a/lua/custom/plugins/statusline.lua b/lua/custom/plugins/statusline.lua index d89cc7a5..0b53e8fb 100644 --- a/lua/custom/plugins/statusline.lua +++ b/lua/custom/plugins/statusline.lua @@ -5,10 +5,10 @@ return { local statusline = require 'mini.statusline' -- Add new section function - statusline.section_target = function() - local target = require('custom.utils'):get_target() - return target and (' ' .. target) or '' - end + -- statusline.section_target = function() + -- local target = require('custom.utils'):get_target() + -- return target and (' ' .. target) or '' + -- end -- Override content.active to include target opts.content = opts.content or {} diff --git a/lua/custom/utils.lua b/lua/custom/utils.lua index fecfc230..b45ac58e 100644 --- a/lua/custom/utils.lua +++ b/lua/custom/utils.lua @@ -1,173 +1,69 @@ -local async = require 'plenary.async' -local pickers = require 'telescope.pickers' -local finders = require 'telescope.finders' -local sorters = require('telescope.config').values -local actions = require 'telescope.actions' -local action_state = require 'telescope.actions.state' - -local function collect_executables(start_dir) - local results = {} - - -- Add '.', start_dir so it works with your fd version - local fd = vim.fn.systemlist { - 'fd', - '.', - start_dir, - '--exec', - 'file', - '{}', - } - - for _, line in ipairs(fd) do - local path, typeinfo = line:match '^(.-):%s*(.+)$' - if path and not path:match 'CMakeFiles' and typeinfo and (typeinfo:match 'Mach%-O' or typeinfo:match 'ELF') then - table.insert(results, path) - end - end - - return results -end - -local function pick_executable(start_dir) - return async.wrap(function(_start_dir, on_choice) - local executables = collect_executables(_start_dir) - - if #executables == 0 then - vim.notify('No executables found in ' .. _start_dir, vim.log.levels.WARN) - on_choice(nil) - return - end - - pickers - .new({}, { - prompt_title = 'Select Executable', - finder = finders.new_table { results = executables }, - sorter = sorters.generic_sorter {}, - attach_mappings = function(_, map) - actions.select_default:replace(function(prompt_bufnr) - local entry = action_state.get_selected_entry() - actions.close(prompt_bufnr) - on_choice(entry.value) - end) - map('i', '', function(bufnr) - actions.close(bufnr) - on_choice(nil) - end) - map('n', 'q', function(bufnr) - actions.close(bufnr) - on_choice(nil) - end) - return true - end, - }) - :find() - end, 2)(start_dir) -end - -return { - pick_executable = pick_executable, - - clangd_base_cmd = { - 'clangd', - '--background-index', - '--clang-tidy', - '--header-insertion=never', - '--query-driver=' .. vim.fn.trim(vim.fn.system 'which clang++'), - '--resource-dir=' .. vim.fn.trim(vim.fn.system 'clang++ --print-resource-dir'), - }, - make_clangd_cmd = function(self, compile_commands_dir) - local cmd = vim.deepcopy(self.clangd_base_cmd) - table.insert(cmd, '--compile-commands-dir=' .. compile_commands_dir) - return cmd - end, - - find_targets = function() - return vim.fn.systemlist 'fd -u compile_commands.json -x dirname {}' - end, - - get_target = function(self) - return vim.g.current_target_dir or 'build/debug' - end, - - set_target = function(self, dir) - vim.g.current_target_dir = dir - print(' set_target:', dir) - self:reload_clangd() - end, - - pick_target = function(self) - local targets = self.find_targets() - if vim.tbl_isempty(targets) then - vim.notify('No build targets found.', vim.log.WARN) - return - end - vim.ui.select(targets, { prompt = 'Select build target:' }, function(choice) - if choice then - self:set_target(choice) - end - end) - end, - - reload_clangd = function(self) - local lspconfig = require 'lspconfig' - local configs = require("lspconfig.configs") - - local cmd = self:make_clangd_cmd(self:get_target()) - print(' clangd cmd:', vim.inspect(cmd)) - - for _, client in ipairs(vim.lsp.get_clients()) do - if client.name == 'clangd' then - print(' stopping old clangd') - client.stop() - end - end - - if not configs.clangd then - configs.clangd = { - default_config = { - cmd = cmd, - filetypes = { 'c', 'cpp', 'objc', 'objcpp' }, - root_dir = lspconfig.util.root_pattern("compile_commands.json", '.git'), - single_file_support = true, - }, - } -else - configs.clangd.default_config.cmd = cmd -end - - lspconfig.clangd.setup({ cmd = cmd }) - -local buf = vim.api.nvim_get_current_buf() - local name = vim.api.nvim_buf_get_name(buf) - loal ft = vim.bo[buf].filetype - - if name ~= "" and ft:match('c') then - print(" reopening buffer to auto-attach clangd") - vim.cmd("edit") -else - print(" Skipping buffer reload: name or filetype invalid") - end -end, - -list_attached_clients = function() - local clients = vim.lsp.get_clients({ bufnr = 0 }) - if vim.tbl_isempty(clients) then - print("No LSP clients attached to this buffer.") - return - end - for _, client in ipairs(clients) do - print("LSP:", client.name, "id:", client.id) - end -end, - -list_attached_clients = function() - local clients = vim.lsp.get_clients({ bufnr = 0 }) - if vim.tbl_isempty(clients) then - print("No LSP clients attached to this buffer.") - return - end - for _, client in ipairs(clients) do - print("LSP:", client.name, "id:", client.id) - end -end, -} +-- local async = require 'plenary.async' +-- local pickers = require 'telescope.pickers' +-- local finders = require 'telescope.finders' +-- local sorters = require('telescope.config').values +-- local actions = require 'telescope.actions' +-- local action_state = require 'telescope.actions.state' +-- +-- local function collect_executables(start_dir) +-- local results = {} +-- +-- -- Add '.', start_dir so it works with your fd version +-- local fd = vim.fn.systemlist { +-- 'fd', +-- '.', +-- start_dir, +-- '--exec', +-- 'file', +-- '{}', +-- } +-- +-- for _, line in ipairs(fd) do +-- local path, typeinfo = line:match '^(.-):%s*(.+)$' +-- if path and not path:match 'CMakeFiles' and typeinfo and (typeinfo:match 'Mach%-O' or typeinfo:match 'ELF') then +-- table.insert(results, path) +-- end +-- end +-- +-- return results +-- end +-- +-- local function pick_executable(start_dir) +-- return async.wrap(function(_start_dir, on_choice) +-- local executables = collect_executables(_start_dir) +-- +-- if #executables == 0 then +-- vim.notify('No executables found in ' .. _start_dir, vim.log.levels.WARN) +-- on_choice(nil) +-- return +-- end +-- +-- pickers +-- .new({}, { +-- prompt_title = 'Select Executable', +-- finder = finders.new_table { results = executables }, +-- sorter = sorters.generic_sorter {}, +-- attach_mappings = function(_, map) +-- actions.select_default:replace(function(prompt_bufnr) +-- local entry = action_state.get_selected_entry() +-- actions.close(prompt_bufnr) +-- on_choice(entry.value) +-- end) +-- map('i', '', function(bufnr) +-- actions.close(bufnr) +-- on_choice(nil) +-- end) +-- map('n', 'q', function(bufnr) +-- actions.close(bufnr) +-- on_choice(nil) +-- end) +-- return true +-- end, +-- }) +-- :find() +-- end, 2)(start_dir) +-- end +-- +-- return { +-- pick_executable = pick_executable, +-- }