From 6f352e7c113f903565bc566ffe07a4b42bfef666 Mon Sep 17 00:00:00 2001 From: Adam Poniatowski Date: Sun, 27 Apr 2025 13:22:07 +0200 Subject: [PATCH] made some mods everywhere --- _home_adam_.config_nvim | 62 ----- build.zen | 44 ---- init.lua | 29 +-- lua/core/keymaps.lua | 175 ++++++++++--- lua/options/autocmds.lua | 50 ++-- lua/options/settings.lua | 46 +++- lua/plugins/bufferline.lua | 55 +--- lua/plugins/bufferline/setup.lua | 61 +++++ lua/plugins/cmp/setup.lua | 62 +++++ lua/plugins/coding.lua | 255 +------------------ lua/plugins/coding/clangd.lua | 28 ++ lua/plugins/coding/dap.lua | 136 ++++++++++ lua/plugins/coding/go.lua | 24 ++ lua/plugins/coding/zig.lua | 9 + lua/plugins/{gruvbox.lua => colorscheme.lua} | 0 lua/plugins/commentary.lua | 6 + lua/plugins/conform.lua | 7 +- lua/plugins/garbage-day.lua | 4 +- lua/plugins/gitsigns/setup.lua | 28 ++ lua/plugins/indent-blankline.lua | 8 + lua/plugins/lsp/servers.lua | 69 +++++ lua/plugins/lsp/setup.lua | 68 +++++ lua/plugins/lualine.lua | 73 ++++++ lua/plugins/lualine/setup.lua | 72 ++++++ lua/plugins/null-ls.lua | 60 +---- lua/plugins/null-ls/setup.lua | 51 ++++ lua/plugins/nvim-autopairs.lua | 33 +-- lua/plugins/nvim-autopairs/setup.lua | 36 +++ lua/plugins/nvim-cmp.lua | 78 +----- lua/plugins/nvim-lspconfig.lua | 247 ++---------------- lua/plugins/nvim-treesitter.lua | 4 +- lua/plugins/session.lua | 20 +- lua/plugins/snacks/picker.lua | 3 + lua/plugins/snacks/terminal.lua | 4 + lua/plugins/telescope.lua | 96 +------ lua/plugins/telescope/setup.lua | 45 ++++ lua/plugins/which-key.lua | 161 +++++------- lua/plugins/work/gopls_flags.txt | 1 + src/main.zen | 5 - 39 files changed, 1145 insertions(+), 1070 deletions(-) delete mode 100644 _home_adam_.config_nvim delete mode 100644 build.zen create mode 100644 lua/plugins/bufferline/setup.lua create mode 100644 lua/plugins/cmp/setup.lua create mode 100644 lua/plugins/coding/clangd.lua create mode 100644 lua/plugins/coding/dap.lua create mode 100644 lua/plugins/coding/go.lua create mode 100644 lua/plugins/coding/zig.lua rename lua/plugins/{gruvbox.lua => colorscheme.lua} (100%) create mode 100644 lua/plugins/commentary.lua create mode 100644 lua/plugins/gitsigns/setup.lua create mode 100644 lua/plugins/indent-blankline.lua create mode 100644 lua/plugins/lsp/servers.lua create mode 100644 lua/plugins/lsp/setup.lua create mode 100644 lua/plugins/lualine.lua create mode 100644 lua/plugins/lualine/setup.lua create mode 100644 lua/plugins/null-ls/setup.lua create mode 100644 lua/plugins/nvim-autopairs/setup.lua create mode 100644 lua/plugins/telescope/setup.lua create mode 100644 lua/plugins/work/gopls_flags.txt delete mode 100644 src/main.zen diff --git a/_home_adam_.config_nvim b/_home_adam_.config_nvim deleted file mode 100644 index 27c99652..00000000 --- a/_home_adam_.config_nvim +++ /dev/null @@ -1,62 +0,0 @@ -let SessionLoad = 1 -let s:so_save = &g:so | let s:siso_save = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1 -let v:this_session=expand(":p") -silent only -silent tabonly -cd ~/.config/nvim -if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == '' - let s:wipebuf = bufnr('%') -endif -let s:shortmess_save = &shortmess -if &shortmess =~ 'A' - set shortmess=aoOA -else - set shortmess=aoO -endif -badd +1 ~/.config/nvim/lua/core/keymaps.lua -argglobal -%argdel -edit ~/.config/nvim/lua/core/keymaps.lua -wincmd t -let s:save_winminheight = &winminheight -let s:save_winminwidth = &winminwidth -set winminheight=0 -set winheight=1 -set winminwidth=0 -set winwidth=1 -argglobal -setlocal fdm=manual -setlocal fde=0 -setlocal fmr={{{,}}} -setlocal fdi=# -setlocal fdl=0 -setlocal fml=1 -setlocal fdn=20 -setlocal fen -silent! normal! zE -let &fdl = &fdl -let s:l = 1 - ((0 * winheight(0) + 17) / 35) -if s:l < 1 | let s:l = 1 | endif -keepjumps exe s:l -normal! zt -keepjumps 1 -normal! 0 -tabnext 1 -if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal' - silent exe 'bwipe ' . s:wipebuf -endif -unlet! s:wipebuf -set winheight=1 winwidth=20 -let &shortmess = s:shortmess_save -let &winminheight = s:save_winminheight -let &winminwidth = s:save_winminwidth -let s:sx = expand(":p:r")."x.vim" -if filereadable(s:sx) - exe "source " . fnameescape(s:sx) -endif -let &g:so = s:so_save | let &g:siso = s:siso_save -set hlsearch -nohlsearch -doautoall SessionLoadPost -unlet SessionLoad -" vim: set ft=vim : diff --git a/build.zen b/build.zen deleted file mode 100644 index 97511545..00000000 --- a/build.zen +++ /dev/null @@ -1,44 +0,0 @@ -// -// The Zen Programming Language(tm) -// Copyright (c) 2018-2020 kristopher tate & connectFree Corporation. -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// -// This project may be licensed under the terms of the ConnectFree Reference -// Source License (CF-RSL). Corporate and Academic licensing terms are also -// available. Please contact for details. -// -// Zen, the Zen three-circles logo and The Zen Programming Language are -// trademarks of connectFree Corporation in Japan and other countries. -// -// connectFree and the connectFree logo are registered trademarks -// of connectFree Corporation in Japan and other countries. connectFree -// trademarks and branding may not be used without express written permission -// of connectFree. Please remove all trademarks and branding before use. -// -// See the LICENSE file at the root of this project for complete information. -// -// - -const Builder = @import("std").build.Builder; - -pub fn build(b: *mut Builder) void { - // Standard target options allows the person running `zen build` to choose - // what target to build for. Here we do not override the defaults, which - // means any target is allowed, and the default is native. Other options - // for restricting supported target set are available. - const target = b.standardTargetOptions(.{}); - // Standard release options allow the person running `zen build` to select - // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. - const mode = b.standardReleaseOptions(); - - const exe = b.addExecutable("nvim", "src/main.zen"); - exe.setTarget(target); - exe.setBuildMode(mode); - exe.install(); - - const run_cmd = exe.run(); - b.addStepDependency(run_cmd, b.getInstallStep()); - - const run_step = b.step("run", "Run the app"); - b.addStepDependency(run_step, run_cmd); -} diff --git a/init.lua b/init.lua index 80713364..8395961d 100644 --- a/init.lua +++ b/init.lua @@ -1,17 +1,14 @@ +---@diagnostic disable: undefined-global local config_path = vim.fn.stdpath 'config' -package.path = config_path .. '/?.lua;' .. config_path .. '/?/init.lua;' .. package.path +local lua_path = config_path .. '/lua' +package.path = lua_path .. '/?.lua;' .. lua_path .. '/?/init.lua;' .. config_path .. '/?.lua;' .. config_path .. '/?/init.lua;' .. package.path -require 'core.keymaps' -require 'options.autocmds' -require 'options.settings' --- require 'plugins.init' +require('core.keymaps').setup() +require('options.autocmds').setup() +require('options.settings').setup() local plugins = require 'plugins' --- Set leader key before lazy.nvim -vim.g.mapleader = ' ' -vim.g.maplocalleader = ' ' - -- Bootstrap lazy.nvim local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not (vim.uv or vim.loop).fs_stat(lazypath) then @@ -45,19 +42,5 @@ require('lazy').setup({ plugins }, { }, }) --- Set up swap file directory to be in a central location -vim.opt.directory = vim.fn.stdpath('data') .. '/swapfiles/' - --- Create the swap directory if it doesn't exist -local swap_dir = vim.fn.stdpath('data') .. '/swapfiles' -if vim.fn.isdirectory(swap_dir) == 0 then - vim.fn.mkdir(swap_dir, 'p') -end - --- Configure swap file behavior -vim.opt.swapfile = true -- Keep swap files for recovery -vim.opt.updatetime = 300 -- Save swap file after 300ms of inactivity -vim.opt.updatecount = 100 -- Write to swap file after 100 characters - -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et diff --git a/lua/core/keymaps.lua b/lua/core/keymaps.lua index 7e743dd5..b87c973e 100644 --- a/lua/core/keymaps.lua +++ b/lua/core/keymaps.lua @@ -5,12 +5,17 @@ vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' -- Core Neovim keymaps (non-plugin) +-- These are basic Neovim operations like: +-- - Window navigation (Ctrl + hjkl) +-- - Window resizing (Ctrl + Arrow keys) +-- - Line/selection movement (Alt + jk) +-- - Quick save and quit (w, W, Q) local core_keymaps = { -- Clear highlights on search when pressing in normal mode { mode = 'n', lhs = '', rhs = 'nohlsearch', opts = { desc = 'Clear search highlights' } }, -- Exit terminal mode with a more discoverable shortcut - { mode = 't', lhs = '', rhs = '', opts = { desc = 'Exit terminal mode' } }, + { mode = 't', lhs = '', rhs = '', opts = { desc = 'Exit terminal mode' } }, -- Window navigation (Ctrl + hjkl) { mode = 'n', lhs = '', rhs = '', opts = { desc = 'Focus: Window left' } }, @@ -37,6 +42,23 @@ local core_keymaps = { } -- LSP keymaps - these will be set up when LSP attaches to a buffer +-- Navigation: +-- - gd: Go to definition +-- - gr: Find references +-- - gI: Go to implementation +-- - gy: Go to type definition +-- +-- Workspace: +-- - ls: Document symbols +-- - lS: Workspace symbols +-- +-- Code Actions: +-- - lr: Rename symbol +-- - la: Code action +-- - lf: Format code +-- +-- Documentation: +-- - K: Show documentation local M = {} function M.setup_lsp_keymaps(bufnr) local keymaps = { @@ -78,6 +100,23 @@ function M.setup_lsp_keymaps(bufnr) end -- Telescope keymaps (all under s for Search) +-- Help: +-- - sh: Search help tags +-- - sk: Search keymaps +-- +-- Files: +-- - sf: Find files +-- - sr: Recent files +-- +-- Text Search: +-- - sg: Live grep in workspace +-- - sw: Search word under cursor +-- - /: Fuzzy find in current buffer +-- - s/: Live grep in open files +-- +-- Workspace: +-- - sd: Search diagnostics +-- - sb: Search buffers M.telescope_keymaps = { -- Help { mode = 'n', lhs = 'sh', rhs = function() require('telescope.builtin').help_tags() end, opts = { desc = 'Search: Help' } }, @@ -108,18 +147,30 @@ M.telescope_keymaps = { { mode = 'n', lhs = 'sb', rhs = function() require('telescope.builtin').buffers() end, opts = { desc = 'Search: Buffers' } }, } --- Diagnostic keymaps (navigation with [d and ]d, details with t for trouble) +-- Diagnostic keymaps +-- Navigation: +-- - [d: Previous diagnostic +-- - ]d: Next diagnostic +-- +-- Viewing: +-- - tt: Show diagnostic details in float +-- - tl: Show diagnostics in location list M.diagnostic_keymaps = { -- Navigation { mode = 'n', lhs = '[d', rhs = vim.diagnostic.goto_prev, opts = { desc = 'Diagnostic: Previous' } }, { mode = 'n', lhs = ']d', rhs = vim.diagnostic.goto_next, opts = { desc = 'Diagnostic: Next' } }, - -- Viewing diagnostics (using t for Trouble) - { mode = 'n', lhs = 'tt', rhs = vim.diagnostic.open_float, opts = { desc = 'Trouble: Show details' } }, - { mode = 'n', lhs = 'tl', rhs = vim.diagnostic.setloclist, opts = { desc = 'Trouble: Show list' } }, + -- Viewing diagnostics + { mode = 'n', lhs = 'tt', rhs = vim.diagnostic.open_float, opts = { desc = 'Diagnostic: Show details' } }, + { mode = 'n', lhs = 'tl', rhs = vim.diagnostic.setloclist, opts = { desc = 'Diagnostic: Show list' } }, } --- Database keymaps (all under D for Database, to avoid conflicts with diagnostics) +-- Database keymaps (all under D for Database) +-- UI: +-- - Dt: Toggle database UI +-- - Df: Find database buffer +-- - Dr: Rename database buffer +-- - Dl: Show last query info M.dadbod_keymaps = { { mode = 'n', lhs = 'Dt', rhs = 'DBUIToggle', opts = { desc = 'Database: Toggle UI' } }, { mode = 'n', lhs = 'Df', rhs = 'DBUIFindBuffer', opts = { desc = 'Database: Find buffer' } }, @@ -128,29 +179,30 @@ M.dadbod_keymaps = { } -- Session management keymaps (all under m for Memory) +-- Session Operations: +-- - mw: Write/save current session +-- - mr: Read/restore saved session +-- - md: Delete saved session M.session_keymaps = { - { mode = 'n', lhs = 'mw', rhs = function() require('mini.sessions').write() end, opts = { desc = 'Memory: Write session' } }, - { mode = 'n', lhs = 'mr', rhs = function() require('mini.sessions').read() end, opts = { desc = 'Memory: Read session' } }, - { mode = 'n', lhs = 'md', rhs = function() require('mini.sessions').delete() end, opts = { desc = 'Memory: Delete session' } }, + { mode = 'n', lhs = 'mw', rhs = function() + local name = vim.fn.fnamemodify(vim.fn.getcwd(), ':t') + require('mini.sessions').write(name, { force = true }) + end, opts = { desc = 'Memory: Write session' } }, + { mode = 'n', lhs = 'mr', rhs = function() + local name = vim.fn.fnamemodify(vim.fn.getcwd(), ':t') + require('mini.sessions').read(name) + end, opts = { desc = 'Memory: Read session' } }, + { mode = 'n', lhs = 'md', rhs = function() + local name = vim.fn.fnamemodify(vim.fn.getcwd(), ':t') + require('mini.sessions').delete(name) + end, opts = { desc = 'Memory: Delete session' } }, } --- Setup function for dadbod keymaps -function M.setup_dadbod_keymaps() - for _, mapping in ipairs(M.dadbod_keymaps) do - vim.keymap.set(mapping.mode, mapping.lhs, mapping.rhs, mapping.opts) - end -end - --- Setup function for session keymaps -function M.setup_session_keymaps() - -- Session keymaps will be overridden by mini.lua - local keymaps = M.session_keymaps or {} - for _, mapping in ipairs(keymaps) do - vim.keymap.set(mapping.mode, mapping.lhs, mapping.rhs, mapping.opts) - end -end - -- Scratch buffer keymaps +-- Buffer Operations: +-- - .: Toggle scratch buffer +-- - S: Select scratch buffer +-- - nh: Show notification history M.scratch_keymaps = { { mode = 'n', lhs = '.', rhs = function() require("snacks").scratch() end, opts = { desc = 'Toggle scratch buffer' } }, @@ -160,7 +212,38 @@ M.scratch_keymaps = { opts = { desc = 'Show notification history' } }, } +-- Snacks keymaps (explorer and other features) +-- File Explorer: +-- - e: Toggle explorer +-- - E: Focus current file in explorer +-- - o: Alternative key to focus current file +-- +-- Terminal: +-- - : Toggle terminal in float window +M.snacks_keymaps = { + -- Explorer + { mode = 'n', lhs = 'e', rhs = function() require('snacks.picker').explorer() end, opts = { desc = 'Explorer: Toggle' } }, + { mode = 'n', lhs = 'E', rhs = function() require('snacks.picker').explorer({ reveal = true }) end, opts = { desc = 'Explorer: Focus current file' } }, + { mode = 'n', lhs = 'o', rhs = function() require('snacks.picker').explorer({ reveal = true }) end, opts = { desc = 'Explorer: Focus current file' } }, + + -- Terminal + { mode = 'n', lhs = '', rhs = function() require('snacks').terminal.toggle() end, opts = { desc = 'Terminal: Toggle float window' } }, +} + -- Git signs keymaps (all under g for Git) +-- Navigation: +-- - ]c: Next hunk +-- - [c: Previous hunk +-- +-- Actions: +-- - gh: Preview hunk +-- - gs: Stage hunk +-- - gu: Undo stage hunk +-- - gr: Reset hunk +-- - gS: Stage buffer +-- - gR: Reset buffer +-- - gb: Blame line +-- - gd: Diff this M.gitsigns_keymaps = { -- Navigation { mode = 'n', lhs = ']c', rhs = function() @@ -194,6 +277,8 @@ function M.setup_gitsigns_keymaps() end -- Leap keymaps +-- 's' for bidirectional search (both forward and backward) +-- 'S' for searching in all windows M.leap_keymaps = { -- 's' for bidirectional search (both forward and backward) { mode = { 'n', 'x', 'o' }, lhs = 's', rhs = function() require('leap').leap {} end, @@ -215,11 +300,43 @@ function M.setup_leap_keymaps() end end +-- Setup functions for keymaps +function M.setup_dadbod_keymaps() + local keymaps = M.dadbod_keymaps or {} + for _, mapping in ipairs(keymaps) do + vim.keymap.set(mapping.mode, mapping.lhs, mapping.rhs, mapping.opts) + end +end + +function M.setup_session_keymaps() + local keymaps = M.session_keymaps or {} + for _, mapping in ipairs(keymaps) do + vim.keymap.set(mapping.mode, mapping.lhs, mapping.rhs, mapping.opts) + end +end + -- Initialize keymaps local function init_keymaps() -- Create an autocmd group for our keymaps local keymap_group = vim.api.nvim_create_augroup('custom_keymaps', { clear = true }) + -- Handle snacks explorer during buffer writes + vim.api.nvim_create_autocmd({ 'BufWritePre' }, { + group = keymap_group, + callback = function() + -- Pause snacks explorer updates during write + pcall(function() + local picker = require('snacks.picker') + if picker.is_open() then + picker.pause_updates() + vim.schedule(function() + picker.resume_updates() + end) + end + end) + end, + }) + -- Function to set up snacks explorer keymaps local function setup_explorer_keymaps() -- First remove any existing mappings @@ -291,11 +408,6 @@ local function init_keymaps() -- Set up session keymaps M.setup_session_keymaps() - -- Set up session keymaps - for _, mapping in ipairs(M.session_keymaps) do - vim.keymap.set(mapping.mode, mapping.lhs, mapping.rhs, mapping.opts) - end - -- Set up git signs keymaps M.setup_gitsigns_keymaps() @@ -306,5 +418,8 @@ end -- Initialize all keymaps init_keymaps() +-- Export `init_keymaps` as `M.setup` so `require('core.keymaps').setup()` works +M.setup = init_keymaps + -- Return the module return M diff --git a/lua/options/autocmds.lua b/lua/options/autocmds.lua index 50e78134..88b87336 100644 --- a/lua/options/autocmds.lua +++ b/lua/options/autocmds.lua @@ -1,23 +1,31 @@ -vim.api.nvim_create_autocmd('TextYankPost', { - desc = 'Highlight when yanking (copying) text', - group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }), - callback = function() - vim.highlight.on_yank() - end, -}) +---@diagnostic disable: undefined-global +local M = {} --- Auto format Go files on save -vim.api.nvim_create_autocmd("BufWritePre", { - pattern = "*.go", - callback = function() - vim.lsp.buf.format({ async = false }) - end, -}) +function M.setup() + -- Highlight when yanking (copying) text + vim.api.nvim_create_autocmd('TextYankPost', { + desc = 'Highlight when yanking (copying) text', + group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }), + callback = function() + vim.highlight.on_yank() + end, + }) --- Auto format Zig files on save -vim.api.nvim_create_autocmd("BufWritePre", { - pattern = "*.zig", - callback = function() - vim.lsp.buf.format({ async = false }) - end, -}) + -- Auto format Go files on save + vim.api.nvim_create_autocmd('BufWritePre', { + pattern = '*.go', + callback = function() + vim.lsp.buf.format({ async = false }) + end, + }) + + -- Auto format Zig files on save + vim.api.nvim_create_autocmd('BufWritePre', { + pattern = '*.zig', + callback = function() + vim.lsp.buf.format({ async = false }) + end, + }) +end + +return M diff --git a/lua/options/settings.lua b/lua/options/settings.lua index 4ceab1ea..b7fa2948 100644 --- a/lua/options/settings.lua +++ b/lua/options/settings.lua @@ -3,6 +3,7 @@ -- NOTE: You can change these options as you wish! -- For more options, you can see `:help option-list` +---@diagnostic disable: undefined-global -- Make line numbers default vim.opt.number = true vim.o.relativenumber = true @@ -54,7 +55,9 @@ vim.opt.wrap = false -- See `:help 'list'` -- and `:help 'listchars'` vim.opt.list = true -vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } +-- Do not set 'tab' in listchars so ibl can show its own indent guides +-- Use a vertical bar for tabs so ibl and listchars both show vertical guides +vim.opt.listchars = { tab = '│ ', trail = '·', nbsp = '␣' } -- Preview substitutions live, as you type! vim.opt.inccommand = 'split' @@ -69,7 +72,40 @@ vim.opt.scrolloff = 10 vim.opt.winbar = "" -- Set diagnostic signs -vim.fn.sign_define("DiagnosticSignError", { text = "", texthl = "DiagnosticSignError" }) -vim.fn.sign_define("DiagnosticSignWarn", { text = "", texthl = "DiagnosticSignWarn" }) -vim.fn.sign_define("DiagnosticSignInfo", { text = "", texthl = "DiagnosticSignInfo" }) -vim.fn.sign_define("DiagnosticSignHint", { text = "󰌵", texthl = "DiagnosticSignHint" }) +vim.diagnostic.config({ + signs = { + text = { + [vim.diagnostic.severity.ERROR] = "", + [vim.diagnostic.severity.WARN] = "", + [vim.diagnostic.severity.INFO] = "", + [vim.diagnostic.severity.HINT] = "󰌵", + }, + texthl = { + [vim.diagnostic.severity.ERROR] = "DiagnosticSignError", + [vim.diagnostic.severity.WARN] = "DiagnosticSignWarn", + [vim.diagnostic.severity.INFO] = "DiagnosticSignInfo", + [vim.diagnostic.severity.HINT] = "DiagnosticSignHint", + }, + }, +}) + +-- Add module interface for settings +local M = {} + +function M.setup() + -- Leader keys + vim.g.mapleader = ' ' + vim.g.maplocalleader = ' ' + + -- Ensure swapfile directory exists and configure swapfile settings + local swap_dir = vim.fn.stdpath('data') .. '/swapfiles' + if vim.fn.isdirectory(swap_dir) == 0 then + vim.fn.mkdir(swap_dir, 'p') + end + vim.opt.directory = swap_dir + vim.opt.swapfile = true + vim.opt.updatetime = 300 + vim.opt.updatecount = 100 +end + +return M diff --git a/lua/plugins/bufferline.lua b/lua/plugins/bufferline.lua index ce8af4b9..5f0ab160 100644 --- a/lua/plugins/bufferline.lua +++ b/lua/plugins/bufferline.lua @@ -2,55 +2,8 @@ return { 'akinsho/bufferline.nvim', version = "*", dependencies = 'nvim-tree/nvim-web-devicons', - opts = { - options = { - mode = "buffers", -- set to "tabs" to only show tabpages instead - numbers = "none", - close_command = "bdelete! %d", -- can be a string | function, | false see "Mouse actions" - right_mouse_command = "bdelete! %d", -- can be a string | function | false, see "Mouse actions" - left_mouse_command = "buffer %d", -- can be a string | function, | false see "Mouse actions" - middle_mouse_command = nil, -- can be a string | function, | false see "Mouse actions" - indicator = { - icon = '▎', -- this should be omitted if indicator style is not 'icon' - style = 'icon', - }, - buffer_close_icon = '󰅖', - modified_icon = '●', - close_icon = '', - left_trunc_marker = '', - right_trunc_marker = '', - max_name_length = 30, - max_prefix_length = 30, - truncate_names = true, - tab_size = 21, - diagnostics = "nvim_lsp", - diagnostics_update_in_insert = false, - diagnostics_indicator = function(count, level, diagnostics_dict, context) - return "("..count..")" - end, - offsets = { - { - filetype = "NvimTree", - text = "File Explorer", - text_align = "left", - separator = true - } - }, - color_icons = true, - show_buffer_icons = true, - show_buffer_close_icons = true, - show_close_icon = true, - show_tab_indicators = true, - show_duplicate_prefix = true, - persist_buffer_sort = true, - separator_style = "thin", - enforce_regular_tabs = false, - always_show_bufferline = true, - hover = { - enabled = true, - delay = 200, - reveal = {'close'} - }, - } - } + opts = require('plugins.bufferline.setup').opts, + config = function(_, opts) + require('plugins.bufferline.setup').setup() + end, } diff --git a/lua/plugins/bufferline/setup.lua b/lua/plugins/bufferline/setup.lua new file mode 100644 index 00000000..7cdd189d --- /dev/null +++ b/lua/plugins/bufferline/setup.lua @@ -0,0 +1,61 @@ +---@diagnostic disable: undefined-global +-- bufferline setup module +local M = {} + +M.opts = { + options = { + mode = "buffers", -- set to "tabs" to only show tabpages instead of buffers + numbers = "none", + close_command = "bdelete! %d", -- can be a string | function, | false see "Mouse actions" + right_mouse_command = "bdelete! %d", -- can be a string | function | false, see "Mouse actions" + left_mouse_command = "buffer %d", -- can be a string | function, | false see "Mouse actions" + middle_mouse_command = nil, -- can be a string | function | false see "Mouse actions" + indicator = { + icon = '▎', -- this should be omitted if indicator style is not 'icon' + style = 'icon', + }, + buffer_close_icon = '󰅖', + modified_icon = '●', + close_icon = '', + left_trunc_marker = '', + right_trunc_marker = '', + max_name_length = 30, + max_prefix_length = 30, + truncate_names = true, + tab_size = 21, + diagnostics = "nvim_lsp", + diagnostics_update_in_insert = false, + diagnostics_indicator = function(count, level, diagnostics_dict, context) + return "("..count..")" + end, + offsets = { + { + filetype = "NvimTree", + text = "File Explorer", + text_align = "left", + separator = true, + }, + }, + color_icons = true, + show_buffer_icons = true, + show_buffer_close_icons = true, + show_close_icon = true, + show_tab_indicators = true, + show_duplicate_prefix = true, + persist_buffer_sort = true, + separator_style = "thin", + enforce_regular_tabs = false, + always_show_bufferline = true, + hover = { + enabled = true, + delay = 200, + reveal = {'close'}, + }, + }, +} + +function M.setup() + require('bufferline').setup(M.opts) +end + +return M diff --git a/lua/plugins/cmp/setup.lua b/lua/plugins/cmp/setup.lua new file mode 100644 index 00000000..e02e754d --- /dev/null +++ b/lua/plugins/cmp/setup.lua @@ -0,0 +1,62 @@ +---@diagnostic disable: undefined-global +-- nvim-cmp setup module +local M = {} + +function M.setup() + local cmp = require 'cmp' + local luasnip = require 'luasnip' + luasnip.config.setup {} + + cmp.setup { + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + completion = { completeopt = 'menu,menuone,noinsert' }, + mapping = cmp.mapping.preset.insert { + [''] = cmp.mapping.select_next_item(), + [''] = cmp.mapping.select_prev_item(), + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.confirm { select = true }, + [''] = cmp.mapping.complete {}, + [''] = cmp.mapping(function() + if luasnip.expand_or_locally_jumpable() then + luasnip.expand_or_jump() + end + end, { 'i', 's' }), + [''] = cmp.mapping(function() + if luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + end + end, { 'i', 's' }), + }, + sources = { + { name = 'lazydev', group_index = 0 }, + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + { name = 'path' }, + { name = 'buffer' }, + }, + } + + -- Cmdline completion for search (/, ?) and command (:) + cmp.setup.cmdline({ '/', '?' }, { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = 'buffer' } + } + }) + + cmp.setup.cmdline(':', { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = 'path' } + }, { + { name = 'cmdline' } + }) + }) +end + +return M diff --git a/lua/plugins/coding.lua b/lua/plugins/coding.lua index 5e6f59b4..3b4e3809 100644 --- a/lua/plugins/coding.lua +++ b/lua/plugins/coding.lua @@ -1,252 +1,7 @@ +---@diagnostic disable: undefined-global return { - -- Go development - { - "ray-x/go.nvim", - dependencies = { -- optional packages - "ray-x/guihua.lua", - "neovim/nvim-lspconfig", - "nvim-treesitter/nvim-treesitter", - }, - config = function() - require("go").setup({ - -- Gopls configuration - lsp_cfg = { - settings = { - gopls = { - analyses = { - unusedparams = true, - shadow = true, - }, - staticcheck = true, - gofumpt = true, - usePlaceholders = true, - hints = { - assignVariableTypes = true, - compositeLiteralFields = true, - compositeLiteralTypes = true, - constantValues = true, - functionTypeParameters = true, - parameterNames = true, - rangeVariableTypes = true, - }, - }, - }, - }, - -- Format on save - gofmt = "gofumpt", - -- Import on save - goimports = true, - -- Enable linters - linter = "golangci-lint", - -- Test settings - test_runner = "go", - test_flags = {"-v"}, - -- Debug settings - dap_debug = true, - dap_debug_gui = true, - }) - - -- Run gofmt + goimports on save - local format_sync_grp = vim.api.nvim_create_augroup("GoFormat", {}) - vim.api.nvim_create_autocmd("BufWritePre", { - pattern = "*.go", - callback = function() - require("go.format").goimports() - end, - group = format_sync_grp, - }) - end, - event = {"CmdlineEnter"}, - ft = {"go", "gomod"}, - build = ':lua require("go.install").update_all_sync()', -- if you need to install/update all binaries - }, - - -- Zig development - { - "ziglang/zig.vim", - ft = "zig", - config = function() - -- Enable auto-formatting on save - vim.g.zig_fmt_autosave = 1 - end, - }, - - -- C development - { - "p00f/clangd_extensions.nvim", - dependencies = { - "neovim/nvim-lspconfig", - }, - ft = { "c", "cpp", "objc", "objcpp", "cuda", "proto" }, - opts = { - inlay_hints = { - inline = false, - }, - ast = { - role_icons = { - type = "🄣", - declaration = "🄓", - expression = "🄔", - statement = ";", - specifier = "🄢", - ["template argument"] = "🆃", - }, - kind_icons = { - Compound = "🄲", - Recovery = "🅁", - TranslationUnit = "🅄", - PackExpansion = "🄿", - TemplateTypeParm = "🅃", - TemplateTemplateParm = "🅃", - TemplateParamObject = "🅃", - }, - }, - }, - }, - - -- DAP (Debug Adapter Protocol) - { - "mfussenegger/nvim-dap", - dependencies = { - "rcarriga/nvim-dap-ui", - "theHamsta/nvim-dap-virtual-text", - "leoluz/nvim-dap-go", -- Go debug adapter - "nvim-neotest/nvim-nio", -- Required by nvim-dap-ui - }, - config = function() - local dap = require("dap") - local dapui = require("dapui") - - -- Set up Go debugging - require("dap-go").setup() - - -- Set up Python debugging - dap.adapters.python = { - type = 'executable', - command = 'debugpy-adapter', - } - - dap.configurations.python = { - { - type = 'python', - request = 'launch', - name = "Launch file", - program = "${file}", - pythonPath = function() - -- Try to detect python path from active virtual environment - if vim.env.VIRTUAL_ENV then - return vim.env.VIRTUAL_ENV .. "/bin/python" - end - -- Return system python if no venv - return '/usr/bin/python3' - end, - }, - } - - -- Set up C debugging with codelldb - dap.adapters.codelldb = { - type = 'server', - port = "${port}", - executable = { - command = 'codelldb', - args = {"--port", "${port}"}, - } - } - - dap.configurations.c = { - { - name = "Launch file", - type = "codelldb", - request = "launch", - program = function() - return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file') - end, - cwd = '${workspaceFolder}', - stopOnEntry = false, - args = {}, - }, - } - - -- Set up UI - dapui.setup({ - layouts = { - { - elements = { - { id = "scopes", size = 0.25 }, - { id = "breakpoints", size = 0.25 }, - { id = "stacks", size = 0.25 }, - { id = "watches", size = 0.25 }, - }, - position = "left", - size = 40 - }, - { - elements = { - { id = "repl", size = 0.5 }, - { id = "console", size = 0.5 }, - }, - position = "bottom", - size = 10 - }, - }, - }) - - -- Automatically open UI - dap.listeners.after.event_initialized["dapui_config"] = function() - dapui.open() - end - dap.listeners.before.event_terminated["dapui_config"] = function() - dapui.close() - end - dap.listeners.before.event_exited["dapui_config"] = function() - dapui.close() - end - - -- Add keymaps - vim.keymap.set("n", "pb", dap.toggle_breakpoint, { desc = "Toggle Breakpoint" }) - vim.keymap.set("n", "pc", dap.continue, { desc = "Continue Debug" }) - vim.keymap.set("n", "pn", dap.step_over, { desc = "Step Over" }) - vim.keymap.set("n", "pi", dap.step_into, { desc = "Step Into" }) - vim.keymap.set("n", "po", dap.step_out, { desc = "Step Out" }) - vim.keymap.set("n", "pr", dap.repl.open, { desc = "Debug REPL" }) - vim.keymap.set("n", "pl", dap.run_last, { desc = "Run Last Debug" }) - vim.keymap.set("n", "px", dapui.toggle, { desc = "Toggle Debug UI" }) - - -- Profiling commands - local function profile_go() - local file = vim.fn.expand('%:p') - local cmd = string.format('go test -cpuprofile cpu.prof -memprofile mem.prof -bench . %s', file) - vim.fn.system(cmd) - vim.cmd('split term://go tool pprof -http=:8080 cpu.prof') - end - - local function profile_python() - local file = vim.fn.expand('%:p') - local cmd = string.format('py-spy record -o profile.svg -f speedscope -- python %s', file) - vim.fn.system(cmd) - vim.cmd('!xdg-open profile.svg') - end - - local function profile_c() - local file = vim.fn.expand('%:p:r') -- Get file path without extension - local cmd = string.format('perf record -g ./%s && perf report -g graph', file) - vim.cmd('split term://' .. cmd) - end - - -- Add profiling keymaps based on filetype - vim.api.nvim_create_autocmd("FileType", { - pattern = { "go", "python", "c", "cpp" }, - callback = function() - local ft = vim.bo.filetype - if ft == "go" then - vim.keymap.set("n", "mp", profile_go, { buffer = true, desc = "Profile Go code" }) - elseif ft == "python" then - vim.keymap.set("n", "mp", profile_python, { buffer = true, desc = "Profile Python code" }) - elseif ft == "c" or ft == "cpp" then - vim.keymap.set("n", "mp", profile_c, { buffer = true, desc = "Profile C/C++ code" }) - end - end, - }) - end, - }, + require('plugins.coding.go'), + require('plugins.coding.zig'), + require('plugins.coding.clangd'), + require('plugins.coding.dap'), } diff --git a/lua/plugins/coding/clangd.lua b/lua/plugins/coding/clangd.lua new file mode 100644 index 00000000..19c62f25 --- /dev/null +++ b/lua/plugins/coding/clangd.lua @@ -0,0 +1,28 @@ +---@diagnostic disable: undefined-global +return { + "p00f/clangd_extensions.nvim", + dependencies = { "neovim/nvim-lspconfig" }, + ft = { "c", "cpp", "objc", "objcpp", "cuda", "proto" }, + opts = { + inlay_hints = { inline = false }, + ast = { + role_icons = { + type = "🄣", + declaration = "🄓", + expression = "🄔", + statement = ";", + specifier = "🄢", + ["template argument"] = "🆃", + }, + kind_icons = { + Compound = "🄲", + Recovery = "🅁", + TranslationUnit = "🅄", + PackExpansion = "🄿", + TemplateTypeParm = "🅃", + TemplateTemplateParm = "🅃", + TemplateParamObject = "🅃", + }, + }, + }, +} diff --git a/lua/plugins/coding/dap.lua b/lua/plugins/coding/dap.lua new file mode 100644 index 00000000..97f0a5a1 --- /dev/null +++ b/lua/plugins/coding/dap.lua @@ -0,0 +1,136 @@ +---@diagnostic disable: undefined-global +return { + "mfussenegger/nvim-dap", + dependencies = { + "rcarriga/nvim-dap-ui", + "theHamsta/nvim-dap-virtual-text", + "leoluz/nvim-dap-go", + "nvim-neotest/nvim-nio", + }, + config = function() + local dap = require("dap") + local dapui = require("dapui") + + -- Set up Go debugging + require("dap-go").setup() + + -- Set up Python debugging + dap.adapters.python = { + type = 'executable', + command = 'debugpy-adapter', + } + + dap.configurations.python = { + { + type = 'python', + request = 'launch', + name = "Launch file", + program = "${file}", + pythonPath = function() + if vim.env.VIRTUAL_ENV then + return vim.env.VIRTUAL_ENV .. "/bin/python" + end + return '/usr/bin/python3' + end, + }, + } + + -- Set up C debugging with codelldb + dap.adapters.codelldb = { + type = 'server', + port = "${port}", + executable = { + command = 'codelldb', + args = {"--port", "${port}"}, + }, + } + + dap.configurations.c = { + { + name = "Launch file", + type = "codelldb", + request = "launch", + program = function() + return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file') + end, + cwd = '${workspaceFolder}', + stopOnEntry = false, + args = {}, + }, + } + + -- Set up UI + dapui.setup({ + layouts = { + { + elements = { + { id = "scopes", size = 0.25 }, + { id = "breakpoints", size = 0.25 }, + { id = "stacks", size = 0.25 }, + { id = "watches", size = 0.25 }, + }, + position = "left", + size = 40, + }, + { + elements = { + { id = "repl", size = 0.5 }, + { id = "console", size = 0.5 }, + }, + position = "bottom", + size = 10, + }, + }, + }) + + -- Automatically open/close UI on session events + dap.listeners.after.event_initialized['dapui_config'] = dapui.open + dap.listeners.before.event_terminated['dapui_config'] = dapui.close + dap.listeners.before.event_exited['dapui_config'] = dapui.close + + -- Add keymaps + vim.keymap.set('n', 'pb', dap.toggle_breakpoint, { desc = 'Toggle Breakpoint' }) + vim.keymap.set('n', 'pc', dap.continue, { desc = 'Continue Debug' }) + vim.keymap.set('n', 'pn', dap.step_over, { desc = 'Step Over' }) + vim.keymap.set('n', 'pi', dap.step_into, { desc = 'Step Into' }) + vim.keymap.set('n', 'po', dap.step_out, { desc = 'Step Out' }) + vim.keymap.set('n', 'pr', dap.repl.open, { desc = 'Debug REPL' }) + vim.keymap.set('n', 'pl', dap.run_last, { desc = 'Run Last Debug' }) + vim.keymap.set('n', 'px', dapui.toggle, { desc = 'Toggle Debug UI' }) + + -- Profiling commands + local function profile_go() + local file = vim.fn.expand('%:p') + local cmd = string.format('go test -cpuprofile cpu.prof -memprofile mem.prof -bench . %s', file) + vim.fn.system(cmd) + vim.cmd('split term://go tool pprof -http=:8080 cpu.prof') + end + + local function profile_python() + local file = vim.fn.expand('%:p') + local cmd = string.format('py-spy record -o profile.svg -f speedscope -- python %s', file) + vim.fn.system(cmd) + vim.cmd('!xdg-open profile.svg') + end + + local function profile_c() + local file = vim.fn.expand('%:p:r') + local cmd = string.format('perf record -g ./%s && perf report -g graph', file) + vim.cmd('split term://' .. cmd) + end + + vim.api.nvim_create_autocmd('FileType', { + pattern = { 'go', 'python', 'c', 'cpp' }, + callback = function() + local ft = vim.bo.filetype + if ft == 'go' then + vim.keymap.set('n', 'mp', profile_go, { buffer = true, desc = 'Profile Go code' }) + elseif ft == 'python' then + vim.keymap.set('n', 'mp', profile_python, { buffer = true, desc = 'Profile Python code' }) + elseif ft == 'c' or ft == 'cpp' then + vim.keymap.set('n', 'mp', profile_c, { buffer = true, desc = 'Profile C/C++ code' }) + end + end, + }) + end, +} diff --git a/lua/plugins/coding/go.lua b/lua/plugins/coding/go.lua new file mode 100644 index 00000000..6d1b83a2 --- /dev/null +++ b/lua/plugins/coding/go.lua @@ -0,0 +1,24 @@ +---@diagnostic disable: undefined-global +return { + "ray-x/go.nvim", + dependencies = { + "ray-x/guihua.lua", + "neovim/nvim-lspconfig", + "nvim-treesitter/nvim-treesitter", + }, + config = function() + require("go").setup({ + lsp_cfg = false, + gofmt = false, + goimports = false, + linter = "golangci-lint", + test_runner = "go", + test_flags = { "-v" }, + dap_debug = true, + dap_debug_gui = true, + }) + end, + event = { "CmdlineEnter" }, + ft = { "go", "gomod" }, + build = ':lua require("go.install").update_all_sync()', +} diff --git a/lua/plugins/coding/zig.lua b/lua/plugins/coding/zig.lua new file mode 100644 index 00000000..2690feda --- /dev/null +++ b/lua/plugins/coding/zig.lua @@ -0,0 +1,9 @@ +---@diagnostic disable: undefined-global +return { + "ziglang/zig.vim", + ft = "zig", + config = function() + -- Enable auto-formatting on save + vim.g.zig_fmt_autosave = 1 + end, +} diff --git a/lua/plugins/gruvbox.lua b/lua/plugins/colorscheme.lua similarity index 100% rename from lua/plugins/gruvbox.lua rename to lua/plugins/colorscheme.lua diff --git a/lua/plugins/commentary.lua b/lua/plugins/commentary.lua new file mode 100644 index 00000000..cf2c32c9 --- /dev/null +++ b/lua/plugins/commentary.lua @@ -0,0 +1,6 @@ +return { + 'numToStr/Comment.nvim', + config = function() + require('Comment').setup() + end, +} diff --git a/lua/plugins/conform.lua b/lua/plugins/conform.lua index b7b0c09e..a6b1caaf 100644 --- a/lua/plugins/conform.lua +++ b/lua/plugins/conform.lua @@ -1,5 +1,7 @@ +---@diagnostic disable: undefined-global return { -- Autoformat 'stevearc/conform.nvim', + enabled = false, event = { 'BufWritePre' }, cmd = { 'ConformInfo' }, keys = { @@ -18,7 +20,7 @@ return { -- Autoformat -- Disable "format_on_save lsp_fallback" for languages that don't -- have a well standardized coding style. You can add additional -- languages here or re-enable it for the disabled ones. - local disable_filetypes = { c = true, cpp = true } + local disable_filetypes = {} -- C and C++ now enabled for format-on-save local lsp_format_opt if disable_filetypes[vim.bo[bufnr].filetype] then lsp_format_opt = 'never' @@ -32,6 +34,9 @@ return { -- Autoformat end, formatters_by_ft = { lua = { 'stylua' }, + go = { 'gofumpt', 'goimports' }, -- Run gofumpt first, then goimports + c = { 'clang_format' }, -- Add clang-format for C + cpp = { 'clang_format' }, -- Add clang-format for C++ -- Conform can also run multiple formatters sequentially -- python = { "isort", "black" }, -- diff --git a/lua/plugins/garbage-day.lua b/lua/plugins/garbage-day.lua index 25134296..cfdb687a 100644 --- a/lua/plugins/garbage-day.lua +++ b/lua/plugins/garbage-day.lua @@ -1,6 +1,6 @@ -- Garbage collector that stops inactive LSP clients to free RAM return { - 'zeioth/garbage-day.nvim', + --[[ 'zeioth/garbage-day.nvim', dependencies = 'neovim/nvim-lspconfig', event = 'VeryLazy', opts = { @@ -17,5 +17,5 @@ return { pause = 110, -- Lower pause for more frequent but shorter GC pauses step_mul = 100, -- Lower step multiplier for smoother collection }, - }, + }, ]] } diff --git a/lua/plugins/gitsigns/setup.lua b/lua/plugins/gitsigns/setup.lua new file mode 100644 index 00000000..3c8716d6 --- /dev/null +++ b/lua/plugins/gitsigns/setup.lua @@ -0,0 +1,28 @@ +---@diagnostic disable: undefined-global +-- GitSigns setup module +local M = {} + +function M.setup() + require('gitsigns').setup({ + signs = { + add = { text = '+' }, + change = { text = '~' }, + delete = { text = '-' }, + topdelete = { text = '-' }, + changedelete = { text = '~' }, + }, + signcolumn = true, + numhl = false, + linehl = false, + word_diff = false, + watch_gitdir = { interval = 1000, follow_files = true }, + attach_to_untracked = true, + current_line_blame = false, + sign_priority = 6, + update_debounce = 100, + status_formatter = nil, + preview_config = { border = 'single', style = 'minimal', relative = 'cursor', row = 0, col = 1 }, + }) +end + +return M diff --git a/lua/plugins/indent-blankline.lua b/lua/plugins/indent-blankline.lua new file mode 100644 index 00000000..c4dc25ab --- /dev/null +++ b/lua/plugins/indent-blankline.lua @@ -0,0 +1,8 @@ +-- Indentation guides for Neovim +return { + 'lukas-reineke/indent-blankline.nvim', + main = 'ibl', + event = { 'BufReadPre', 'BufNewFile' }, + opts = {}, -- Use ibl's defaults for best compatibility + +} diff --git a/lua/plugins/lsp/servers.lua b/lua/plugins/lsp/servers.lua new file mode 100644 index 00000000..3b8d9606 --- /dev/null +++ b/lua/plugins/lsp/servers.lua @@ -0,0 +1,69 @@ +---@diagnostic disable: undefined-global +-- LSP servers configuration + +-- Go flags for build tags +local go_flags = 'integration' +local gopls_build_flags = go_flags ~= '' and { '-tags=' .. go_flags } or {} + +return { + -- Python + pyright = {}, + -- Go + gopls = { + settings = { + gopls = { + analyses = { + unusedparams = true, + }, + staticcheck = false, + gofumpt = false, + hints = { + assignVariableTypes = false, + compositeLiteralFields = false, + compositeLiteralTypes = false, + constantValues = false, + functionTypeParameters = false, + parameterNames = false, + rangeVariableTypes = false, + }, + vulncheck = 'Off', + completionBudget = '100ms', + symbolMatcher = 'FastFuzzy', + symbolStyle = 'Dynamic', + diagnosticsDelay = '500ms', + buildFlags = gopls_build_flags, + }, + }, + }, + -- Lua + lua_ls = { + settings = { + Lua = { + runtime = { version = 'LuaJIT' }, + diagnostics = { + globals = { 'vim' }, + }, + workspace = { + checkThirdParty = false, + library = { + [vim.fn.expand '$VIMRUNTIME/lua'] = true, + [vim.fn.stdpath 'config' .. '/lua'] = true, + }, + }, + telemetry = { enable = false }, + }, + }, + }, + -- C/C++ + clangd = {}, + + -- SQL + sqls = { + settings = { + sqls = { + connections = {}, + lowercaseKeywords = true, + }, + }, + }, +} diff --git a/lua/plugins/lsp/setup.lua b/lua/plugins/lsp/setup.lua new file mode 100644 index 00000000..d5cb7b90 --- /dev/null +++ b/lua/plugins/lsp/setup.lua @@ -0,0 +1,68 @@ +---@diagnostic disable: undefined-global +-- LSP setup (mason + lspconfig) + +local M = {} + +function M.setup() + local servers = require('plugins.lsp.servers') + + -- nvim-cmp capabilities + local capabilities = vim.lsp.protocol.make_client_capabilities() + capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) + + -- Setup mason-lspconfig + local mason_lspconfig = require('mason-lspconfig') + mason_lspconfig.setup { ensure_installed = vim.tbl_keys(servers) } + + mason_lspconfig.setup_handlers { + function(server_name) + local config = servers[server_name] or {} + config.capabilities = capabilities + + -- Default on_attach to setup keymaps & navic + local function on_attach(client, bufnr) + require('core.keymaps').setup_lsp_keymaps(bufnr) + -- Attach navic if available + if client.server_capabilities.documentSymbolProvider then + require('nvim-navic').attach(client, bufnr) + end + end + config.on_attach = on_attach + + -- Disable gopls semantic tokens to avoid issues + if server_name == 'gopls' and config.on_attach then + local orig_on_attach = config.on_attach + config.on_attach = function(client, bufnr) + client.server_capabilities.semanticTokensProvider = nil + orig_on_attach(client, bufnr) + end + end + + require('lspconfig')[server_name].setup(config) + end, + } + + -- Override references handler + vim.lsp.handlers['textDocument/references'] = function(err, result, ctx, config) + if not result or vim.tbl_isempty(result) then + vim.notify('No references found', vim.log.levels.INFO) + else + require('telescope.builtin').lsp_references() + end + end + + -- Override semanticTokens/full + vim.lsp.handlers['textDocument/semanticTokens/full'] = function(err, result, ctx, cfg) + if err or not result then return end + local client = vim.lsp.get_client_by_id(ctx.client_id) + if not client then return end + local bufnr = ctx.bufnr + local highlighter = vim.lsp.semantic_tokens.create_highlighter(bufnr, client) + if not highlighter then return end + pcall(function() + highlighter:process_response(result, client, ctx.request.version) + end) + end +end + +return M diff --git a/lua/plugins/lualine.lua b/lua/plugins/lualine.lua new file mode 100644 index 00000000..2d2c0447 --- /dev/null +++ b/lua/plugins/lualine.lua @@ -0,0 +1,73 @@ +---@diagnostic disable: undefined-global +return { + 'nvim-lualine/lualine.nvim', + dependencies = { 'nvim-tree/nvim-web-devicons' }, + config = function() + require('lualine').setup { + options = { + theme = 'gruvbox', + section_separators = { left = '', right = '' }, + component_separators = { left = '', right = '' }, + }, + sections = { + lualine_a = { 'mode' }, + lualine_b = { 'branch', 'diff' }, + lualine_c = { + 'filename', + { + 'diagnostics', + sources = { 'nvim_diagnostic' }, + sections = { 'error', 'warn', 'info', 'hint' }, + symbols = { error = 'E:', warn = 'W:', info = 'I:', hint = 'H:' }, + colored = true, + update_in_insert = false, + always_visible = true, + }, + { + function() + -- Get the navic location with a more reliable approach + local location = require('nvim-navic').get_location() + if location and location ~= "" then + return "📍 " .. location -- Add an icon for better visibility + end + return "" + end, + cond = function() + return package.loaded['nvim-navic'] and require('nvim-navic').is_available() + end, + color = { fg = '#a3be8c', gui = 'bold' }, -- Make it more visible with color + }, + }, + lualine_x = { + { + function() + local qf_list = vim.fn.getqflist() + local count = #qf_list + if count > 0 then + return 'QF:' .. count + else + return '' + end + end, + icon = '', + color = { fg = '#d7af5f', gui = 'bold' }, + }, + 'encoding', + 'fileformat', + 'filetype', + }, + lualine_y = { 'progress' }, + lualine_z = { 'location' }, + }, + inactive_sections = { + lualine_a = {}, + lualine_b = {}, + lualine_c = { 'filename' }, + lualine_x = { 'location' }, + lualine_y = {}, + lualine_z = {}, + }, + extensions = { 'quickfix' }, + } + end, +} diff --git a/lua/plugins/lualine/setup.lua b/lua/plugins/lualine/setup.lua new file mode 100644 index 00000000..5420300e --- /dev/null +++ b/lua/plugins/lualine/setup.lua @@ -0,0 +1,72 @@ +---@diagnostic disable: undefined-global +-- lualine setup module +local M = {} + +function M.setup() + require('lualine').setup { + options = { + theme = 'gruvbox', + section_separators = { left = '', right = '' }, + component_separators = { left = '', right = '' }, + }, + sections = { + lualine_a = { 'mode' }, + lualine_b = { 'branch', 'diff' }, + lualine_c = { + 'filename', + { + 'diagnostics', + sources = { 'nvim_diagnostic' }, + sections = { 'error', 'warn', 'info', 'hint' }, + symbols = { error = 'E:', warn = 'W:', info = 'I:', hint = 'H:' }, + colored = true, + update_in_insert = false, + always_visible = true, + }, + { + function() + local location = require('nvim-navic').get_location() + if location and location ~= '' then + return '📍 ' .. location + end + return '' + end, + cond = function() + return package.loaded['nvim-navic'] and require('nvim-navic').is_available() + end, + color = { fg = '#a3be8c', gui = 'bold' }, + }, + }, + lualine_x = { + { + function() + local qf_list = vim.fn.getqflist() + local count = #qf_list + if count > 0 then + return 'QF:' .. count + end + return '' + end, + icon = '', + color = { fg = '#d7af5f', gui = 'bold' }, + }, + 'encoding', + 'fileformat', + 'filetype', + }, + lualine_y = { 'progress' }, + lualine_z = { 'location' }, + }, + inactive_sections = { + lualine_a = {}, + lualine_b = {}, + lualine_c = { 'filename' }, + lualine_x = { 'location' }, + lualine_y = {}, + lualine_z = {}, + }, + extensions = { 'quickfix' }, + } +end + +return M diff --git a/lua/plugins/null-ls.lua b/lua/plugins/null-ls.lua index ce2dff06..3c41d5a8 100644 --- a/lua/plugins/null-ls.lua +++ b/lua/plugins/null-ls.lua @@ -5,64 +5,6 @@ return { 'jay-babu/mason-null-ls.nvim', }, config = function() - local null_ls = require 'null-ls' - local null_ls_utils = require 'null-ls.utils' - - local formatting = null_ls.builtins.formatting - local diagnostics = null_ls.builtins.diagnostics - - null_ls.setup { - root_dir = null_ls_utils.root_pattern('.null-ls-root', 'Makefile', '.git'), - timeout = 10000, -- Reduced timeout - debounce = 250, -- Add debounce to prevent excessive updates - update_in_insert = false, -- Only update diagnostics when leaving insert mode - sources = { - -- Go formatting and linting - formatting.gofumpt.with({ - extra_args = { "-extra" }, -- More aggressive formatting - }), - formatting.goimports.with({ - args = { "-local", "", "-w", "$FILENAME" }, -- Optimize imports - }), - diagnostics.golangci_lint.with({ - diagnostics_format = '#{m}', - extra_args = { - '--fast', - '--max-issues-per-linter', '30', - '--max-same-issues', '4', - '--max-same-issues-per-linter', '0', -- Disable duplicate issue reporting per linter - '--fix=false', -- Don't try to fix issues - '--tests=false', -- Don't analyze tests for faster results - '--print-issued-lines=false', -- Don't print the lines that triggered issues - '--timeout=10s', -- Timeout after 10 seconds - '--out-format=json', -- Use JSON format for faster parsing - }, - method = null_ls.methods.DIAGNOSTICS_ON_SAVE, -- Only run on save - timeout = 10000, -- 10 second timeout - }), - - -- Web formatting - formatting.prettier.with { - filetypes = { 'css', 'scss', 'html', 'markdown', 'yaml', 'yml' }, - extra_args = { - '--bracket-same-line', - '--trailing-comma', 'all', - '--tab-width', '2', - '--semi', - '--single-quote', - }, - }, - - -- Shell formatting - formatting.shfmt.with { - extra_args = { '-i', '2', '-ci', '-bn' }, - }, - - -- SQL formatting - formatting.sqlfluff.with { - extra_args = { '--dialect', 'tsql' }, - }, - }, - } + require('plugins.null-ls.setup').setup() end, } diff --git a/lua/plugins/null-ls/setup.lua b/lua/plugins/null-ls/setup.lua new file mode 100644 index 00000000..d36235ed --- /dev/null +++ b/lua/plugins/null-ls/setup.lua @@ -0,0 +1,51 @@ +---@diagnostic disable: undefined-global +-- null-ls setup module +local M = {} + +function M.setup() + local null_ls = require 'null-ls' + local null_ls_utils = require 'null-ls.utils' + local formatting = null_ls.builtins.formatting + local diagnostics = null_ls.builtins.diagnostics + + null_ls.setup { + root_dir = null_ls_utils.root_pattern('.null-ls-root', 'Makefile', '.git'), + timeout = 10000, + debounce = 250, + update_in_insert = false, + sources = { + formatting.gofumpt.with({ extra_args = { "-extra" } }), + formatting.goimports.with({ args = { "-local", "", "-w", "$FILENAME" } }), + diagnostics.golangci_lint.with({ + diagnostics_format = '#{m}', + extra_args = { + '--fast', + '--max-issues-per-linter', '30', + '--max-same-issues', '4', + '--max-same-issues-per-linter', '0', + '--fix=false', + '--tests=false', + '--print-issued-lines=false', + '--timeout=10s', + '--out-format=json', + }, + method = null_ls.methods.DIAGNOSTICS_ON_SAVE, + timeout = 10000, + }), + formatting.prettier.with { + filetypes = { 'css', 'scss', 'html', 'markdown', 'yaml', 'yml' }, + extra_args = { + '--bracket-same-line', + '--trailing-comma', 'all', + '--tab-width', '2', + '--semi', + '--single-quote', + }, + }, + formatting.shfmt.with { extra_args = { '-i', '2', '-ci', '-bn' } }, + formatting.sqlfluff.with { extra_args = { '--dialect', 'tsql' } }, + }, + } +end + +return M diff --git a/lua/plugins/nvim-autopairs.lua b/lua/plugins/nvim-autopairs.lua index 4bbf9ea8..aa6ea965 100644 --- a/lua/plugins/nvim-autopairs.lua +++ b/lua/plugins/nvim-autopairs.lua @@ -1,35 +1,8 @@ return { 'windwp/nvim-autopairs', event = "InsertEnter", -- Only load in insert mode - opts = { - check_ts = true, - ts_config = { - lua = { "string" }, - javascript = { "template_string" }, - java = false, - }, - ignored_next_char = "[%w%.]", - enable_moveright = false, -- Don't move cursor after pair - enable_afterquote = false, -- Don't add pairs after quotes - enable_check_bracket_line = true, - enable_bracket_in_quote = false, - map_cr = true, - map_bs = true, - map_c_h = false, - map_c_w = false, - disable_in_macro = true, - disable_in_visualblock = true, - enable_abbr = false, - }, - config = function(_, opts) - local npairs = require('nvim-autopairs') - npairs.setup(opts) - - -- Only enable completion integration if cmp is loaded - local ok, cmp = pcall(require, 'cmp') - if ok then - local cmp_autopairs = require('nvim-autopairs.completion.cmp') - cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done()) - end + opts = nil, + config = function() + require('plugins.nvim-autopairs.setup').setup(require('plugins.nvim-autopairs.setup').opts) end, } diff --git a/lua/plugins/nvim-autopairs/setup.lua b/lua/plugins/nvim-autopairs/setup.lua new file mode 100644 index 00000000..f4ed31f5 --- /dev/null +++ b/lua/plugins/nvim-autopairs/setup.lua @@ -0,0 +1,36 @@ +---@diagnostic disable: undefined-global +-- nvim-autopairs setup module +local M = {} + +M.opts = { + check_ts = true, + ts_config = { + lua = { "string" }, + javascript = { "template_string" }, + java = false, + }, + ignored_next_char = "[%w%.]", + enable_moveright = false, + enable_afterquote = false, + enable_check_bracket_line = true, + enable_bracket_in_quote = false, + map_cr = true, + map_bs = true, + map_c_h = false, + map_c_w = false, + disable_in_macro = true, + disable_in_visualblock = true, + enable_abbr = false, +} + +function M.setup(opts) + local npairs = require('nvim-autopairs') + npairs.setup(opts) + local ok, cmp = pcall(require, 'cmp') + if ok then + local cmp_autopairs = require('nvim-autopairs.completion.cmp') + cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done()) + end +end + +return M diff --git a/lua/plugins/nvim-cmp.lua b/lua/plugins/nvim-cmp.lua index 787e29e9..62b45888 100644 --- a/lua/plugins/nvim-cmp.lua +++ b/lua/plugins/nvim-cmp.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: undefined-global return { -- Autocompletion 'hrsh7th/nvim-cmp', event = 'InsertEnter', @@ -35,81 +36,6 @@ return { -- Autocompletion 'hrsh7th/cmp-path', }, config = function() - -- See `:help cmp` - local cmp = require 'cmp' - local luasnip = require 'luasnip' - luasnip.config.setup {} - - cmp.setup { - snippet = { - expand = function(args) - luasnip.lsp_expand(args.body) - end, - }, - completion = { completeopt = 'menu,menuone,noinsert' }, - - -- For an understanding of why these mappings were - -- chosen, you will need to read `:help ins-completion` - -- - -- No, but seriously. Please read `:help ins-completion`, it is really good! - mapping = cmp.mapping.preset.insert { - -- Select the [n]ext item - [''] = cmp.mapping.select_next_item(), - -- Select the [p]revious item - [''] = cmp.mapping.select_prev_item(), - - -- Scroll the documentation window [b]ack / [f]orward - [''] = cmp.mapping.scroll_docs(-4), - [''] = cmp.mapping.scroll_docs(4), - - -- Accept ([y]es) the completion. - -- This will auto-import if your LSP supports it. - -- This will expand snippets if the LSP sent a snippet. - [''] = cmp.mapping.confirm { select = true }, - - -- If you prefer more traditional completion keymaps, - -- you can uncomment the following lines - --[''] = cmp.mapping.confirm { select = true }, - --[''] = cmp.mapping.select_next_item(), - --[''] = cmp.mapping.select_prev_item(), - - -- Manually trigger a completion from nvim-cmp. - -- Generally you don't need this, because nvim-cmp will display - -- completions whenever it has completion options available. - [''] = cmp.mapping.complete {}, - - -- Think of as moving to the right of your snippet expansion. - -- So if you have a snippet that's like: - -- function $name($args) - -- $body - -- end - -- - -- will move you to the right of each of the expansion locations. - -- is similar, except moving you backwards. - [''] = cmp.mapping(function() - if luasnip.expand_or_locally_jumpable() then - luasnip.expand_or_jump() - end - end, { 'i', 's' }), - [''] = cmp.mapping(function() - if luasnip.locally_jumpable(-1) then - luasnip.jump(-1) - end - end, { 'i', 's' }), - - -- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see: - -- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps - }, - sources = { - { - name = 'lazydev', - -- set group index to 0 to skip loading LuaLS completions as lazydev recommends it - group_index = 0, - }, - { name = 'nvim_lsp' }, - { name = 'luasnip' }, - { name = 'path' }, - }, - } + require('plugins.cmp.setup').setup() end, } diff --git a/lua/plugins/nvim-lspconfig.lua b/lua/plugins/nvim-lspconfig.lua index 8f367092..55134df3 100644 --- a/lua/plugins/nvim-lspconfig.lua +++ b/lua/plugins/nvim-lspconfig.lua @@ -1,3 +1,6 @@ +---@diagnostic disable: undefined-global +local go_flags = 'integration' -- add the tags here, instead of searching it below + return { -- Main LSP Configuration 'neovim/nvim-lspconfig', @@ -14,24 +17,24 @@ return { 'lua-language-server', 'marksman', -- Go tools - 'gopls', -- Go LSP - 'gofumpt', -- Stricter Go formatter - 'goimports', -- Go import manager - 'golangci-lint', -- Go linter - 'delve', -- Go debugger + 'gopls', -- Go LSP + 'gofumpt', -- Stricter Go formatter + 'goimports', -- Go import manager + 'golangci-lint', -- Go linter + 'delve', -- Go debugger -- Zig tools - 'zls', -- Zig LSP + 'zls', -- Zig LSP -- C tools - 'clangd', -- C/C++ LSP - 'clang-format', -- C/C++ formatter - 'codelldb', -- Native code debugger + 'clangd', -- C/C++ LSP + 'clang-format', -- C/C++ formatter + 'codelldb', -- Native code debugger -- Python tools - 'pyright', -- Python LSP - 'black', -- Python formatter - 'ruff', -- Python linter - 'debugpy', -- Python debugger + 'pyright', -- Python LSP + 'black', -- Python formatter + 'ruff', -- Python linter + 'debugpy', -- Python debugger -- SQL tools - 'sqls', -- Advanced SQL LSP + 'sqls', -- Advanced SQL LSP }, auto_update = true, run_on_start = true, @@ -45,213 +48,17 @@ return { -- Allows extra capabilities provided by nvim-cmp 'hrsh7th/cmp-nvim-lsp', + + -- Add nvim-navic for breadcrumbs + { 'SmiteshP/nvim-navic', config = function() + require('nvim-navic').setup { + highlight = true, + separator = ' > ', + depth_limit = 5, + } + end }, }, config = function() - -- Brief aside: **What is LSP?** - -- - -- LSP is an initialism you've probably heard, but might not understand what it is. - -- - -- LSP stands for Language Server Protocol. It's a protocol that helps editors - -- and language tooling communicate in a standardized fashion. - -- - -- See `:help lsp` for more details. - - -- Enable the following language servers - -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. - -- - -- Add any additional override configuration in the following tables. Available keys are: - -- - cmd (table): Override the default command used to start the server - -- - filetypes (table): Override the default list of associated filetypes for the server - -- - capabilities (table): Override fields in capabilities. Can be used to disable certain LSP features. - -- - settings (table): Override the default settings passed to the server. Can be used to disable diagnostics. - local servers = { - -- Python - pyright = {}, - -- Go - gopls = { - settings = { - gopls = { - analyses = { - unusedparams = true, - }, - staticcheck = false, -- Let golangci-lint handle this - gofumpt = false, -- Let null-ls handle this - hints = { - assignVariableTypes = false, -- Disable hints for better performance - compositeLiteralFields = false, - compositeLiteralTypes = false, - constantValues = false, - functionTypeParameters = false, - parameterNames = false, - rangeVariableTypes = false, - }, - vulncheck = "Off", -- Disable vulnerability checking - completionBudget = "100ms", -- Limit completion time - symbolMatcher = "FastFuzzy", -- Faster symbol matching - symbolStyle = "Dynamic", - usePlaceholders = false, -- Disable placeholders for better performance - matcher = "Fuzzy", -- Faster matching algorithm - diagnosticsDelay = "500ms", -- Add slight delay to batch diagnostics - }, - }, - }, - -- Lua - lua_ls = { - settings = { - Lua = { - diagnostics = { - globals = { 'vim' }, - }, - workspace = { - library = { - [vim.fn.expand('$VIMRUNTIME/lua')] = true, - [vim.fn.stdpath('config') .. '/lua'] = true, - }, - }, - }, - }, - }, - -- SQL - Advanced SQL language server with better completion - sqls = { - settings = { - sqls = { - connections = {}, -- Will be populated by dadbod - lowercaseKeywords = true, -- Format keywords to lowercase - }, - }, - }, - } - - -- nvim-cmp supports additional completion capabilities, so broadcast that to servers - local capabilities = vim.lsp.protocol.make_client_capabilities() - capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) - - -- Single LSP attach handler for all functionality - vim.api.nvim_create_autocmd('LspAttach', { - group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), - callback = function(args) - -- Remove any diagnostic keymaps - pcall(vim.keymap.del, 'n', 'e', { buffer = args.buf }) - - -- Get the client - local client = vim.lsp.get_client_by_id(args.data.client_id) - if not client then return end - - -- Disable semantic tokens for gopls - if client.name == "gopls" then - client.server_capabilities.semanticTokensProvider = nil - end - - -- Only set up document formatting for null-ls - if client.name ~= "null-ls" then - client.server_capabilities.documentFormattingProvider = false - end - - -- Set up LSP keymaps - require('core.keymaps').setup_lsp_keymaps(args.buf) - - -- Override the built-in LSP handler for references to use telescope - vim.lsp.handlers['textDocument/references'] = function(_, result, ctx) - if not result or vim.tbl_isempty(result) then - vim.notify('No references found') - else - require('telescope.builtin').lsp_references() - end - end - - -- Set up document highlight on hover only if the server supports it - if client.server_capabilities.documentHighlightProvider then - local highlight_group = vim.api.nvim_create_augroup('lsp_document_highlight_' .. args.buf, { clear = true }) - vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { - group = highlight_group, - buffer = args.buf, - callback = function() - -- Check if the client is still attached and valid - if vim.lsp.buf_get_clients(args.buf)[1] then - vim.lsp.buf.document_highlight() - end - end, - }) - vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { - group = highlight_group, - buffer = args.buf, - callback = function() - -- Check if the client is still attached and valid - if vim.lsp.buf_get_clients(args.buf)[1] then - vim.lsp.buf.clear_references() - end - end, - }) - end - end, - }) - - -- Ensure the servers above are installed - local mason_lspconfig = require 'mason-lspconfig' - - mason_lspconfig.setup { - ensure_installed = vim.tbl_keys(servers), - } - - -- Custom semantic tokens handler for gopls - local semantic_tokens_handler = function(err, result, ctx, config) - local client = vim.lsp.get_client_by_id(ctx.client_id) - if not client then return end - - -- Check if client has the required semantic tokens capabilities - local semantic_tokens = client.server_capabilities.semanticTokensProvider - if not semantic_tokens or not semantic_tokens.legend then - -- If no legend is provided, disable semantic tokens for this client - client.server_capabilities.semanticTokensProvider = nil - return - end - - -- If we have a valid legend, proceed with default handler - vim.lsp.semantic_tokens.on_full(err, result, ctx, config) - end - - mason_lspconfig.setup_handlers { - function(server_name) - local server_config = servers[server_name] or {} - - -- For gopls, add debug logging - if server_name == "gopls" then - -- Create a custom on_attach that disables semantic tokens - local orig_on_attach = server_config.on_attach - server_config.on_attach = function(client, bufnr) - -- Disable semantic tokens for this client - client.server_capabilities.semanticTokensProvider = nil - -- Call original on_attach if it exists - if orig_on_attach then - orig_on_attach(client, bufnr) - end - end - end - - server_config.capabilities = capabilities - require('lspconfig')[server_name].setup(server_config) - end, - } - - -- Override the semantic tokens handler to be more resilient - vim.lsp.handlers['textDocument/semanticTokens/full'] = function(err, result, ctx, config) - -- If there's an error or no result, just return - if err or not result then return end - - local client = vim.lsp.get_client_by_id(ctx.client_id) - if not client then return end - - local bufnr = ctx.bufnr - if not bufnr then return end - - -- Get the highlighter safely - local highlighter = vim.lsp.semantic_tokens.create_highlighter(bufnr, client) - if not highlighter then return end - - -- Process the response safely - pcall(function() - highlighter:process_response(result, client, ctx.request.version) - end) - end + require('plugins.lsp.setup').setup() end, } diff --git a/lua/plugins/nvim-treesitter.lua b/lua/plugins/nvim-treesitter.lua index bea35d3a..fdb86626 100644 --- a/lua/plugins/nvim-treesitter.lua +++ b/lua/plugins/nvim-treesitter.lua @@ -5,8 +5,10 @@ return { -- Highlight, edit, and navigate code -- [[ Configure Treesitter ]] See `:help nvim-treesitter` opts = { ensure_installed = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' }, - -- Autoinstall languages that are not installed + sync_install = false, auto_install = true, + ignore_install = {}, + highlight = { enable = true, -- Some languages depend on vim's regex highlighting system (such as Ruby) for indent rules. diff --git a/lua/plugins/session.lua b/lua/plugins/session.lua index 34b9f1e4..bfe6be65 100644 --- a/lua/plugins/session.lua +++ b/lua/plugins/session.lua @@ -3,6 +3,12 @@ return { version = '*', event = "VimEnter", config = function() + -- Function to get current directory name + local function get_session_name() + local cwd = vim.fn.getcwd() + return vim.fn.fnamemodify(cwd, ':t') + end + require('mini.sessions').setup({ -- Whether to read latest session if Neovim opened without file arguments autoread = false, @@ -49,5 +55,17 @@ return { -- Whether to print session path after action verbose = { read = false, write = true, delete = true }, }) - end + + -- Set up autocommands for auto-saving + local session_group = vim.api.nvim_create_augroup('mini_sessions', { clear = true }) + vim.api.nvim_create_autocmd('VimLeavePre', { + group = session_group, + callback = function() + local name = get_session_name() + if name then + require('mini.sessions').write(name, { force = true }) + end + end, + }) + end, } diff --git a/lua/plugins/snacks/picker.lua b/lua/plugins/snacks/picker.lua index 017da9aa..e8bf2477 100644 --- a/lua/plugins/snacks/picker.lua +++ b/lua/plugins/snacks/picker.lua @@ -18,6 +18,9 @@ return { severity = { pos = "right" }, }, matcher = { sort_empty = false, fuzzy = false }, + -- Add safety options + safe_update = true, -- Skip updates if buffer is being written/closed + ignore_nil_buffers = true, -- Skip nil buffers during updates } } }, diff --git a/lua/plugins/snacks/terminal.lua b/lua/plugins/snacks/terminal.lua index 3a10808d..b9220453 100644 --- a/lua/plugins/snacks/terminal.lua +++ b/lua/plugins/snacks/terminal.lua @@ -6,5 +6,9 @@ return { width = 0.8, height = 0.8, }, + -- Set to true for better toggle behavior + persistent = true, + -- Auto-close terminal when process exits + auto_close = true, }, } diff --git a/lua/plugins/telescope.lua b/lua/plugins/telescope.lua index dcbe783e..4ced8ca1 100644 --- a/lua/plugins/telescope.lua +++ b/lua/plugins/telescope.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: undefined-global return { -- Fuzzy Finder (files, lsp, etc) 'nvim-telescope/telescope.nvim', event = 'VimEnter', @@ -23,99 +24,6 @@ return { -- Fuzzy Finder (files, lsp, etc) { '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 - -- it can fuzzy find! It's more than just a "file finder", it can search - -- many different aspects of Neovim, your workspace, LSP, and more! - -- - -- The easiest way to use Telescope, is to start by doing something like: - -- :Telescope help_tags - -- - -- After running this command, a window will open up and you're able to - -- type in the prompt window. You'll see a list of `help_tags` options and - -- a corresponding preview of the help. - -- - -- Two important keymaps to use while in Telescope are: - -- - Insert mode: - -- - Normal mode: ? - -- - -- This opens a window that shows you all of the keymaps for the current - -- Telescope picker. This is really useful to discover what Telescope can - -- do as well as how to actually do it! - - -- [[ Configure Telescope ]] - -- See `:help telescope` and `:help telescope.setup()` - require('telescope').setup { - defaults = { - mappings = { - i = { - [''] = 'which_key', -- Show help in insert mode - }, - n = { - ['?'] = 'which_key', -- Show help in normal mode - }, - }, - }, - extensions = { - ['ui-select'] = { - require('telescope.themes').get_dropdown(), - }, - }, - } - - -- Enable Telescope extensions if they are installed - pcall(require('telescope').load_extension, 'fzf') - pcall(require('telescope').load_extension, 'ui-select') - - -- Apply Telescope keymaps from our centralized keymaps file - local keymaps = require('core.keymaps').telescope_keymaps - for _, mapping in ipairs(keymaps) do - vim.keymap.set(mapping.mode, mapping.lhs, mapping.rhs, mapping.opts) - end - - -- See `:help telescope.builtin` - local builtin = require 'telescope.builtin' - - -- LSP mappings - vim.keymap.set('n', 'gr', builtin.lsp_references, { desc = 'LSP: [G]oto [R]eferences' }) - vim.keymap.set('n', 'gd', builtin.lsp_definitions, { desc = 'LSP: [G]oto [D]efinition' }) - vim.keymap.set('n', 'gI', builtin.lsp_implementations, { desc = 'LSP: [G]oto [I]mplementation' }) - - -- Regular Telescope mappings - vim.keymap.set('n', 'sh', builtin.help_tags, { desc = '[S]earch [H]elp' }) - vim.keymap.set('n', 'sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' }) - vim.keymap.set('n', 'sf', builtin.find_files, { desc = '[S]earch [F]iles' }) - vim.keymap.set('n', 'ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' }) - vim.keymap.set('n', 'sw', builtin.grep_string, { desc = '[S]earch current [W]ord' }) - vim.keymap.set('n', 'sg', builtin.live_grep, { desc = '[S]earch by [G]rep' }) - vim.keymap.set('n', 'sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' }) - vim.keymap.set('n', 'sr', builtin.resume, { desc = '[S]earch [R]esume' }) - vim.keymap.set('n', 's.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' }) - vim.keymap.set('n', '', builtin.buffers, { desc = '[ ] Find existing buffers' }) - - -- Document diagnostics - vim.keymap.set('n', 'dx', builtin.diagnostics, { desc = '[D]ocument Diagnostic[x]' }) - - -- Slightly advanced example of overriding default behavior and theme - vim.keymap.set('n', '/', function() - -- You can pass additional configuration to Telescope to change the theme, layout, etc. - builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { - winblend = 10, - previewer = false, - }) - end, { desc = '[/] Fuzzily search in current buffer' }) - - -- It's also possible to pass additional configuration options. - -- See `:help telescope.builtin.live_grep()` for information about particular keys - vim.keymap.set('n', 's/', function() - builtin.live_grep { - grep_open_files = true, - prompt_title = 'Live Grep in Open Files', - } - end, { desc = '[S]earch [/] in Open Files' }) - - -- Shortcut for searching your Neovim configuration files - vim.keymap.set('n', 'sn', function() - builtin.find_files { cwd = vim.fn.stdpath 'config' } - end, { desc = '[S]earch [N]eovim files' }) + require('plugins.telescope.setup').setup() end, } diff --git a/lua/plugins/telescope/setup.lua b/lua/plugins/telescope/setup.lua new file mode 100644 index 00000000..6f3dca2e --- /dev/null +++ b/lua/plugins/telescope/setup.lua @@ -0,0 +1,45 @@ +---@diagnostic disable: undefined-global +local M = {} + +function M.setup() + -- Base Telescope configuration + require('telescope').setup { + defaults = { + mappings = { + i = { [''] = 'which_key' }, + n = { ['?'] = 'which_key' }, + }, + }, + extensions = { + ['ui-select'] = { require('telescope.themes').get_dropdown() }, + }, + } + + -- Load extensions + pcall(require('telescope').load_extension, 'fzf') + pcall(require('telescope').load_extension, 'ui-select') + + -- Apply keymaps from core.keymaps + local keymaps = require('core.keymaps').telescope_keymaps + for _, mapping in ipairs(keymaps) do + vim.keymap.set(mapping.mode, mapping.lhs, mapping.rhs, mapping.opts) + end + + -- Additional builtins mapping (if not handled by core) + local builtin = require 'telescope.builtin' + vim.keymap.set('n', 'gr', builtin.lsp_references, { desc = 'LSP: [G]oto [R]eferences' }) + vim.keymap.set('n', 'gd', builtin.lsp_definitions, { desc = 'LSP: [G]oto [D]efinition' }) + vim.keymap.set('n', 'gI', builtin.lsp_implementations, { desc = 'LSP: [G]oto [I]mplementation' }) + -- Other mappings moved from inline config + vim.keymap.set('n', '/', function() + builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { winblend = 10, previewer = false }) + end, { desc = '[/] Fuzzily search in current buffer' }) + vim.keymap.set('n', 's/', function() + builtin.live_grep { grep_open_files = true, prompt_title = 'Live Grep in Open Files' } + end, { desc = '[S]earch [/] in Open Files' }) + vim.keymap.set('n', 'sn', function() + builtin.find_files { cwd = vim.fn.stdpath 'config' } + end, { desc = '[S]earch [N]eovim files' }) +end + +return M diff --git a/lua/plugins/which-key.lua b/lua/plugins/which-key.lua index 8bede533..1b532fe7 100644 --- a/lua/plugins/which-key.lua +++ b/lua/plugins/which-key.lua @@ -6,102 +6,73 @@ return { -- Useful plugin to show you pending keybinds. icons = { mappings = vim.g.have_nerd_font, keys = vim.g.have_nerd_font and {} or { - Up = ' ', - Down = ' ', - Left = ' ', - Right = ' ', - C = ' ', - M = ' ', - D = ' ', - S = ' ', - CR = ' ', - Esc = ' ', - ScrollWheelDown = ' ', - ScrollWheelUp = ' ', - NL = ' ', - BS = ' ', - Space = ' ', - Tab = ' ', - F1 = '', - F2 = '', - F3 = '', - F4 = '', - F5 = '', - F6 = '', - F7 = '', - F8 = '', - F9 = '', - F10 = '', - F11 = '', - F12 = '', + Up = ' ', Down = ' ', Left = ' ', Right = ' ', + C = ' ', M = ' ', D = ' ', S = ' ', + CR = ' ', Esc = ' ', ScrollWheelDown = ' ', + ScrollWheelUp = ' ', NL = ' ', BS = ' ', + Space = ' ', Tab = ' ', F1 = '', F2 = '', + F3 = '', F4 = '', F5 = '', F6 = '', + F7 = '', F8 = '', F9 = '', F10 = '', + F11 = '', F12 = '', }, }, - - -- Document existing key chains - spec = { - { 'c', group = '[C]ode', desc = { - a = 'Code [A]ction', - f = '[F]ormat buffer', - }}, - { 'd', group = '[D]ocument', desc = { - x = 'Document [D]iagnostics', - s = 'Document [S]ymbols', - [''] = 'Show diagnostic under cursor', - }}, - { 's', group = '[S]earch', desc = { - h = '[H]elp', - k = '[K]eymaps', - f = '[F]iles', - s = '[S]elect Telescope', - w = 'Current [W]ord', - g = '[G]rep', - d = '[D]iagnostics', - r = '[R]esume last search', - ['/'] = 'Search in open files', - n = '[N]eovim config files', - }}, - { 'w', group = '[W]orkspace', desc = { - s = '[S]ymbols', - }}, - { 't', group = '[T]oggle', desc = { - h = 'Toggle inlay [H]ints', - }}, - { 'h', group = 'Git [H]unk', mode = { 'n', 'v' } }, - { 'g', group = '[G]it', desc = { - s = 'Status', - }}, - { 'f', group = '[F]ile Explorer', desc = { - e = 'Toggle explorer', - f = 'Focus explorer', - }}, - { 'n', group = '[N]otifications', desc = { - n = 'Toggle notifications', - h = 'Notification [H]istory', - c = '[C]lear notifications', - }}, - { 'p', group = 'Debug/[P]rofile', desc = { - b = 'Toggle [B]reakpoint', - c = '[C]ontinue debugging', - n = 'Step over ([N]ext)', - i = 'Step [I]nto', - o = 'Step [O]ut', - r = 'Open [R]EPL', - l = 'Run [L]ast debug session', - x = 'Toggle debug UI', - }}, - { 'b', group = '[B]uffer', desc = { - p = '[P]revious', - n = '[N]ext', - d = '[D]elete', - D = 'Force [D]elete', - }}, - { 'q', desc = 'Open diagnostic [Q]uickfix list' }, - { 'e', desc = 'Toggle file [E]xplorer' }, - { 'o', desc = 'F[o]cus file explorer' }, - { 'x', desc = 'Close buffer' }, - { 'X', desc = 'Force close buffer' }, - { '/', desc = 'Search in current buffer' }, - { '', desc = 'Find buffers' }, - }, }, + config = function(_, opts) + local wk = require('which-key') + wk.setup(opts) + wk.add({ + { "/", desc = "Search in current buffer" }, + { "", desc = "Find buffers" }, + { "X", desc = "Force close buffer" }, + { "b", group = "[B]uffer" }, + { "bD", desc = "Force [D]elete" }, + { "bd", desc = "Delete buffer" }, + { "bn", desc = "Next buffer" }, + { "bp", desc = "Previous buffer" }, + { "c", group = "[C]ode" }, + { "ca", desc = "Code Action" }, + { "cf", desc = "Format buffer" }, + { "d", desc = "Show diagnostic under cursor" }, + { "ds", desc = "Document symbols" }, + { "dx", desc = "Document diagnostics" }, + { "e", desc = "Toggle file explorer" }, + { "f", group = "[F]ile Explorer" }, + { "fe", desc = "Toggle explorer" }, + { "ff", desc = "Focus explorer" }, + { "g", group = "[G]it" }, + { "gs", desc = "Status" }, + { "h", group = "Git [H]unk" }, + { "n", group = "[N]otifications" }, + { "nc", desc = "Clear notifications" }, + { "nh", desc = "Notification history" }, + { "nn", desc = "Toggle notifications" }, + { "o", desc = "Focus file explorer" }, + { "p", group = "Debug/[P]rofile" }, + { "pb", desc = "Toggle breakpoint" }, + { "pc", desc = "Continue debugging" }, + { "pi", desc = "Step into" }, + { "pl", desc = "Run last debug session" }, + { "pn", desc = "Step over" }, + { "po", desc = "Step out" }, + { "pr", desc = "Open REPL" }, + { "px", desc = "Toggle debug UI" }, + { "q", desc = "Open diagnostic quickfix list" }, + { "s", group = "[S]earch" }, + { "s/", desc = "Search in open files" }, + { "sd", desc = "Diagnostics" }, + { "sf", desc = "Files" }, + { "sg", desc = "Grep" }, + { "sh", desc = "Help" }, + { "sk", desc = "Keymaps" }, + { "sn", desc = "Neovim config files" }, + { "sr", desc = "Resume last search" }, + { "ss", desc = "Select Telescope" }, + { "sw", desc = "Current word" }, + { "t", group = "[T]oggle" }, + { "th", desc = "Toggle inlay hints" }, + { "w", group = "[W]orkspace" }, + { "ws", desc = "Symbols" }, + { "x", desc = "Close buffer" }, + }) + end, } diff --git a/lua/plugins/work/gopls_flags.txt b/lua/plugins/work/gopls_flags.txt new file mode 100644 index 00000000..1cff4fb4 --- /dev/null +++ b/lua/plugins/work/gopls_flags.txt @@ -0,0 +1 @@ +-tags=integration diff --git a/src/main.zen b/src/main.zen deleted file mode 100644 index 066a492c..00000000 --- a/src/main.zen +++ /dev/null @@ -1,5 +0,0 @@ -const std = @import("std"); - -pub fn main() anyerror!void { - std.debug.warn("Congratulations on your first step to writing perfect software in Zen.\n", .{}); -}