From 42483b98f548e3e03a2e84ec437ead0208f8712d Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Thu, 7 May 2026 20:41:03 +0545 Subject: [PATCH 01/18] migrate to new builtin plugin manager with new folder structure --- init.lua | 11 +- lazy-lock.json | 48 ----- lua/autocmd.lua | 194 +++++++++++++++++++ lua/config/autocmd.lua | 325 ------------------------------- lua/config/extensions.lua | 66 ------- lua/config/keys.lua | 143 -------------- lua/config/lazy.lua | 48 ----- lua/config/lsp.lua | 100 ---------- lua/config/options.lua | 67 ------- lua/extensions.lua | 66 +++++++ lua/keys.lua | 143 ++++++++++++++ lua/lsp.lua | 113 +++++++++++ lua/options.lua | 67 +++++++ lua/pack_helper.lua | 71 +++++++ lua/plugins/ai.lua | 14 -- lua/plugins/coding.lua | 126 ------------- lua/plugins/colorscheme.lua | 39 ---- lua/plugins/editor.lua | 100 ---------- lua/plugins/formatting.lua | 64 ------- lua/plugins/git.lua | 61 ------ lua/plugins/linting.lua | 34 ---- lua/plugins/lsp.lua | 109 ----------- lua/plugins/mini.lua | 161 ---------------- lua/plugins/snacks.lua | 367 ------------------------------------ lua/plugins/syntax.lua | 78 -------- lua/plugins/ui.lua | 114 ----------- lua/plugins/util.lua | 108 ----------- lua/plugins/whichkey.lua | 307 ------------------------------ nvim-pack-lock.json | 184 ++++++++++++++++++ plugin/00-colorscheme.lua | 34 ++++ plugin/01-lsp.lua | 74 ++++++++ plugin/code_quality.lua | 82 ++++++++ plugin/completion.lua | 75 ++++++++ plugin/editor.lua | 72 +++++++ plugin/git.lua | 34 ++++ plugin/mini.lua | 153 +++++++++++++++ plugin/snacks.lua | 367 ++++++++++++++++++++++++++++++++++++ plugin/ui.lua | 104 ++++++++++ plugin/whichkey.lua | 301 +++++++++++++++++++++++++++++ 39 files changed, 2139 insertions(+), 2485 deletions(-) delete mode 100644 lazy-lock.json create mode 100644 lua/autocmd.lua delete mode 100644 lua/config/autocmd.lua delete mode 100644 lua/config/extensions.lua delete mode 100644 lua/config/keys.lua delete mode 100644 lua/config/lazy.lua delete mode 100644 lua/config/lsp.lua delete mode 100644 lua/config/options.lua create mode 100644 lua/extensions.lua create mode 100644 lua/keys.lua create mode 100644 lua/lsp.lua create mode 100644 lua/options.lua create mode 100644 lua/pack_helper.lua delete mode 100644 lua/plugins/ai.lua delete mode 100644 lua/plugins/coding.lua delete mode 100644 lua/plugins/colorscheme.lua delete mode 100644 lua/plugins/editor.lua delete mode 100644 lua/plugins/formatting.lua delete mode 100644 lua/plugins/git.lua delete mode 100644 lua/plugins/linting.lua delete mode 100644 lua/plugins/lsp.lua delete mode 100644 lua/plugins/mini.lua delete mode 100644 lua/plugins/snacks.lua delete mode 100644 lua/plugins/syntax.lua delete mode 100644 lua/plugins/ui.lua delete mode 100644 lua/plugins/util.lua delete mode 100644 lua/plugins/whichkey.lua create mode 100644 nvim-pack-lock.json create mode 100644 plugin/00-colorscheme.lua create mode 100644 plugin/01-lsp.lua create mode 100644 plugin/code_quality.lua create mode 100644 plugin/completion.lua create mode 100644 plugin/editor.lua create mode 100644 plugin/git.lua create mode 100644 plugin/mini.lua create mode 100644 plugin/snacks.lua create mode 100644 plugin/ui.lua create mode 100644 plugin/whichkey.lua diff --git a/init.lua b/init.lua index de6b89c..445486b 100644 --- a/init.lua +++ b/init.lua @@ -1,6 +1,5 @@ --- load config -require('config.options') -require('config.keys') -require('config.autocmd') -require('config.lazy') -require('config.lsp') +require("pack_helper") +require("keys") +require("options") +require("autocmd") +require('lsp') diff --git a/lazy-lock.json b/lazy-lock.json deleted file mode 100644 index 46f3862..0000000 --- a/lazy-lock.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" }, - "LuaSnip": { "branch": "master", "commit": "642b0c595e11608b4c18219e93b88d7637af27bc" }, - "Navigator.nvim": { "branch": "master", "commit": "91d86506ac2a039504d5205d32a1d4bc7aa57072" }, - "bento.nvim": { "branch": "main", "commit": "aee8a542bc1839ff1764992ef2aa41c981d0bba4" }, - "better-escape.nvim": { "branch": "master", "commit": "3f4bc0b326606264ff75967f59091b5ddada0554" }, - "blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" }, - "codesnap.nvim": { "branch": "main", "commit": "0a0941340376439a25d6cd8a4d1d2b372edbfdbd" }, - "conform.nvim": { "branch": "master", "commit": "dca1a190aa85f9065979ef35802fb77131911106" }, - "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" }, - "gitignore.nvim": { "branch": "master", "commit": "0344f643768c4d64af4add8c1bdddf6f7d4c9010" }, - "gitsigns.nvim": { "branch": "main", "commit": "6d808f99bd63303646794406e270bd553ad7792e" }, - "gruvbox.nvim": { "branch": "main", "commit": "154eb5ff5b96d0641307113fa385eaf0d36d9796" }, - "hardtime.nvim": { "branch": "main", "commit": "b4e431934af1fe224a3a801f632c008278cb7628" }, - "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, - "lazygit.nvim": { "branch": "main", "commit": "a04ad0dbc725134edbee3a5eea29290976695357" }, - "lspsaga.nvim": { "branch": "main", "commit": "c532fb86c3d211c5829ad58d2a0783012739bb65" }, - "markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" }, - "markview.nvim": { "branch": "main", "commit": "86cf4bcede58e88497f7e5214efb281d4a6f633d" }, - "mason-conform.nvim": { "branch": "main", "commit": "48da2ebd5efbaf8a99566eadc3ece82d523f03c5" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "0c2823e0418f3d9230ff8b201c976e84de1cb401" }, - "mason-nvim-lint": { "branch": "main", "commit": "cafbc5d82d8eb4af0daf0057332a325ddf2f436b" }, - "mason.nvim": { "branch": "main", "commit": "12ddd182d9efbdc848b540f16484a583d52da0fb" }, - "mdx.nvim": { "branch": "main", "commit": "6c3dc7c4a4b58b5d86404c21a9b4655282ca08c5" }, - "mini.nvim": { "branch": "main", "commit": "be81509b7160aa02264a59789164a2e1c4a6750a" }, - "neogen": { "branch": "main", "commit": "23e7e9f883d01289ebd90e98025acc860ea26366" }, - "neoscroll.nvim": { "branch": "master", "commit": "c8d29979cb0cb3a2437a8e0ae683fd82f340d3b8" }, - "nvim-autopairs": { "branch": "master", "commit": "59bce2eef357189c3305e25bc6dd2d138c1683f5" }, - "nvim-genghis": { "branch": "main", "commit": "12d62b0aaeb0bf6e52f2335d532813a8b8105baa" }, - "nvim-lint": { "branch": "master", "commit": "eab58b48eb11d7745c11c505e0f3057165902461" }, - "nvim-lspconfig": { "branch": "master", "commit": "8fde495949782bb61c2605174e231d145a048d8c" }, - "nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" }, - "nvim-ts-autotag": { "branch": "main", "commit": "88c1453db4ba7dd24131086fe51fdf74e587d275" }, - "nvim-ts-context-commentstring": { "branch": "main", "commit": "6141a40173c6efa98242dc951ed4b6f892c97027" }, - "nvim-ufo": { "branch": "main", "commit": "ab3eb124062422d276fae49e0dd63b3ad1062cfc" }, - "promise-async": { "branch": "main", "commit": "119e8961014c9bfaf1487bf3c2a393d254f337e2" }, - "smartcolumn.nvim": { "branch": "main", "commit": "b9cdbdf42f7ac5a659204cd5926017c7ff724a19" }, - "snacks.nvim": { "branch": "main", "commit": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e" }, - "tiny-code-action.nvim": { "branch": "main", "commit": "0d040ed81f7953118b81cd12681fcdfcac069803" }, - "tiny-inline-diagnostic.nvim": { "branch": "main", "commit": "147af4e49f51dd48f41972de26552872b8ba7b25" }, - "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, - "toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" }, - "vim-suda": { "branch": "master", "commit": "c492741b4679b3cdd4d9e34138209784e061d916" }, - "vim-visual-multi": { "branch": "master", "commit": "a6975e7c1ee157615bbc80fc25e4392f71c344d4" }, - "vim-wakatime": { "branch": "master", "commit": "8217dfb5a5a3ad3a509365d8a39d7daca12b1745" }, - "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }, - "windsurf.vim": { "branch": "main", "commit": "3c0a4f8a7be75113a6e19be13b7cc37210d6e26a" } -} diff --git a/lua/autocmd.lua b/lua/autocmd.lua new file mode 100644 index 0000000..9ca9bba --- /dev/null +++ b/lua/autocmd.lua @@ -0,0 +1,194 @@ +local function augroup(name) + return vim.api.nvim_create_augroup("nvim_" .. name, { clear = true }) +end + +-- ----------------------------------------------------------------------------- +-- General UI & Behavior +-- ----------------------------------------------------------------------------- + +-- Secure .env Masking (Conceal method) +local function toggle_env_mask() + local buf = vim.api.nvim_get_current_buf() + if vim.wo.conceallevel > 0 then + vim.wo.conceallevel = 0 + vim.notify("Env masking disabled", vim.log.levels.INFO, { title = "Security" }) + else + vim.wo.conceallevel = 2 + vim.wo.concealcursor = "n" -- Show when editing (insert mode) + vim.notify("Env masking enabled", vim.log.levels.INFO, { title = "Security" }) + end +end + +-- Auto-mask .env files on load +vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile" }, { + group = augroup("env_masking"), + pattern = { ".env", ".env.*", "*.env" }, + callback = function() + vim.opt_local.conceallevel = 2 + vim.opt_local.concealcursor = "n" + -- Match everything after '=' (only if not empty) and conceal it with '*' + vim.fn.matchadd("Conceal", [[=\zs.\+]], 10, -1, { conceal = "*" }) + end, +}) + +vim.keymap.set("n", "ot", toggle_env_mask, { desc = "Toggle .env masking" }) + + +-- Strip trailing spaces before write +vim.api.nvim_create_autocmd("BufWritePre", { + group = augroup("strip_space"), + pattern = "*", + callback = function() + local save = vim.fn.winsaveview() + vim.cmd([[keeppatterns %s/\s\+$//e]]) + vim.fn.winrestview(save) + end, +}) + +-- Highlight on yank +vim.api.nvim_create_autocmd("TextYankPost", { + group = augroup("highlight_yank"), + callback = function() + vim.highlight.on_yank({ timeout = 200 }) + end, +}) + +-- Resize splits if window got resized +vim.api.nvim_create_autocmd("VimResized", { + group = augroup("resize_splits"), + callback = function() + vim.cmd("tabdo wincmd =") + end, +}) + +-- Go to last location when opening a buffer +vim.api.nvim_create_autocmd("BufReadPost", { + group = augroup("last_loc"), + callback = function() + local mark = vim.api.nvim_buf_get_mark(0, '"') + local lcount = vim.api.nvim_buf_line_count(0) + if mark[1] > 0 and mark[1] <= lcount then + pcall(vim.api.nvim_win_set_cursor, 0, mark) + end + end, +}) + +-- Close specific filetypes with +vim.api.nvim_create_autocmd("FileType", { + group = augroup("close_with_q"), + pattern = { + "help", "lspinfo", "man", "notify", "qf", "query", "spectre_panel", + "startuptime", "tsplayground", "neotest-output", "checkhealth", + }, + callback = function(event) + vim.bo[event.buf].buflisted = false + vim.keymap.set("n", "q", "close", { buffer = event.buf, silent = true }) + end, +}) + +-- Auto-create directories on save +vim.api.nvim_create_autocmd("BufWritePre", { + group = augroup("auto_create_dir"), + callback = function(event) + if event.match:match("^%w%w+://") then + return + end + local file = vim.loop.fs_realpath(event.match) or event.match + vim.fn.mkdir(vim.fn.fnamemodify(file, ":p:h"), "p") + end, +}) + +-- ----------------------------------------------------------------------------- +-- LSP Related +-- ----------------------------------------------------------------------------- + +-- Document Highlight on CursorHold +vim.api.nvim_create_autocmd("LspAttach", { + group = augroup("lsp_attach_autocmds"), + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + if client and client.supports_method("textDocument/documentHighlight") then + vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { + buffer = args.buf, + callback = vim.lsp.buf.document_highlight, + }) + vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, { + buffer = args.buf, + callback = vim.lsp.buf.clear_references, + }) + end + end, +}) + +-- ----------------------------------------------------------------------------- +-- Filetype Specific +-- ----------------------------------------------------------------------------- + +-- Wrap and spellcheck in text filetypes +vim.api.nvim_create_autocmd("FileType", { + group = augroup("wrap_spell"), + pattern = { "gitcommit", "markdown", "text" }, + callback = function() + vim.opt_local.wrap = true + vim.opt_local.spell = true + end, +}) + +-- Disable auto-commenting on new lines +vim.api.nvim_create_autocmd("FileType", { + group = augroup("no_auto_comment"), + callback = function() + vim.opt_local.formatoptions:remove({ "c", "r", "o" }) + end, +}) + + +-- Manual Treesitter Installation command +vim.api.nvim_create_user_command("TSInstallAll", function() + local parsers = require("extensions").ts_parsers + vim.notify("Installing all configured Tree-sitter parsers...", vim.log.levels.INFO, { title = "Tree-sitter" }) + require("nvim-treesitter.install").install(parsers) +end, { desc = "Install all configured Tree-sitter parsers" }) + +-- ----------------------------------------------------------------------------- +-- Macro Notifications +-- ----------------------------------------------------------------------------- + +vim.api.nvim_create_autocmd("RecordingEnter", { + callback = function() + vim.notify("Recording macro...", vim.log.levels.INFO, { title = "Macro", timeout = 1000 }) + end, +}) + +vim.api.nvim_create_autocmd("RecordingLeave", { + callback = function() + local reg = vim.v.recording + vim.notify("Stopped recording @" .. reg, vim.log.levels.INFO, { title = "Macro", timeout = 1000 }) + end, +}) + +-- ----------------------------------------------------------------------------- +-- Auto-Save (3s Debounce) +-- ----------------------------------------------------------------------------- + +local save_timer = nil +vim.api.nvim_create_autocmd({ "TextChanged", "InsertLeave", "BufLeave", "FocusLost" }, { + group = augroup("autosave"), + callback = function(args) + if not vim.bo[args.buf].modified or vim.bo[args.buf].buftype ~= "" then + return + end + if save_timer then + save_timer:stop() + end + + local delay = (args.event == "BufLeave" or args.event == "FocusLost") and 0 or 3000 + save_timer = vim.defer_fn(function() + if vim.api.nvim_buf_is_valid(args.buf) and vim.bo[args.buf].modified then + vim.api.nvim_buf_call(args.buf, function() + vim.cmd("silent! write") + end) + end + end, delay) + end, +}) diff --git a/lua/config/autocmd.lua b/lua/config/autocmd.lua deleted file mode 100644 index a36092c..0000000 --- a/lua/config/autocmd.lua +++ /dev/null @@ -1,325 +0,0 @@ -local function augroup(name) - return vim.api.nvim_create_augroup('nvim' .. name, { clear = true }) -end - --- hide sensetive data in .env --- local group = vim.api.nvim_create_augroup('EnvMask', { clear = true }) --- local hidden = {} --- --- local function mask_line(line) --- if line:match('^%s*#') or line:match('^%s*$') then --- return line --- end --- --- local key, value = line:match('^([%w_]+)%s*=%s*(.*)') --- if not key or not value then --- return line --- end --- --- return key .. '=' .. string.rep('*', #value) --- end --- --- local function hide(buf) --- if hidden[buf] then --- return --- end --- --- local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false) --- hidden[buf] = lines --- --- local masked = {} --- for i, line in ipairs(lines) do --- masked[i] = mask_line(line) --- end --- --- vim.api.nvim_buf_set_lines(buf, 0, -1, false, masked) --- end --- --- local function show(buf) --- if not hidden[buf] then --- return --- end --- vim.api.nvim_buf_set_lines(buf, 0, -1, false, hidden[buf]) --- hidden[buf] = nil --- end --- --- vim.api.nvim_create_autocmd('BufReadPost', { --- group = group, --- pattern = { '.env', '.env.*', '*.env' }, --- callback = function(args) --- vim.cmd('silent! noautocmd redraw') --- hide(args.buf) --- end, --- }) --- --- vim.keymap.set('n', 'ot', function() --- local buf = vim.api.nvim_get_current_buf() --- if hidden[buf] then --- show(buf) --- else --- hide(buf) --- end --- end, { desc = 'Toggle env masking' }) - --- Strip trailing spaces before write -vim.api.nvim_create_autocmd({ 'BufWritePre' }, { - group = augroup('strip_space'), - pattern = { '*' }, - callback = function() - vim.cmd([[ %s/\s\+$//e ]]) - end, -}) - --- Check if we need to reload the file when it changed -vim.api.nvim_create_autocmd({ 'FocusGained', 'TermClose', 'TermLeave' }, { - group = augroup('checktime'), - command = 'checktime', -}) - --- Highlight on yank -vim.api.nvim_create_autocmd('TextYankPost', { - group = augroup('highlight_yank'), - callback = function() - vim.highlight.on_yank({ timeout = 200, visual = true }) - end, -}) - --- resize splits if window got resized -vim.api.nvim_create_autocmd({ 'VimResized' }, { - group = augroup('resize_splits'), - callback = function() - vim.cmd('tabdo wincmd =') - end, -}) - --- go to last loc when opening a buffer --- vim.api.nvim_create_autocmd('BufReadPost', { --- group = augroup('last_loc'), --- callback = function() --- local mark = vim.api.nvim_buf_get_mark(0, '"') --- local lcount = vim.api.nvim_buf_line_count(0) --- if mark[1] > 0 and mark[1] <= lcount then --- pcall(vim.api.nvim_win_set_cursor, 0, mark) --- end --- end, --- }) - --- restore cursor to file position in previous editing session --- vim.api.nvim_create_autocmd('BufReadPost', { --- callback = function(args) --- local mark = vim.api.nvim_buf_get_mark(args.buf, '"') --- local line_count = vim.api.nvim_buf_line_count(args.buf) --- if mark[1] > 0 and mark[1] <= line_count then --- vim.api.nvim_win_set_cursor(0, mark) --- -- defer centering slightly so it's applied after render --- vim.schedule(function() --- vim.cmd('normal! zz') --- end) --- end --- end, --- }) - --- open help in vertical split -vim.api.nvim_create_autocmd('FileType', { - pattern = 'help', - command = 'wincmd L', -}) - --- no auto continue comments on new line -vim.api.nvim_create_autocmd('FileType', { - group = vim.api.nvim_create_augroup('no_auto_comment', {}), - callback = function() - vim.opt_local.formatoptions:remove({ 'c', 'r', 'o' }) - end, -}) - --- show cursorline only in active window enable -vim.api.nvim_create_autocmd({ 'WinEnter', 'BufEnter' }, { - group = vim.api.nvim_create_augroup('active_cursorline', { clear = true }), - callback = function() - vim.opt_local.cursorline = true - end, -}) - --- show cursorline only in active window disable -vim.api.nvim_create_autocmd({ 'WinLeave', 'BufLeave' }, { - group = 'active_cursorline', - callback = function() - vim.opt_local.cursorline = false - end, -}) - --- ide like highlight when stopping cursor -vim.api.nvim_create_autocmd('CursorMoved', { - group = vim.api.nvim_create_augroup('LspReferenceHighlight', { clear = true }), - desc = 'Highlight references under cursor', - callback = function() - -- Only run if the cursor is not in insert mode - if vim.fn.mode() ~= 'i' then - local clients = vim.lsp.get_clients({ bufnr = 0 }) - local supports_highlight = false - for _, client in ipairs(clients) do - if client.server_capabilities.documentHighlightProvider then - supports_highlight = true - break -- Found a supporting client, no need to check others - end - end - - -- 3. Proceed only if an LSP is active AND supports the feature - if supports_highlight then - vim.lsp.buf.clear_references() - vim.lsp.buf.document_highlight() - end - end - end, -}) - --- ide like highlight when stopping cursor -vim.api.nvim_create_autocmd('CursorMovedI', { - group = 'LspReferenceHighlight', - desc = 'Clear highlights when entering insert mode', - callback = function() - vim.lsp.buf.clear_references() - end, -}) - --- close some filetypes with -vim.api.nvim_create_autocmd('FileType', { - group = augroup('close_with_q'), - pattern = { - 'Jaq', - 'PlenaryTestPopup', - 'Avante', - 'AvanteInput', - 'AvanteSelectedFiles', - 'fugitive', - 'git', - 'help', - 'lir', - 'lspinfo', - 'man', - 'netrw', - 'notify', - 'qf', - 'spectre_panel', - 'startuptime', - 'tsplayground', - }, - callback = function(event) - vim.bo[event.buf].buflisted = false - vim.keymap.set('n', 'q', 'close', { buffer = event.buf, silent = true }) - end, -}) - --- wrap and check for spell in text filetypes -vim.api.nvim_create_autocmd('FileType', { - group = augroup('wrap_spell'), - pattern = { 'gitcommit', 'markdown' }, - callback = function() - vim.opt_local.wrap = true - vim.opt_local.spell = true - end, -}) - --- Auto create dir when saving a file, in case some intermediate directory does not exist -vim.api.nvim_create_autocmd({ 'BufWritePre' }, { - group = augroup('auto_create_dir'), - callback = function(event) - local file = vim.loop.fs_realpath(event.match) or event.match - vim.fn.mkdir(vim.fn.fnamemodify(file, ':p:h'), 'p') - end, -}) - --- Set arb filetype -vim.api.nvim_create_autocmd({ 'BufEnter' }, { - group = augroup('set_file_type'), - pattern = { '*.arb' }, - command = 'setfiletype arb', -}) - --- Disable format options -vim.api.nvim_create_autocmd('FileType', { - group = augroup('disable_formatoptions'), - pattern = '*', - callback = function() - vim.opt_local.formatoptions:remove({ 'c', 'r', 'o' }) - end, -}) - -local function enable_autoformat() - vim.api.nvim_create_autocmd({ 'BufWritePre' }, { - group = augroup('autoformat'), - pattern = { '*' }, - callback = function() - vim.lsp.buf.format() - end, - }) -end - -enable_autoformat() - -vim.api.nvim_create_user_command('WriteNoFormat', function() - -- Temporarily disable the autoformat autocmd - vim.api.nvim_del_augroup_by_name('keycodex_autoformat') - vim.cmd('write') - -- Re-enable the autoformat autocmd - enable_autoformat() -end, {}) - --- Macro recording notifications -vim.api.nvim_create_autocmd('RecordingEnter', { - callback = function() - vim.notify('Macro recording started', vim.log.levels.INFO, { - title = 'Macro', - timeout = 2000, - }) - -- Print to command line for debugging - vim.cmd("echo 'Recording macro...'") - end, -}) - -vim.api.nvim_create_autocmd('RecordingLeave', { - callback = function() - vim.notify('Macro recording stopped', vim.log.levels.INFO, { - title = 'Macro', - timeout = 2000, - }) - -- Print to command line for debugging - vim.cmd("echo 'Macro recording stopped'") - end, -}) - --- Function to show macro replay notification -local function show_macro_replay(count) - local message = count > 1 and string.format('Replaying macro %d times', count) or 'Replaying macro' - vim.notify(message, vim.log.levels.INFO, { - title = 'Macro', - timeout = 2000, - }) -end - --- Function to clear all macros -local function clear_all_macros() - -- Clear all registers from a to z - for i = 97, 122 do -- ASCII values for 'a' to 'z' - vim.fn.setreg(string.char(i), '') - end - -- Clear all registers from 0 to 9 - for i = 48, 57 do -- ASCII values for '0' to '9' - vim.fn.setreg(string.char(i), '') - end - vim.notify('All macros cleared', vim.log.levels.INFO, { - title = 'Macro', - timeout = 2000, - }) -end - --- Create keymaps for macro replay with notifications -vim.keymap.set('n', '@', function() - local count = vim.v.count1 - show_macro_replay(count) - return '@' -end, { expr = true }) - --- Add keybinding to clear all macros -vim.keymap.set('n', 'oc', clear_all_macros, { desc = 'Clear all macros' }) diff --git a/lua/config/extensions.lua b/lua/config/extensions.lua deleted file mode 100644 index abb815d..0000000 --- a/lua/config/extensions.lua +++ /dev/null @@ -1,66 +0,0 @@ -local treesitter_parsers = { - "c", - "markdown", - "python", - "java", - "cpp", - "bash", - "lua", - "make", - "json", - "jsonc", - "sql", - "yaml", - "toml", - "javascript", - "typescript", - "gitignore", - "go", - "rust", - "html", - "css", - "scss", - "markdown_inline", -} - -local lsp_server = { - "ts_ls", - "html", - "cssls", - "tailwindcss", - "lua_ls", - "basedpyright", - "bashls", - "clangd", - "rust_analyzer", -} - -local formatter = { - "clang_format", - "ruff", - "stylua", - "prettier", - "markdown-toc", - "markdownlint-cli2", - "biome", -} - -local linter = { - "eslint_d", - "hadolint", - "write_good", - "markdownlint", - "shellcheck", - "actionlint", - "djlint", - "ruff", - "codespell", - "cspell", -} - -return { - ts_parsers = treesitter_parsers, - lsp_server = lsp_server, - formatter = formatter, - linter = linter, -} diff --git a/lua/config/keys.lua b/lua/config/keys.lua deleted file mode 100644 index 1f185cc..0000000 --- a/lua/config/keys.lua +++ /dev/null @@ -1,143 +0,0 @@ -local function map(mode, lhs, rhs, opts) - opts = opts or {} - opts.silent = opts.silent ~= false - vim.keymap.set(mode, lhs, rhs, opts) -end -local opts = { noremap = true, silent = true } - --- Space as leader -map('n', '', '', opts) -vim.g.mapleader = ' ' -vim.g.maplocalleader = ' ' - --- Modes --- normal_mode = "n", insert_mode = "i", visual_mode = "v", --- visual_block_mode = "x", term_mode = "t", command_mode = "c", - --- Terminal Mappings -map('t', 'jk', '') -map('t', 'kj', '') -map('t', '', '') - --- Clear search, diff update and redraw -map({ 'i', 'n' }, '', 'noh', { desc = 'Escape and clear hlsearch' }) - -map({ 'i', 'c' }, '', '') -map({ 'i', 'c' }, '', '') - -map('n', 'rL', vim.lsp.buf.rename, { desc = 'Rename Lsp Symbol' }) -map('n', '`', "'", { noremap = true }) -- better marks - -map({ 'n', 'v' }, 'H', '^', { desc = 'Move to the beginning of the line' }) -map({ 'n', 'v' }, 'L', '$', { desc = 'Move to the end of the line' }) - --- Visual overwrite paste -map({ 'v', 'x' }, 'p', '"_dP', opts) - --- Do not copy on x -map({ 'v', 'x' }, 'x', '"_x', opts) -map('n', 'X', '"_D', opts) -map('n', 'dd', '"_dd', opts) -map({ 'v', 'x' }, 'X', '"_d', opts) - --- Select all - --- Select all -map('n', 'a', 'ggVG', { desc = 'Select all' }) -map('n', '', 'ggVG', { desc = 'Select all' }) -map('i', '', 'ggVG', { desc = 'Select all' }) - --- Move text up and down -map({ 'v', 'x' }, 'K', ":move '<-2gv-gv", opts) -map({ 'v', 'x' }, 'J', ":move '>+1gv-gv", opts) - --- Line operations -map('n', '', ':m .-2==', { desc = 'Move line up' }) -map('n', '', ':m .+1==', { desc = 'Move line down' }) -map('i', '', ':m .-2==gi', { desc = 'Move line up' }) -map('i', '', ':m .+1==gi', { desc = 'Move line down' }) -map('v', '', ":m '<-2gv=gv", { desc = 'Move selection up' }) -map('v', '', ":m '>+1gv=gv", { desc = 'Move selection down' }) - --- Line manipulation -map('n', '', '>>', { desc = 'Indent line' }) -map('n', '', '<<', { desc = 'Unindent line' }) -map('i', '', '>>', { desc = 'Indent line' }) -map('i', '', '<<', { desc = 'Unindent line' }) - --- Quick word operations -map('n', '', 'db', { desc = 'Delete word backward' }) -map('i', '', '', { desc = 'Delete word backward' }) -map('n', '', 'dw', { desc = 'Delete word forward' }) -map('i', '', 'dw', { desc = 'Delete word forward' }) - -map('n', 'd', '"_d', { desc = 'Delete without replacing clipboard' }) -map('n', 'x', '"_x', { desc = 'Cut without replacing clipboard' }) -map('n', 'c', '"_c', { desc = 'Change without replacing clipboard' }) -map('v', 'p', '"_dP', { desc = 'Paste without replacing clipboard' }) - ---insert the following characters around the visual selection -map('v', '(', 's()Pll', { desc = 'wrap selection with parens' }) -map('v', '[', 's[]Pll', { desc = 'wrap selection with square braces' }) -map('v', '{', 's{}Pll', { desc = 'wrap selection with curly braces' }) -map('v', "'", "s''Pll", { desc = 'wrap selection with single quotes' }) -map('v', '"', 's""Pll', { desc = 'wrap selection with double quotes' }) - --- Insert mode cursor movement with Ctrl+hjkl -map({ 'i', 'c' }, '', '', { noremap = true, silent = true }) -map({ 'i', 'c' }, '', '', { noremap = true, silent = true }) -map({ 'i', 'c' }, '', '', { noremap = true, silent = true }) -map({ 'i', 'c' }, '', '', { noremap = true, silent = true }) - -map('n', 're', ':%s//', { desc = 'Shortcut to replace current word under cursor' }) - --- toggle inlay hints -vim.keymap.set('n', 'th', function() - vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) -end) - --- No arrow navigation -local modes = { 'n', 'v', 'i' } -local arrows = { '', '', '', '' } - -for _, mode in ipairs(modes) do - for _, key in ipairs(arrows) do - vim.api.nvim_set_keymap(mode, key, '', opts) - end -end - --- Go to Beginning or End of line -map({ 'n', 'v' }, 'H', '_^', { desc = 'Move to the beginning of the line' }) -map({ 'n', 'v' }, 'L', '$', { desc = 'Move to the end of the line' }) - --- Search inside visually highlighted text. -map('x', 'g/', '/\\%V', { silent = false, desc = 'Search inside visual selection' }) - --- Search & replace in current file/line -map('v', 'rw', '"9y:%s@9@9@g', { desc = 'Search & replace selection', silent = false }) -map('n', 'rw', 'viw"9y:%s@9@9@g', { desc = 'Search & replace word', silent = false }) -map( - 'v', - 'rl', - '"9y:s@9@9@g', - { desc = 'Search & replace in current line', silent = false } -) -map( - 'n', - 'rl', - 'viw"9y:s@9@9@g', - { desc = 'Search & replace word in current line', silent = false } -) - --- Folds -map('n', '<', function() - if not vim.opt.foldmethod then - vim.opt.foldmethod = 'indent' - end - vim.cmd('normal! zM') -end, { desc = 'Fold all' }) - -map('n', '>', function() - vim.opt.foldenable = false - vim.cmd('normal! zR') -end, { desc = 'Open all folds' }) diff --git a/lua/config/lazy.lua b/lua/config/lazy.lua deleted file mode 100644 index 2d6e473..0000000 --- a/lua/config/lazy.lua +++ /dev/null @@ -1,48 +0,0 @@ --------------------------------------------------------------------------------- --- Bootstrap lazy plugin manager --------------------------------------------------------------------------------- -local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' -if not (vim.uv or vim.loop).fs_stat(lazypath) then - local lazyrepo = 'https://github.com/folke/lazy.nvim.git' - local out = vim.fn.system({ 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath }) - if vim.v.shell_error ~= 0 then - vim.api.nvim_echo({ - { 'Failed to clone lazy.nvim:\n', 'ErrorMsg' }, - { out, 'WarningMsg' }, - { '\nPress any key to exit...' }, - }, true, {}) - vim.fn.getchar() - os.exit(1) - end -end -vim.opt.rtp:prepend(lazypath) - --- lazy config -require('lazy').setup({ - spec = { - { import = 'plugins' }, - }, - install = { - missing = true, - colorscheme = { 'gruvbox' }, - }, - change_detection = { - enable = true, - notify = false, - }, - ui = { - border = 'rounded', - backdrop = 100, - }, - rtp = { - -- disable some rtp plugins - disabled_plugins = { - 'gzip', - 'tarPlugin', - 'tohtml', - 'tutor', - 'netrwPlugin', - 'zipPlugin', - }, - }, -}) diff --git a/lua/config/lsp.lua b/lua/config/lsp.lua deleted file mode 100644 index 31cac1b..0000000 --- a/lua/config/lsp.lua +++ /dev/null @@ -1,100 +0,0 @@ --------------------------------------------------------------------------------- --- LSP --------------------------------------------------------------------------------- - --- ts_ls -vim.lsp.config("ts_ls", { - settings = { - typescript = { - inlayHints = { - includeInlayParameterNameHints = "all", - includeInlayParameterNameHintsWhenArgumentMatchesName = false, - includeInlayFunctionParameterTypeHints = true, - includeInlayVariableTypeHints = true, - includeInlayPropertyDeclarationTypeHints = true, - includeInlayFunctionLikeReturnTypeHints = true, - includeInlayEnumMemberValueHints = true, - }, - }, - }, -}) -vim.lsp.enable("ts_ls") - -vim.lsp.enable("html") -vim.lsp.enable("cssls") -vim.lsp.enable("tailwindcss") - --- rust -vim.lsp.config("rust_analyzer", { - settings = { - ["rust-analyzer"] = { - diagnostics = { - enable = true, - experimental = { enable = true }, - }, - }, - }, -}) -vim.lsp.enable("rust_analyzer") - --- lua -vim.lsp.config("lua_ls", { - settings = { - Lua = { - diagnostics = { - disable = { - "missing-fields", - "undefined-global", - }, - }, - }, - }, -}) -vim.lsp.enable("lua_ls") - --- python -vim.lsp.config("basedpyright", { - settings = { - basedpyright = { - inlayHints = true, - analysis = { - diagnosticSeverityOverrides = { - reportUnusedImport = "none", - reportUnusedVariable = "none", - reportAttributeAccessIssue = "none", - reportUnusedClass = "none", - reportUnusedFunction = "none", - reportDuplicateImport = "none", - reportArgumentType = "error", - }, - typeCheckingMode = "standard", - }, - }, - }, -}) -vim.lsp.enable("basedpyright") - - - --- bash -vim.lsp.config("bashls", { - settings = { - bashIde = { - shellcheckArguments = { - "--exclude=SC1090,SC1091,SC2076,SC2164", - }, - }, - }, -}) -vim.lsp.enable("bashls") - --- cpp -vim.lsp.config("clangd", { - cmd = { - "clangd", - "--fallback-style=llvm", - "--header-insertion=iwyu", - "-j=4", - }, -}) -vim.lsp.enable("clangd") diff --git a/lua/config/options.lua b/lua/config/options.lua deleted file mode 100644 index c333208..0000000 --- a/lua/config/options.lua +++ /dev/null @@ -1,67 +0,0 @@ -local options = { - ai = true, - clipboard = 'unnamedplus', -- use system clipboard - number = true, - relativenumber = true, - undofile = true, -- save state of file on write - undodir = vim.fn.stdpath('cache') .. '/undo', - undolevels = 10000, - autoread = true, -- autoread changes from other sources - signcolumn = 'yes', - cursorline = true, - cursorlineopt = 'number', - wrap = false, - scrolloff = 3, - ruler = false, -- removes cursor position from lastline - pumheight = 10, -- size of completion window - showmode = false, -- do not show mode under statusline - swapfile = false, -- creates a swapfile - backup = false, -- creates a backup file - writebackup = false, -- do not edit backups - winminwidth = 5, -- Minimum window width - termguicolors = true, -- set term gui colors (most terminals support this) - showtabline = 0, -- always show tabs - showcmd = false, - mouse = 'a', -- allow the mouse to be used in neovim - confirm = true, -- Confirm to save changes before exiting modified buffer - - -- tabs - smarttab = true, - tabstop = 4, -- 1 tab represented as 4 spaces - expandtab = true, -- key will create " " instead of "\t" - shiftwidth = 4, -- indent change after backspace and >> << - softtabstop = 4, -- number of spaces instead of tab - autoindent = true, -- auto indent - smartindent = true, -- make indenting smarter again - list = true, - -- listchars = { trail = "", tab = "", nbsp = "_", extends = ">", precedes = "<" }, -- highlight - showbreak = string.rep(' ', 3), - - -- Search - ignorecase = true, - smartcase = true, - hlsearch = true, - wildmenu = true, - wildmode = 'longest:full,full', - wildoptions = 'pum', - - -- Window - splitright = true, - splitbelow = true, - title = true, -} - -for k, v in pairs(options) do - vim.opt[k] = v -end - -vim.g.loaded_netrw = 1 -vim.g.loaded_netrwPlugin = 1 - -vim.opt.path:append({ '**' }) -vim.opt.shortmess:append({ W = true, I = true, c = true }) -- disable greeting - --- Fix markdown indentation settings -vim.g.markdown_recommended_style = 0 - -vim.cmd([[set fillchars+=eob:\ ]]) diff --git a/lua/extensions.lua b/lua/extensions.lua new file mode 100644 index 0000000..abad39e --- /dev/null +++ b/lua/extensions.lua @@ -0,0 +1,66 @@ +local treesitter_parsers = { + "c", + "markdown", + "python", + "java", + "cpp", + "bash", + "lua", + "make", + "json", + "jsonc", + "sql", + "yaml", + "toml", + "javascript", + "typescript", + "gitignore", + "go", + "rust", + "html", + "css", + "scss", + "markdown_inline", +} + +local lsp_server = { + "ts_ls", + "html", + "cssls", + "tailwindcss", + "lua_ls", + "basedpyright", + "bashls", + "clangd", + "rust_analyzer", +} + +local formatter = { + "clang_format", + "ruff", + "stylua", + "prettier", + "markdown-toc", + "markdownlint-cli2", + "biome", +} + +local linter = { + "eslint_d", + "hadolint", + "write_good", + "markdownlint", + "shellcheck", + "actionlint", + "djlint", + "ruff", + "codespell", + "cspell", +} + +return { + ts_parsers = treesitter_parsers, + lsp_server = lsp_server, + formatter = formatter, + linter = linter, +} diff --git a/lua/keys.lua b/lua/keys.lua new file mode 100644 index 0000000..83d4afa --- /dev/null +++ b/lua/keys.lua @@ -0,0 +1,143 @@ +local function map(mode, lhs, rhs, opts) + opts = opts or {} + opts.silent = opts.silent ~= false + vim.keymap.set(mode, lhs, rhs, opts) +end +local opts = { noremap = true, silent = true } + +-- Space as leader +map("n", "", "", opts) +vim.g.mapleader = " " +vim.g.maplocalleader = " " + +-- Modes +-- normal_mode = "n", insert_mode = "i", visual_mode = "v", +-- visual_block_mode = "x", term_mode = "t", command_mode = "c", + +-- Terminal Mappings +map("t", "jk", "") +map("t", "kj", "") +map("t", "", "") + +-- Clear search, diff update and redraw +map({ "i", "n" }, "", "noh", { desc = "Escape and clear hlsearch" }) + +map({ "i", "c" }, "", "") +map({ "i", "c" }, "", "") + +map("n", "rL", vim.lsp.buf.rename, { desc = "Rename Lsp Symbol" }) +map("n", "`", "'", { noremap = true }) -- better marks + +map({ "n", "v" }, "H", "^", { desc = "Move to the beginning of the line" }) +map({ "n", "v" }, "L", "$", { desc = "Move to the end of the line" }) + +-- Visual overwrite paste +map({ "v", "x" }, "p", '"_dP', opts) + +-- Do not copy on x +map({ "v", "x" }, "x", '"_x', opts) +map("n", "X", '"_D', opts) +map("n", "dd", '"_dd', opts) +map({ "v", "x" }, "X", '"_d', opts) + +-- Select all + +-- Select all +map("n", "a", "ggVG", { desc = "Select all" }) +map("n", "", "ggVG", { desc = "Select all" }) +map("i", "", "ggVG", { desc = "Select all" }) + +-- Move text up and down +map({ "v", "x" }, "K", ":move '<-2gv-gv", opts) +map({ "v", "x" }, "J", ":move '>+1gv-gv", opts) + +-- Line operations +map("n", "", ":m .-2==", { desc = "Move line up" }) +map("n", "", ":m .+1==", { desc = "Move line down" }) +map("i", "", ":m .-2==gi", { desc = "Move line up" }) +map("i", "", ":m .+1==gi", { desc = "Move line down" }) +map("v", "", ":m '<-2gv=gv", { desc = "Move selection up" }) +map("v", "", ":m '>+1gv=gv", { desc = "Move selection down" }) + +-- Line manipulation +map("n", "", ">>", { desc = "Indent line" }) +map("n", "", "<<", { desc = "Unindent line" }) +map("i", "", ">>", { desc = "Indent line" }) +map("i", "", "<<", { desc = "Unindent line" }) + +-- Quick word operations +map("n", "", "db", { desc = "Delete word backward" }) +map("i", "", "", { desc = "Delete word backward" }) +map("n", "", "dw", { desc = "Delete word forward" }) +map("i", "", "dw", { desc = "Delete word forward" }) + +map("n", "d", '"_d', { desc = "Delete without replacing clipboard" }) +map("n", "x", '"_x', { desc = "Cut without replacing clipboard" }) +map("n", "c", '"_c', { desc = "Change without replacing clipboard" }) +map("v", "p", '"_dP', { desc = "Paste without replacing clipboard" }) + +--insert the following characters around the visual selection +map("v", "(", "s()Pll", { desc = "wrap selection with parens" }) +map("v", "[", "s[]Pll", { desc = "wrap selection with square braces" }) +map("v", "{", "s{}Pll", { desc = "wrap selection with curly braces" }) +map("v", "'", "s''Pll", { desc = "wrap selection with single quotes" }) +map("v", '"', 's""Pll', { desc = "wrap selection with double quotes" }) + +-- Insert mode cursor movement with Ctrl+hjkl +map({ "i", "c" }, "", "", { noremap = true, silent = true }) +map({ "i", "c" }, "", "", { noremap = true, silent = true }) +map({ "i", "c" }, "", "", { noremap = true, silent = true }) +map({ "i", "c" }, "", "", { noremap = true, silent = true }) + +map("n", "re", ":%s//", { desc = "Shortcut to replace current word under cursor" }) + +-- toggle inlay hints +vim.keymap.set("n", "th", function() + vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) +end) + +-- No arrow navigation +local modes = { "n", "v", "i" } +local arrows = { "", "", "", "" } + +for _, mode in ipairs(modes) do + for _, key in ipairs(arrows) do + vim.api.nvim_set_keymap(mode, key, "", opts) + end +end + +-- Go to Beginning or End of line +map({ "n", "v" }, "H", "_^", { desc = "Move to the beginning of the line" }) +map({ "n", "v" }, "L", "$", { desc = "Move to the end of the line" }) + +-- Search inside visually highlighted text. +map("x", "g/", "/\\%V", { silent = false, desc = "Search inside visual selection" }) + +-- Search & replace in current file/line +map("v", "rw", '"9y:%s@9@9@g', { desc = "Search & replace selection", silent = false }) +map("n", "rw", 'viw"9y:%s@9@9@g', { desc = "Search & replace word", silent = false }) +map( + "v", + "rl", + '"9y:s@9@9@g', + { desc = "Search & replace in current line", silent = false } +) +map( + "n", + "rl", + 'viw"9y:s@9@9@g', + { desc = "Search & replace word in current line", silent = false } +) + +-- Folds +map("n", "<", function() + if not vim.opt.foldmethod then + vim.opt.foldmethod = "indent" + end + vim.cmd("normal! zM") +end, { desc = "Fold all" }) + +map("n", ">", function() + vim.opt.foldenable = false + vim.cmd("normal! zR") +end, { desc = "Open all folds" }) diff --git a/lua/lsp.lua b/lua/lsp.lua new file mode 100644 index 0000000..843f090 --- /dev/null +++ b/lua/lsp.lua @@ -0,0 +1,113 @@ +-------------------------------------------------------------------------------- +-- LSP +-------------------------------------------------------------------------------- + +vim.api.nvim_create_autocmd("User", { + pattern = "PackerComplete", -- Fallback or custom event if needed, but let's use a more standard one + callback = function() + -- This is where we would put it if we had a specific event. + -- Since we're using VimEnter, let's use that instead. + end, +}) + +-- Let's use a simple function and schedule it to run after plugins +vim.schedule(function() + vim.lsp.config("*", { + capabilities = require("blink.cmp").get_lsp_capabilities(), + }) + + -- ts_ls + vim.lsp.config("ts_ls", { + settings = { + typescript = { + inlayHints = { + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = false, + includeInlayFunctionParameterTypeHints = true, + includeInlayVariableTypeHints = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayEnumMemberValueHints = true, + }, + }, + }, + }) + vim.lsp.enable("ts_ls") + + vim.lsp.enable("html") + vim.lsp.enable("cssls") + vim.lsp.enable("tailwindcss") + + -- rust + vim.lsp.config("rust_analyzer", { + settings = { + ["rust-analyzer"] = { + diagnostics = { + enable = true, + experimental = { enable = true }, + }, + }, + }, + }) + vim.lsp.enable("rust_analyzer") + + -- lua + vim.lsp.config("lua_ls", { + settings = { + Lua = { + diagnostics = { + disable = { + "missing-fields", + "undefined-global", + }, + }, + }, + }, + }) + vim.lsp.enable("lua_ls") + + -- python + vim.lsp.config("basedpyright", { + settings = { + basedpyright = { + inlayHints = true, + analysis = { + diagnosticSeverityOverrides = { + reportUnusedImport = "none", + reportUnusedVariable = "none", + reportAttributeAccessIssue = "none", + reportUnusedClass = "none", + reportUnusedFunction = "none", + reportDuplicateImport = "none", + reportArgumentType = "error", + }, + typeCheckingMode = "standard", + }, + }, + }, + }) + vim.lsp.enable("basedpyright") + + -- bash + vim.lsp.config("bashls", { + settings = { + bashIde = { + shellcheckArguments = { + "--exclude=SC1090,SC1091,SC2076,SC2164", + }, + }, + }, + }) + vim.lsp.enable("bashls") + + -- cpp + vim.lsp.config("clangd", { + cmd = { + "clangd", + "--fallback-style=llvm", + "--header-insertion=iwyu", + "-j=4", + }, + }) + vim.lsp.enable("clangd") +end) diff --git a/lua/options.lua b/lua/options.lua new file mode 100644 index 0000000..e335ea4 --- /dev/null +++ b/lua/options.lua @@ -0,0 +1,67 @@ +local options = { + ai = true, + clipboard = "unnamedplus", -- use system clipboard + number = true, + relativenumber = true, + undofile = true, -- save state of file on write + undodir = vim.fn.stdpath("cache") .. "/undo", + undolevels = 10000, + autoread = true, -- autoread changes from other sources + signcolumn = "yes", + cursorline = true, + cursorlineopt = "number", + wrap = false, + scrolloff = 3, + ruler = false, -- removes cursor position from lastline + pumheight = 10, -- size of completion window + showmode = false, -- do not show mode under statusline + swapfile = false, -- creates a swapfile + backup = false, -- creates a backup file + writebackup = false, -- do not edit backups + winminwidth = 5, -- Minimum window width + termguicolors = true, -- set term gui colors (most terminals support this) + showtabline = 0, -- always show tabs + showcmd = false, + mouse = "a", -- allow the mouse to be used in neovim + confirm = true, -- Confirm to save changes before exiting modified buffer + + -- tabs + smarttab = true, + tabstop = 4, -- 1 tab represented as 4 spaces + expandtab = true, -- key will create " " instead of "\t" + shiftwidth = 4, -- indent change after backspace and >> << + softtabstop = 4, -- number of spaces instead of tab + autoindent = true, -- auto indent + smartindent = true, -- make indenting smarter again + list = true, + listchars = { tab = "» ", trail = "·", nbsp = "␣" }, + showbreak = string.rep(" ", 3), + + -- Search + ignorecase = true, + smartcase = true, + hlsearch = true, + wildmenu = true, + wildmode = "longest:full,full", + wildoptions = "pum", + + -- Window + splitright = true, + splitbelow = true, + title = true, +} + +for k, v in pairs(options) do + vim.opt[k] = v +end + +vim.g.loaded_netrw = 1 +vim.g.loaded_netrwPlugin = 1 + +vim.opt.path:append({ "**" }) +vim.opt.shortmess:append({ W = true, I = true, c = true }) -- disable greeting + +-- Fix markdown indentation settings +vim.g.markdown_recommended_style = 0 + +vim.cmd([[set fillchars+=eob:\ ]]) diff --git a/lua/pack_helper.lua b/lua/pack_helper.lua new file mode 100644 index 0000000..849cb82 --- /dev/null +++ b/lua/pack_helper.lua @@ -0,0 +1,71 @@ +local M = {} + +-- Define sources outside the function to avoid re-allocation +local SOURCES = { + gl = "https://gitlab.com/", + cb = "https://codeberg.org/", + gh = "https://github.com/", +} + +--- Resolves a shorthand URL or full URL to its canonical form. +local function resolve_url(url) + if not url or url:match("^https?://") then + return url + end + + -- Extract prefix if present (e.g., 'gl:user/repo') + local prefix, rest = url:match("^(%w+):(.+)$") + if prefix and SOURCES[prefix] then + return SOURCES[prefix] .. rest + end + + -- Default to GitHub if no prefix or unknown prefix + return SOURCES.gh .. url +end + +--- Normalizes a plugin specification. +local function normalize_spec(spec) + if type(spec) == "string" then + return resolve_url(spec) + elseif type(spec) == "table" and spec.src then + spec.src = resolve_url(spec.src) + return spec + end + return spec +end + +--- Global helper to add plugins to the package manager. +--- Supports shorthand for GitHub (default), GitLab (gl:), and Codeberg (cb:). +--- +--- Examples: +--- add("user/repo") --> https://github.com/user/repo +--- add("gl:user/repo") --> https://gitlab.com/user/repo +--- add("cb:user/repo") --> https://codeberg.org/user/repo +--- add({ "user/repo", version = "main" }) +--- add({ "user/repo", "gl:other/repo" }) +--- +_G.add = function(specs) + -- Normalize input to a table if a single spec is provided + local list = type(specs) == "table" and (specs.src or not specs[1]) and { specs } or specs + if type(list) ~= "table" then + list = { specs } + end + + local resolved = {} + for _, spec in ipairs(list) do + local normalized = normalize_spec(spec) + if normalized then + table.insert(resolved, normalized) + end + end + + if #resolved > 0 then + -- Wrap in pcall to handle potential vim.pack errors gracefully + local ok, err = pcall(vim.pack.add, resolved) + if not ok then + vim.notify("vim.pack.add failed: " .. tostring(err), vim.log.levels.ERROR, { title = "Pack Helper" }) + end + end +end + +return M diff --git a/lua/plugins/ai.lua b/lua/plugins/ai.lua deleted file mode 100644 index 1f0492d..0000000 --- a/lua/plugins/ai.lua +++ /dev/null @@ -1,14 +0,0 @@ -return { - { - 'Exafunction/windsurf.vim', - event = 'VeryLazy', - config = function() - vim.keymap.set('i', '', function() - return vim.fn['codeium#Accept']() - end, { expr = true, silent = true }) - vim.keymap.set('i', '', function() - return vim.fn['codeium#Clear']() - end, { expr = true, silent = true }) - end, - }, -} diff --git a/lua/plugins/coding.lua b/lua/plugins/coding.lua deleted file mode 100644 index f54be95..0000000 --- a/lua/plugins/coding.lua +++ /dev/null @@ -1,126 +0,0 @@ -return { - - -- completion - { - 'saghen/blink.cmp', - version = '*', - config = function() - require('blink.cmp').setup({ - fuzzy = { implementation = 'prefer_rust' }, - snippets = { preset = 'luasnip' }, - sources = { - default = { 'lsp', 'path', 'snippets', 'buffer' }, - providers = {}, - }, - - completion = { - ghost_text = { enabled = true }, - - list = { - selection = { - preselect = false, - auto_insert = true, - }, - }, - documentation = { - window = { border = 'rounded' }, - auto_show = true, - auto_show_delay_ms = 50, - }, - menu = { - border = 'rounded', - draw = { - components = { - kind_icon = { - text = function(ctx) - local kind_icon, _, _ = require('mini.icons').get('lsp', ctx.kind) - return kind_icon - end, - highlight = function(ctx) - local _, hl, _ = require('mini.icons').get('lsp', ctx.kind) - return hl - end, - }, - kind = { - highlight = function(ctx) - local _, hl, _ = require('mini.icons').get('lsp', ctx.kind) - return hl - end, - }, - }, - }, - }, - }, - signature = { - window = { border = 'rounded' }, - }, - keymap = { - preset = 'none', - [''] = { 'select_prev', 'snippet_backward', 'fallback' }, - [''] = { 'select_next', 'snippet_forward', 'fallback' }, - [''] = { 'accept', 'fallback' }, - [''] = { 'hide', 'show' }, - [''] = { 'show', 'show_documentation', 'hide_documentation' }, - [''] = { 'scroll_documentation_up', 'fallback' }, - [''] = { 'scroll_documentation_down', 'fallback' }, - }, - }) - end, - }, - - -- snippets - { - 'L3MON4D3/LuaSnip', - version = '*', - dependencies = { 'rafamadriz/friendly-snippets' }, - config = function() - local luasnip = require('luasnip') - require('luasnip.loaders.from_vscode').lazy_load() - require('luasnip.loaders.from_vscode').lazy_load({ - paths = { vim.fn.stdpath('config') .. '/snippets' }, - }) - - luasnip.filetype_extend('mdx', { 'markdown' }) - end, - }, - - -- comment - { - 'numToStr/Comment.nvim', - dependencies = { - 'JoosepAlviste/nvim-ts-context-commentstring', - }, - config = function() - require('Comment').setup({ - pre_hook = require('ts_context_commentstring.integrations.comment_nvim').create_pre_hook(), - mappings = { - basic = true, - extra = true, - }, - }) - end, - keys = { - { 'gcc', mode = 'n', desc = 'Toggle comment line' }, - { 'gc', mode = { 'n', 'o' }, desc = 'Toggle comment linewise' }, - { 'gc', mode = 'x', desc = 'Toggle comment linewise (visual)' }, - { 'gbc', mode = 'n', desc = 'Toggle comment block' }, - { 'gb', mode = { 'n', 'o' }, desc = 'Toggle comment blockwise' }, - { 'gb', mode = 'x', desc = 'Toggle comment blockwise (visual)' }, - }, - }, - - -- annotation generator - { - 'danymat/neogen', - opts = { - snippet_engine = 'luasnip', - languages = { - python = { - template = { - annotation_convention = 'google_docstrings', - }, - }, - }, - }, - }, -} diff --git a/lua/plugins/colorscheme.lua b/lua/plugins/colorscheme.lua deleted file mode 100644 index 4bf3efe..0000000 --- a/lua/plugins/colorscheme.lua +++ /dev/null @@ -1,39 +0,0 @@ -return { - "ellisonleao/gruvbox.nvim", - priority = 1000, - config = function() - local palette = require("gruvbox").palette - require("gruvbox").setup({ - bold = false, - italic = { - strings = false, - emphasis = false, - comments = false, - folds = false, - }, - contrast = "hard", - transparent_mode = true, - overrides = { - -- builtin - SignColumn = { bg = "None" }, - CursorLineNr = { bg = "None" }, - Whitespace = { fg = palette.dark0 }, - EndOfBuffer = { fg = palette.dark0_hard }, - Visual = { fg = "None", bg = palette.dark1 }, - Label = { link = "GruvboxPurple" }, - - -- blink.cmp - BlinkCmpMenu = { link = "Normal" }, - BlinkCmpMenuBorder = { link = "BlinkCmpMenu" }, - BlinkCmpMenuSelection = { fg = "None", bg = palette.dark1 }, - BlinkCmpLabelMatch = { fg = palette.bright_green }, - BlinkCmpScrollBarGutter = { bg = palette.dark2 }, - BlinkCmpScrollBarThumb = { bg = palette.light1 }, - - -- indent guides - MiniIndentscopeSymbol = { fg = palette.dark1 }, - }, - }) - vim.cmd.colorscheme("gruvbox") - end, -} diff --git a/lua/plugins/editor.lua b/lua/plugins/editor.lua deleted file mode 100644 index 6a04514..0000000 --- a/lua/plugins/editor.lua +++ /dev/null @@ -1,100 +0,0 @@ -return { - - -- Todo Comments - { - 'folke/todo-comments.nvim', - event = 'BufRead', - opts = {}, - }, - - -- Working with file permissions - { - 'lambdalisue/vim-suda', - cmd = { 'SudaRead', 'SudaWrite' }, - }, - - -- visual multi - { - 'mg979/vim-visual-multi', - event = 'VeryLazy', - init = function() - vim.g.VM_maps = { - ['Find Under'] = '', - ['Find Subword Under'] = '', - ['Select All'] = '', - ['Add Cursor Down'] = '', - ['Add Cursor Up'] = '', - } - end, - }, - - -- dimming the highlights of unused functions, variables, parameters, and more - { - 'zbirenbaum/neodim', - enabled = false, - event = 'LspAttach', - config = function() - require('neodim').setup({ - alpha = 0.5, - blend_color = nil, - hide = { - underline = true, - virtual_text = true, - signs = true, - }, - regex = { - '[uU]nused', - '[nN]ever [rR]ead', - '[nN]ot [rR]ead', - }, - priority = 128, - disable = {}, - }) - end, - }, - - -- file operations - { - 'chrisgrieser/nvim-genghis', - keys = { - { - 'fn', - function() - require('genghis').createNewFile() - end, - desc = 'New File', - }, - { - 'fd', - function() - require('genghis').duplicateFile() - end, - desc = 'Duplicate File', - }, - { - 'fr', - function() - require('genghis').renameFile() - end, - desc = 'Rename File', - }, - { - 'fz', - function() - require('genghis').chmodx() - end, - desc = 'Make Executable', - }, - }, - }, - - -- markdown preview - { - 'iamcco/markdown-preview.nvim', - cmd = { 'MarkdownPreviewToggle', 'MarkdownPreview', 'MarkdownPreviewStop' }, - ft = { 'markdown' }, - build = function() - vim.fn['mkdp#util#install']() - end, - }, -} diff --git a/lua/plugins/formatting.lua b/lua/plugins/formatting.lua deleted file mode 100644 index 9716fb3..0000000 --- a/lua/plugins/formatting.lua +++ /dev/null @@ -1,64 +0,0 @@ -return { - "stevearc/conform.nvim", - dependencies = { "zapling/mason-conform.nvim" }, - event = "BufWritePre", - cmd = "ConformInfo", - keys = { "tf" }, - config = function() - require("conform").setup({ - formatters = { - ["markdown-toc"] = { - condition = function(_, ctx) - for _, line in ipairs(vim.api.nvim_buf_get_lines(ctx.buf, 0, -1, false)) do - if line:find("") then - return true - end - end - end, - }, - ["markdownlint-cli2"] = { - condition = function(_, ctx) - local diag = vim.tbl_filter(function(d) - return d.source == "markdownlint" - end, vim.diagnostic.get(ctx.buf)) - return #diag > 0 - end, - }, - }, - formatters_by_ft = { - ["lua"] = { "stylua" }, - ["c"] = { "clang_format" }, - ["cpp"] = { "clang_format" }, - ["h"] = { "clang_format" }, - ["python"] = { "ruff_fix", "ruff_format", "ruff_organize_imports" }, - ["javascript"] = { "biome" }, - ["typescript"] = { "biome" }, - ["typescriptreact"] = { "biome" }, - ["markdown"] = { "prettier", "markdownlint-cli2", "markdown-toc" }, - ["markdown.mdx"] = { "prettier", "markdownlint-cli2", "markdown-toc" }, - ["mdx"] = { "prettier" }, - ["_"] = { "trim_whitespace" }, - }, - options = { - stop_after_first = true, - }, - format_after_save = function(bufnr) - if not vim.b[bufnr].conform_disable then - return { - lsp_format = "fallback", - } - end - end, - }) - - vim.keymap.set("n", "tf", function() - vim.b.conform_disable = not vim.b.conform_disable - local status = vim.b.conform_disable and "disabled" or "enabled" - vim.notify("Autoformat " .. status, vim.log.levels.INFO) - end, { desc = "Toggle autoformat" }) - require("mason-conform").setup({ - ensure_installed = require("config.extensions").formatter, - automatic_installation = true, - }) - end, -} diff --git a/lua/plugins/git.lua b/lua/plugins/git.lua deleted file mode 100644 index 5ea01a8..0000000 --- a/lua/plugins/git.lua +++ /dev/null @@ -1,61 +0,0 @@ -return { - -- gitignore generator - { - 'wintermute-cell/gitignore.nvim', - cmd = { 'Gitignore' }, - opts = {}, - }, - - -- git signs - { - 'lewis6991/gitsigns.nvim', - events = { 'BufReadPost', 'BufNewFile' }, - opts = { - signcolumn = true, - current_line_blame = true, - attach_to_untracked = false, - current_line_blame_formatter = ', - ', - watch_gitdir = { - follow_files = true, - }, - current_line_blame_opts = { - virt_text = true, - virt_text_pos = 'eol', -- 'eol' | 'overlay' | 'right_align' - delay = 1000, - ignore_whitespace = false, - virt_text_priority = 100, - use_focus = true, - }, - signs = { - add = { text = ' ' }, - change = { text = '󱗜 ' }, - delete = { text = '󰍵 ' }, - topdelete = { text = '󱥨 ' }, - changedelete = { text = '󰾟 ' }, - untracked = { text = '󰰧 ' }, - }, - }, - }, - - -- lazygit integration - { - 'kdheepak/lazygit.nvim', - lazy = true, - enabled = true, - cmd = { - 'LazyGit', - 'LazyGitConfig', - 'LazyGitCurrentFile', - 'LazyGitFilter', - 'LazyGitFilterCurrentFile', - }, - keys = { - { 'lg', 'LazyGit', desc = 'LazyGit' }, - }, - config = function() - vim.g.lazygit_floating_window_winblend = 0 - vim.g.lazygit_floating_window_scaling_factor = 0.9 - vim.g.lazygit_floating_window_border_chars = { '╭', '─', '╮', '│', '╯', '─', '╰', '│' } - end, - }, -} diff --git a/lua/plugins/linting.lua b/lua/plugins/linting.lua deleted file mode 100644 index 3836822..0000000 --- a/lua/plugins/linting.lua +++ /dev/null @@ -1,34 +0,0 @@ -return { - "mfussenegger/nvim-lint", - dependencies = { "rshkarin/mason-nvim-lint" }, - event = { "BufReadPost", "BufNewFile" }, - keys = { - { - "cL", - mode = { "n" }, - function() - require("lint").try_lint() - end, - desc = "Trigger linting for current file", - }, - }, - config = function() - require("lint").linters_by_ft = { - ["*"] = { "codespell" }, - ["javascript"] = { "eslint_d", "cspell" }, - ["typescript"] = { "eslint_d", "cspell" }, - ["javascriptreact"] = { "eslint_d", "cspell" }, - ["typescriptreact"] = { "eslint_d", "cspell" }, - ["dockerfile"] = { "hadolint" }, - ["markdown"] = { "write_good", "markdownlint" }, - ["text"] = { "write_good" }, - ["sh"] = { "shellcheck" }, - ["yaml"] = { "actionlint" }, - ["python"] = { "ruff" }, - } - require("mason-nvim-lint").setup({ - ensure_installed = require("config.extensions").linter, - automatic_installation = false, - }) - end, -} diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua deleted file mode 100644 index 03cee36..0000000 --- a/lua/plugins/lsp.lua +++ /dev/null @@ -1,109 +0,0 @@ -return { - -- default lsp configs - { - 'neovim/nvim-lspconfig', - config = function() end, - }, - - -- lsp installer - { - 'williamboman/mason.nvim', - dependencies = { - 'williamboman/mason-lspconfig.nvim', - }, - cmd = 'Mason', - config = function() - -- mason - require('mason').setup({ - ui = { - icons = { - package_installed = '✓', - package_pending = '➜', - package_uninstalled = '✗', - }, - border = 'rounded', - backdrop = 100, - }, - }) - require('mason-lspconfig').setup({ - ensure_installed = require('config.extensions').lsp_server, - automatic_installation = false, -- Don't auto-install or auto-configure - }) - end, - }, - - -- improve neovim lsp experience - { - 'nvimdev/lspsaga.nvim', - event = 'LspAttach', - config = function() - require('lspsaga').setup({ - ui = { - theme = 'round', - border = 'rounded', - devicon = true, - title = true, - winblend = 1, - expand = ' ', - collapse = ' ', - preview = '', - code_action = '󰠠 ', - diagnostic = ' ', - incoming = ' ', - outgoing = ' ', - hover = ' ', - }, - }) - end, - }, - - -- inline diagnostic - { - 'rachartier/tiny-inline-diagnostic.nvim', - event = 'VeryLazy', - priority = 1000, - config = function() - require('tiny-inline-diagnostic').setup({ - options = { - show_source = true, - multiple_diag_under_cursor = true, - -- break_line = { - -- enabled = true, - -- after = 60, - -- } - }, - }) - vim.diagnostic.config({ virtual_text = false }) -- Disable default virtual text - end, - }, - - -- code action - { - 'rachartier/tiny-code-action.nvim', - dependencies = { - { - 'folke/snacks.nvim', - opts = { - terminal = {}, - }, - }, - }, - event = 'LspAttach', - config = function() - local codeaction = require('tiny-code-action') - - codeaction.setup({ - picker = { - 'buffer', - opts = { - auto_preview = true, - hotkeys = true, - hotkeys_mode = 'sequential', - }, - }, - }) - - vim.keymap.set('n', '.', codeaction.code_action) - end, - }, -} diff --git a/lua/plugins/mini.lua b/lua/plugins/mini.lua deleted file mode 100644 index 6fc88b6..0000000 --- a/lua/plugins/mini.lua +++ /dev/null @@ -1,161 +0,0 @@ -return { - 'echasnovski/mini.nvim', - config = function() - require('mini.ai').setup() -- Extend and create a/i textobjects - require('mini.pairs').setup() -- Autopairs - require('mini.icons').setup() -- Icons - require('mini.bracketed').setup() -- Go forward/backward with square brackets - - -- File explorer - require('mini.files').setup({ - mappings = { - close = 'q', - go_in = 'L', - go_in_plus = 'l', - go_out = 'h', - go_out_plus = 'H', - mark_goto = "'", - mark_set = 'm', - reset = '', - reveal_cwd = '@', - show_help = 'g?', - synchronize = '', - trim_left = '<', - trim_right = '>', - }, - }) - - require('mini.misc').setup({ - -- restore cursor position on file reopen - require('mini.misc').setup_restore_cursor(), - -- automated change of current directory - require('mini.misc').setup_auto_root(), - }) - - -- splitjoin - require('mini.splitjoin').setup({ - mappings = { - toggle = 'tj', - split = '', - join = '', - }, - }) - - -- surround action - require('mini.surround').setup({ - mappings = { - add = 'msa', - delete = 'msd', - find = 'msf', - find_left = 'msF', - highlight = 'msh', - replace = 'msr', - update_n_lines = 'msn', - - suffix_last = 'l', - suffix_next = 'n', - }, - }) - - -- indents - require('mini.indentscope').setup({ - draw = { animation = require('mini.indentscope').gen_animation.linear({ ease = 'out', duration = 15 }) }, - options = { border = 'top', try_as_border = true, indent_at_cursor = false }, - }) - - vim.api.nvim_create_autocmd('BufEnter', { - pattern = '*', - callback = function(args) - if vim.bo[args.buf].buftype ~= '' then - vim.b[args.buf].miniindentscope_disable = true - end - end, - }) - - -- statusline - require('mini.statusline').setup({ - use_icons = true, - content = { - active = function() - local mode, mode_hl = MiniStatusline.section_mode({ trunc_width = 120 }) - local git = MiniStatusline.section_git({ trunc_width = 40 }) - local diff = MiniStatusline.section_diff({ trunc_width = 80 }) - local diagnostics = MiniStatusline.section_diagnostics({ trunc_width = 60 }) - local lsp = MiniStatusline.section_lsp({ trunc_width = 40 }) - local filename = MiniStatusline.section_filename({ trunc_width = 140 }) - - local function section_filetype(args) - if - MiniStatusline.is_truncated(args.trunc_width) - or vim.bo.filetype == '' - or vim.bo.buftype ~= '' - then - return '' - end - local ok, icons = pcall(require, 'mini.icons') - local icon = ok and select(1, icons.get('filetype', vim.bo.filetype)) or '' - return string.format('%s %s│', icon, vim.bo.filetype) - end - - local function section_lsp_clients(args) - if MiniStatusline.is_truncated(args.trunc_width) then - return '' - end - local clients = vim.lsp.get_clients({ bufnr = 0 }) - if not clients or #clients == 0 then - return '' - end - local names = vim.tbl_map(function(c) - return c.name - end, clients) - return string.format(' %s', table.concat(names, ', ')) - end - - local function section_searchcount(args) - if vim.v.hlsearch == 0 then - return '' - end - local ok, s = pcall(vim.fn.searchcount, { recompute = true }) - if not ok or s.current == nil or s.total == 0 then - return '' - end - local icon = MiniStatusline.is_truncated(args.trunc_width) and '' or ' ' - if s.incomplete == 1 then - return icon .. '?/?│' - end - local fmt = '>%d' - local cur = s.current > s.maxcount and fmt:format(s.maxcount) or s.current - local tot = s.total > s.maxcount and fmt:format(s.maxcount) or s.total - return ('%s%s/%s│'):format(icon, cur, tot) - end - - local function section_location(args) - return MiniStatusline.is_truncated(args.trunc_width) and '%-2l│%-2v' - or '󰉸 %-2l│󱥖 %-2v' - end - - local filetype = section_filetype({ trunc_width = 70 }) - local searchcount = section_searchcount({ trunc_width = 80 }) - local loc = section_location({ trunc_width = 120 }) - local lsp_clients = section_lsp_clients({ trunc_width = 60 }) - - return MiniStatusline.combine_groups({ - { hl = mode_hl, strings = { mode:upper() } }, - { hl = 'MiniStatuslineDevinfo', strings = { git, diff, diagnostics, lsp } }, - '%<', - { hl = 'MiniStatuslineFilename', strings = { filename } }, - '%=', - { hl = 'MiniStatuslineDevinfo', strings = { lsp_clients } }, - { hl = mode_hl, strings = { filetype, searchcount, loc } }, - }) - end, - - inactive = function() - return MiniStatusline.combine_groups({ - { hl = 'MiniStatuslineInactive', strings = { vim.fn.expand('%:t') } }, - }) - end, - }, - }) - end, -} diff --git a/lua/plugins/snacks.lua b/lua/plugins/snacks.lua deleted file mode 100644 index 83939ee..0000000 --- a/lua/plugins/snacks.lua +++ /dev/null @@ -1,367 +0,0 @@ -return { - 'folke/snacks.nvim', - priority = 1000, - lazy = false, - config = function() - local function files_layout(preview_width, height, width) - preview_width = preview_width or 0.6 - height = height or 0.8 - width = width or 0.9 - return { - layout = { - box = 'horizontal', - width = width, - min_width = 120, - height = height, - { - box = 'vertical', - border = 'rounded', - title = '{title} {live} {flags}', - { win = 'input', height = 1, border = 'bottom' }, - { win = 'list', border = 'none' }, - }, - { win = 'preview', title = '{preview}', border = 'rounded', width = preview_width }, - }, - } - end - - local function palette_layout(height, width) - height = height or 0.4 - width = width or 0.6 - return { - preview = false, - layout = { - backdrop = false, - row = 1, - width = width, - min_width = 80, - height = height, - border = 'rounded', - box = 'vertical', - { - win = 'input', - height = 1, - border = 'rounded', - title = '{title} {live} {flags}', - title_pos = 'center', - }, - { win = 'list', border = 'hpad' }, - { win = 'preview', title = '{preview}', border = 'rounded' }, - }, - } - end - - local Snacks = require('snacks') - Snacks.setup({ - animate = { - enabled = true, - duration = 20, -- ms per step - easing = 'linear', - fps = 60, - }, - bigfile = { - enabled = true, - notify = true, - size = 1000 * 1024, -- 1 MB instead of 100 KB - }, - bufdelete = { enabled = true }, - dashboard = { - preset = { - header = [[ -░█░█░█▀▀░█░█░█▀▀░█▀█░█▀▄░█▀▀░█░█ -░█▀▄░█▀▀░░█░░█░░░█░█░█░█░█▀▀░▄▀▄ -░▀░▀░▀▀▀░░▀░░▀▀▀░▀▀▀░▀▀░░▀▀▀░▀░▀ - ]], - }, - sections = { - { section = 'header' }, - { - icon = ' ', - title = 'Keymaps', - section = 'keys', - indent = 2, - padding = 1, - }, - { - icon = ' ', - title = 'Recent Files', - section = 'recent_files', - indent = 2, - padding = 1, - }, - { - icon = ' ', - title = 'Projects', - section = 'projects', - indent = 2, - padding = 1, - }, - { section = 'startup' }, - }, - }, - debug = { enabled = true }, - dim = { - enabled = true, - scope = { - min_size = 5, - max_size = 20, - siblings = true, - }, - }, - explorer = { enabled = false }, - git = { enabled = true }, - gitbrowse = { enabled = true }, - image = { enabled = true }, - indent = { - enabled = true, - priority = 1, - char = '▍', - only_scope = false, - only_current = false, - hl = { - 'SnacksIndent1', - 'SnacksIndent2', - 'SnacksIndent3', - 'SnacksIndent4', - 'SnacksIndent5', - 'SnacksIndent6', - 'SnacksIndent7', - 'SnacksIndent8', - }, - }, - input = { - enabled = true, - icon = ' ', - icon_hl = 'SnacksInputIcon', - icon_pos = 'left', - prompt_pos = 'title', - win = { style = 'input' }, - expand = true, - }, - layout = { enabled = true }, - lazygit = { enabled = true }, - notifier = { - enabled = true, - timeout = 2000, - width = { min = 40, max = 0.4 }, - height = { min = 1, max = 0.6 }, - margin = { top = 0, right = 1, bottom = 0 }, - padding = true, - sort = { 'level', 'added' }, - level = vim.log.levels.TRACE, - icons = { - debug = ' ', - error = ' ', - info = ' ', - trace = ' ', - warn = ' ', - }, - style = 'compact', - top_down = true, - date_format = '%R', - more_format = ' ↓ %d lines ', - refresh = 50, - }, - notify = { enabled = true }, - picker = { - enabled = true, - icon = ' ', - icon_hl = 'SnacksPickerIcon', - icon_pos = 'left', - prompt_pos = 'title', - win = { style = 'picker' }, - expand = true, - matchers = { - frecency = true, - cwd_bonus = false, - }, - sources = { - -- layout options: dropdown, horizontal, vertical, vscode, ivy, ivy_split, telescope, top, left, right, bottom, sidebar - buffers = { layout = files_layout() }, - commands = { layout = palette_layout() }, - command_history = { layout = palette_layout() }, - files = { - hidden = true, - layout = files_layout(), - }, - icons = { - icon_sources = { 'nerd_fonts', 'emoji' }, - layout = palette_layout(), - }, - git_files = { layout = files_layout() }, - git_branches = { layout = { preset = 'vertical' } }, - git_status = { layout = files_layout() }, - help = { layout = { preset = 'ivy_split' } }, - man = { layout = { preset = 'ivy_split' } }, - notifications = { layout = palette_layout() }, - projects = { layout = files_layout(0.8) }, - recent = { layout = files_layout() }, - search_history = { layout = palette_layout() }, - smart = { layout = files_layout() }, - undo = { layout = { preset = 'ivy' } }, - zoxide = { layout = files_layout(0.7) }, - }, - layout = 'custom', - layouts = { - custom = { - layout = { - box = 'vertical', - backdrop = false, - row = -1, - width = 0, - height = 0.4, - border = 'top', - title = ' {title} {live} {flags}', - title_pos = 'left', - { - box = 'horizontal', - { win = 'list', border = 'rounded' }, - { win = 'preview', title = '{preview}', width = 0.6, border = 'left' }, - }, - { win = 'input', height = 1, border = 'top' }, - }, - }, - }, - }, - profiler = { enabled = true }, - quickfile = { enabled = true }, - rename = { enabled = true }, - scope = { - enabled = true, - keys = { - textobject = { - ii = { - min_size = 2, -- minimum size of the scope - edge = false, -- inner scope - cursor = false, - treesitter = { blocks = { enabled = false } }, - desc = 'inner scope', - }, - ai = { - cursor = false, - min_size = 2, -- minimum size of the scope - treesitter = { blocks = { enabled = false } }, - desc = 'full scope', - }, - }, - jump = { - ['[a'] = { - min_size = 1, -- allow single line scopes - bottom = false, - cursor = false, - edge = true, - treesitter = { blocks = { enabled = false } }, - desc = 'jump to top edge of scope', - }, - [']a'] = { - min_size = 1, -- allow single line scopes - bottom = true, - cursor = false, - edge = true, - treesitter = { blocks = { enabled = false } }, - desc = 'jump to bottom edge of scope', - }, - }, - }, - }, - scratch = { - enabled = true, - name = 'SCRATCH', - ft = function() - if vim.bo.buftype == '' and vim.bo.filetype ~= '' then - return vim.bo.filetype - end - return 'markdown' - end, - icon = nil, - root = vim.fn.stdpath('data') .. '/scratch', - autowrite = true, - filekey = { - cwd = true, - branch = true, - count = true, - }, - win = { - width = 120, - height = 40, - bo = { buftype = '', buflisted = false, bufhidden = 'hide', swapfile = false }, - minimal = false, - noautocmd = false, - zindex = 20, - wo = { winhighlight = 'NormalFloat:Normal' }, - border = 'rounded', - title_pos = 'center', - footer_pos = 'center', - - keys = { - ['execute'] = { - '', - function(_) - vim.cmd('%SnipRun') - end, - desc = 'Execute buffer', - mode = { 'n', 'x' }, - }, - }, - }, - win_by_ft = { - lua = { - keys = { - ['source'] = { - 'cr', - function(self) - local name = 'scratch.' - .. vim.fn.fnamemodify(vim.api.nvim_buf_get_name(self.buf), ':e') - Snacks.debug.run({ buf = self.buf, name = name }) - end, - desc = 'Source buffer', - mode = { 'n', 'x' }, - }, - }, - }, - }, - }, - scroll = { enabled = false }, - statuscolumn = { - enabled = false, -- Change this to false - left = { 'mark', 'sign' }, - right = { 'fold', 'git' }, - folds = { - open = false, - git_hl = false, - }, - git = { - patterns = { 'GitSign', 'MiniDiffSign' }, - }, - refresh = 50, - }, - terminal = { enabled = false }, - toggle = { enabled = false }, - win = { enabled = true }, - words = { enabled = false }, - zen = { - enabled = true, - toggles = { - dim = true, - git_signs = false, - mini_diff_signs = false, - -- diagnostics = false, - -- inlay_hints = false, - }, - show = { - statusline = false, - tabline = false, - }, - win = { style = 'zen' }, - zoom = { - toggles = {}, - show = { statusline = true, tabline = true }, - win = { - backdrop = false, - width = 0, - }, - }, - }, - }) - end, -} diff --git a/lua/plugins/syntax.lua b/lua/plugins/syntax.lua deleted file mode 100644 index c7a91bb..0000000 --- a/lua/plugins/syntax.lua +++ /dev/null @@ -1,78 +0,0 @@ -return { - - -- treesitter - { - 'nvim-treesitter/nvim-treesitter', - build = ':TSUpdate', - event = { 'BufReadPost', 'BufNewFile' }, - config = function() - require('nvim-treesitter').setup({ - ensure_installed = require('config.extensions').ts_parsers, - auto_install = true, - highlight = { - enable = true, - additional_vim_regex_highlighting = true, - }, - indent = { - enable = true, - }, - }) - end, - }, - - -- auto pairs - { - 'windwp/nvim-autopairs', - event = 'InsertEnter', - config = function() - local npairs = require('nvim-autopairs') - local Rule = require('nvim-autopairs.rule') - local conds = require('nvim-autopairs.conds') - - npairs.setup() - - -- Autoclosing angle-brackets. - npairs.add_rule(Rule('<', '>', { - -- Avoid conflicts with nvim-ts-autotag. - '-html', - '-javascriptreact', - '-typescriptreact', - }):with_pair(conds.before_regex('%a+:?:?$', 3)):with_move(function(opts) - return opts.char == '>' - end)) - end, - }, - - -- auto tag - { - 'windwp/nvim-ts-autotag', - ft = { - 'html', - 'xml', - 'javascript', - 'typescript', - 'javascriptreact', - 'typescriptreact', - 'jsx', - 'tsx', - 'vue', - 'svelte', - 'markdown', - 'htmldjango', - }, - event = 'InsertEnter', - lazy = true, - opts = { - -- Defaults - enable_close = true, -- Auto close tags - enable_rename = true, -- Auto rename pairs of tags - enable_close_on_slash = false, -- Auto close on trailing cv', 'Markview toggle', desc = 'Toggle markdown preview', mode = 'n' }, - }, - }, - - -- Better folding - { - 'kevinhwang91/nvim-ufo', - dependencies = 'kevinhwang91/promise-async', - event = 'BufReadPost', - keys = { - { - 'zR', - function() - require('ufo').openAllFolds() - end, - }, - { - 'zM', - function() - require('ufo').closeAllFolds() - end, - }, - { - 'zr', - function() - require('ufo').openFoldsExceptKinds() - end, - }, - { - 'zm', - function() - require('ufo').closeFoldsWith() - end, - }, - }, - config = function() - vim.o.foldcolumn = '1' - vim.o.foldlevel = 99 - vim.o.foldlevelstart = 99 - vim.o.foldenable = true - - require('ufo').setup({ - provider_selector = function() - return { 'treesitter', 'indent' } - end, - }) - end, - }, - - -- smooth scrolling - { - 'karb94/neoscroll.nvim', - opts = {}, - }, - - -- Smart column (colorcolumn only when needed) - { - 'm4xshen/smartcolumn.nvim', - event = { 'BufReadPost', 'BufNewFile' }, - opts = { - colorcolumn = '120', - disabled_filetypes = { - 'help', - 'text', - 'markdown', - 'dashboard', - 'snacks_dashboard', - 'lazy', - 'mason', - 'oil', - }, - }, - }, - - -- Screenshot Tool - { - 'mistricky/codesnap.nvim', - build = 'make', - cmd = { - 'CodeSnap', - 'CodeSnapSave', - 'CodeSnapHighlight', - 'CodeSnapSaveHighlight', - 'CodeSnapASCII', - }, - opts = { - bg_theme = 'dusk', - code_font_family = 'JetBrainsMono Nerd Font', - save_path = os.getenv('XDG_SCREENSHOTS_DIR') or (os.getenv('HOME') .. '/Pictures'), - watermark = 'SANKALP', - watermark_font_family = 'Anurati', - has_breadcrumbs = true, - breadcrumbs_separator = '/', - has_line_number = true, - }, - }, -} diff --git a/lua/plugins/util.lua b/lua/plugins/util.lua deleted file mode 100644 index b0f2fa7..0000000 --- a/lua/plugins/util.lua +++ /dev/null @@ -1,108 +0,0 @@ -return { - - -- better escape - { - 'max397574/better-escape.nvim', - config = function() - require('better_escape').setup({ - mappings = { - -- i for insert, other modes are the first letter too - i = { - -- map kj to exit insert mode - k = { - j = '', - }, - -- map jk and jj to exit insert mode - j = { - k = '', - j = '', - }, - -- disable jj - j = { - j = false, - }, - }, - }, - }) - end, - }, - - -- float terminal - { - 'akinsho/toggleterm.nvim', - cmd = { 'ToggleTerm' }, - version = '*', - config = function() - require('toggleterm').setup({ - size = 10, - open_mapping = [[]], - hide_numbers = true, - shade_filetypes = {}, - shade_terminals = true, - shading_factor = '2', - start_in_insert = true, - insert_mappings = true, - terminal_mappings = true, - persist_size = true, - direction = 'float', -- 'vertical' | 'horizontal' | 'tab' | 'float' - close_on_exit = true, - shell = vim.o.shell, - float_opts = { - border = 'curved', -- 'single', 'double', 'shadow', etc. - winblend = 0, -- Set to 0 for full transparency - highlights = { - border = 'Normal', - background = 'Normal', - }, - }, - }) - end, - }, - - -- discord presence - -- { - -- "vyfor/cord.nvim", - -- event = "VeryLazy", - -- }, - - -- wakatime - { 'wakatime/vim-wakatime', event = 'VimEnter', lazy = false }, - - -- workflow - { - 'm4xshen/hardtime.nvim', - lazy = false, - opts = {}, - }, - - -- buffer manager - { - 'serhez/bento.nvim', - opts = {}, - -- config = function() - -- require('bento').setup({ - -- ordering_metric = 'edit', - -- ui = { - -- mode = 'floating', - -- floating = { - -- position = 'middle-right', - -- minimal_menu = 'full', - -- }, - -- }, - -- }) - -- end, - }, - - -- navigator - { - 'numToStr/Navigator.nvim', - event = 'VeryLazy', - config = function() - require('Navigator').setup({ - auto_save = 'current', - disable_on_zoom = false, - mux = 'auto', - }) - end, - }, -} diff --git a/lua/plugins/whichkey.lua b/lua/plugins/whichkey.lua deleted file mode 100644 index 7bb67fe..0000000 --- a/lua/plugins/whichkey.lua +++ /dev/null @@ -1,307 +0,0 @@ -return { - 'folke/which-key.nvim', - event = 'VeryLazy', - config = function() - local wk = require('which-key') - wk.setup({ - preset = 'helix', - plugins = { - marks = true, - registers = true, - spelling = { - enabled = true, - suggestions = 30, - }, - }, - presets = { - operators = true, - motions = true, - text_objects = true, - windows = true, - nav = true, - z = true, - g = true, - }, - icons = { - breadcrumb = ' ', - separator = ' ', - group = '', - keys = { - Space = ' ', - }, - rules = false, -- enable auto icon rules - }, - show_help = false, - show_keys = true, - triggers = { - { '', mode = 'nvisoct' }, - { '', mode = { 'n', 'v' } }, - }, - }) - - local normal_mappings = { - mode = 'n', - { 'x', ':x', desc = ' Save and Quit' }, - - -- { "a", group = " AI" }, - - { 'b', group = ' Buffer' }, - - { 'c', group = ' Code' }, - { 'cF', ':retab', desc = 'Fix Tabs' }, - { 'cd', ':RootDir', desc = 'Root Directory' }, - { 'cf', ':lua vim.lsp.buf.format({async = true})', desc = 'Format File' }, - { 'cg', ':Neogen', desc = 'Generate Docstring' }, - { 'cl', '::g/^\\s*$/d', desc = 'Clean Empty Lines' }, - { 'cm', ':MarkdownPreviewToggle', desc = 'Markdown Preview' }, - { 'cq', ':lua Snacks.picker.qflist()', desc = 'Quickfix List' }, - - { 'e', group = ' Edit' }, - { 'ea', ':b#', desc = 'Alternate File' }, - { 'eC', group = 'Edit Configs' }, - { - 'ee', - function() - local minifiles = require('mini.files') - minifiles.open(vim.api.nvim_buf_get_name(0), true) - minifiles.reveal_cwd() - end, - desc = 'Explore Tree', - }, - { 'eE', ':lua Snacks.explorer()', desc = 'File Explorer' }, - { 'ef', 'gf', desc = 'File Under Cursor' }, - { 'em', ':e README.md', desc = 'Readme' }, - { 'en', ':enew', desc = 'New File' }, - { 'er', ":lua require('snacks').rename.rename_file()", desc = 'Rename Current File' }, - - { 'f', group = ' Find' }, - { 'fx', ':%bd|e#|bd#', desc = 'Close except current' }, - { 'ff', ':lua Snacks.picker.files()', desc = 'Find Files' }, - { 'fg', ':lua Snacks.picker.grep()', desc = 'Live Grep' }, - { 'fp', ':lua Snacks.picker.projects()', desc = 'Projects' }, - { - 'ct', - function() - local curr_path = vim.fn.expand('%:p') - Snacks.picker.todo_comments({ - transform = function(item) - local item_path = vim.fn.fnamemodify(item.cwd .. '/' .. item.file, ':p') - return item_path == curr_path - end, - }) - end, - desc = 'Search Todos in Current File', - }, - { 'fT', ':lua Snacks.picker.todo_comments()', desc = 'Search Todos' }, - { 'fu', ':lua Snacks.picker.undo()', desc = 'Undotree' }, - - { 'g', group = ' Git' }, - { 'gA', ':Gitsigns stage_buffer', desc = 'Stage Buffer' }, - { 'gR', ':Gitsigns reset_buffer', desc = 'Reset Buffer' }, - { 'ga', ':Gitsigns stage_hunk', desc = 'Stage Hunk' }, - { 'gb', ":lua require('gitsigns').blame_line({full = true})", desc = 'Blame' }, - { 'gB', ":lua require('snacks').git.blame_line()", desc = 'Detailed Blame' }, - { 'gc', ':Gitignore', desc = 'Generate .gitignore' }, - { 'gd', ':Gitsigns diffthis HEAD', desc = 'Git Diff' }, - { 'gF', ':Git', desc = 'Fugitive Panel' }, - { 'gi', ':Gitsigns preview_hunk', desc = 'Hunk Info' }, - { 'gj', ':Gitsigns next_hunk', desc = 'Next Hunk' }, - { 'gk', ':Gitsigns prev_hunk', desc = 'Prev Hunk' }, - { 'gl', ':lua Snacks.picker.git_log()', desc = 'Checkout commit' }, - { 'gr', ':Gitsigns reset_hunk', desc = 'Reset Hunk' }, - { 'gs', ':lua Snacks.picker.git_status()', desc = 'Open changed file' }, - { 'gu', ':Gitsigns undo_stage_hunk', desc = 'Undo Stage Hunk' }, - { 'gv', ':Gitsigns select_hunk', desc = 'Select Hunk' }, - { 'gw', ':lua require("snacks").gitbrowse()', desc = 'Git Browse' }, - { 'gp', ':lua Snacks.picker.git_branches()', desc = 'Pick and Switch Git Branches' }, - - { 'gt', group = 'Toggle' }, - { 'gtb', ':Gitsigns toggle_current_line_blame', desc = 'Blame' }, - { 'gtd', ':Gitsigns toggle_deleted', desc = 'Deleted' }, - { 'gtl', ':Gitsigns toggle_linehl', desc = 'Line HL' }, - { 'gtn', ':Gitsigns toggle_numhl', desc = 'Number HL' }, - { 'gts', ':Gitsigns toggle_signs', desc = 'Signs' }, - { 'gtw', ':Gitsigns toggle_word_diff', desc = 'Word Diff' }, - - { 'i', group = ' Insert' }, - { 'id', ":put =strftime('## %a, %d %b, %Y, %r')", desc = 'Date' }, - { 'if', ":put =expand('%:t')", desc = 'File Name' }, - { 'ip', ':put %', desc = 'Relative Path' }, - { 'iP', ':put %:p', desc = 'Absolute Path' }, - { 'it', ":put =strftime('## %r')", desc = 'Time' }, - - { 'l', group = ' LSP' }, - { 'la', ':Lspsaga code_action', desc = 'Code Action' }, - { 'ld', ':Lspsaga goto_definition', desc = 'Goto Definition' }, - { 'lf', ':Lspsaga finder', desc = 'Finder' }, - { 'lh', ':Lspsaga hover_doc', desc = 'Hover' }, - { 'lI', ':LspInfo', desc = 'LSP Info' }, - { 'lj', ':Lspsaga diagnostic_jump_next', desc = 'Next Diagnostic' }, - { 'lk', ':Lspsaga diagnostic_jump_prev', desc = 'Prev Diagnostic' }, - { 'lo', ':Lspsaga outline', desc = 'Outline' }, - { 'lp', ':Lspsaga peek_definition', desc = 'Peek Definition' }, - { 'lq', ':LspStop', desc = 'Stop LSP' }, - { 'lQ', ':LspRestart', desc = 'Restart LSP' }, - { 'lr', ':Lspsaga rename', desc = 'Rename' }, - { 'lR', ':Lspsaga project_replace', desc = 'Replace' }, - { 'lt', ':Lspsaga goto_type_definition', desc = 'Goto Type Definition' }, - { 'lT', ':Lspsaga peek_type_definition', desc = 'Peek Type Definition' }, - - { 'o', group = ' Options' }, - { 'oi', 'vim.show_pos', desc = 'Inspect Position' }, - { 'oN', ':lua Snacks.notifier.show_history()', desc = 'Notification History' }, - { 'or', ':set relativenumber!', desc = 'Relative Numbers' }, - - { 'p', group = ' Packages' }, - { 'pc', ':Lazy check', desc = 'Check' }, - { 'pd', ':Lazy debug', desc = 'Debug' }, - { 'pe', ':lua require("snacks").profiler.scratch()', desc = 'Profiler Scratch' }, - { 'pf', ':lua require("snacks").profiler.pick()', desc = 'Profiler Pick' }, - { 'pi', ':Lazy install', desc = 'Install' }, - { 'pl', ':Lazy log', desc = 'Log' }, - { 'pm', ':Mason', desc = 'Mason' }, - { 'pp', ':Lazy', desc = 'Plugins' }, - { 'pP', ':Lazy profile', desc = 'Profile' }, - { 'pr', ':Lazy restore', desc = 'Restore' }, - { 'ps', ':Lazy sync', desc = 'Sync' }, - { 'pt', ':lua require("snacks").profiler.toggle()', desc = 'Profiler Toggle' }, - { 'pu', ':Lazy update', desc = 'Update' }, - { 'px', ':Lazy clean', desc = 'Clean' }, - - { 'q', group = ' Quit' }, - { 'qa', ':qall', desc = 'Quit All' }, - { 'qb', ':bw', desc = 'Close Buffer' }, - { 'qd', ':lua require("snacks").bufdelete()', desc = 'Delete Buffer' }, - { 'qf', ':qall!', desc = 'Force Quit' }, - { 'qo', ':%bdelete|b#|bdelete#', desc = 'Close Others' }, - { 'qq', ':q', desc = 'Quit' }, - { 'qs', 'c', desc = 'Close Split' }, - { 'qw', ':wq', desc = 'Write and Quit' }, - - { 'r', group = ' Refactor' }, - { 'rd', '', desc = 'Go To Definition' }, -- treesitter navigation - { 'rD', '', desc = 'List Definition' }, - { 'rh', '', desc = 'List Definition Head' }, - { 'rj', '', desc = 'Next Usage' }, - { 'rk', '', desc = 'Previous Usage' }, - { 'rn', '', desc = 'Swap Next' }, - { 'rp', '', desc = 'Swap Previous' }, - { 'rr', '', desc = 'Smart Rename' }, - { 'rs', ':%s/\\<\\>//gI', desc = 'Replace Word Buffer' }, - - { 's', group = ' Split' }, - { 's+', ':resize +10', desc = 'Increase window height' }, - { 's-', ':vertical resize -20', desc = 'Decrease window width' }, - { 's/', 's', desc = 'Split Below' }, - { 's=', ':vertical resize +20', desc = 'Increase window width' }, - { 'sH', ':vertical resize -10', desc = 'Decrease window width' }, - { 'sJ', ':resize -5', desc = 'Decrease window height' }, - { 'sK', ':resize +5', desc = 'Increase window height' }, - { 'sL', ':vertical resize +10', desc = 'Increase window width' }, - { 's\\', 'v', desc = 'Split Right' }, - { 's_', ':resize -10', desc = 'Decrease window height' }, - { 's`', 'p', desc = 'Previous Window' }, - { 'sa', ':split', desc = 'Horizontal Split' }, - { 'sc', ':tabclose', desc = 'Close Tab' }, - { 'sf', ':tabfirst', desc = 'First Tab' }, - { 'sh', 'h', desc = 'Move Left' }, - { 'sj', 'j', desc = 'Move Down' }, - { 'sk', 'k', desc = 'Move Up' }, - { 'sl', 'l', desc = 'Move Right' }, - { 'sq', 'c', desc = 'Close Split' }, - { 'ss', ':vsplit', desc = 'Vertical Split' }, - - { 't', group = ' Terminal' }, - { 't1', '1ToggleTerm', desc = 'Toggle Terminal' }, - { 't2', '2ToggleTerm', desc = 'Toggle Terminal' }, - { 'tc', 'close', desc = 'Hide Terminal' }, - { 'th', group = 'Inlay Hints' }, - - { 'w', group = ' Writing' }, - { 'wc', ':set spell!', desc = 'Spellcheck' }, - { 'wd', ':lua require("snacks").dim.enable()', desc = 'Dim On' }, - { 'wD', ':lua require("snacks").dim.disable()', desc = 'Dim Off' }, - { 'wf', ":lua require'utils'.sudo_write()", desc = 'Force Write' }, - { 'wj', ']s', desc = 'Next Misspell' }, - { 'wk', '[s', desc = 'Prev Misspell' }, - { 'wn', ':WriteNoFormat', desc = 'Write Without Formatting' }, - { 'wq', ':wq', desc = 'Write and Quit' }, - { 'ww', ':w', desc = 'Write' }, - { 'wz', ':lua require("snacks").zen.zen()', desc = 'Zen' }, - { 'wZ', ':lua require("snacks").zen.zoom()', desc = 'Zoom' }, - - { 'y', group = ' Yank' }, - { 'yL', ':CopyAbsolutePathWithLine', desc = 'Absolute Path with Line' }, - { 'yP', ':CopyAbsolutePath', desc = 'Absolute Path' }, - { 'ya', ':%y+', desc = 'Copy Whole File' }, - { 'yf', ':CopyFileName', desc = 'File Name' }, - { 'yg', ':lua require"gitlinker".get_buf_range_url()', desc = 'Copy Git URL' }, - { 'yl', ':CopyRelativePathWithLine', desc = 'Relative Path with Line' }, - { 'yp', ':CopyRelativePath', desc = 'Relative Path' }, - } - - local visual_mappings = { - mode = 'v', - -- { "a", group = " AI" }, - - { 'c', group = ' Code' }, - { 'cS', ':sort!', desc = 'Sort Desc' }, - { 'ci', ':sort i', desc = 'Sort Case Insensitive' }, - { 'cs', ':sort', desc = 'Sort Asc' }, - { 'cu', ':!uniq', desc = 'Unique' }, - { 'cx', ':lua', desc = 'Execute Lua' }, - - { 'g', group = ' Git' }, - { 'ga', ":'<,'>Gitsigns stage_hunk", desc = 'Stage Hunk' }, - { 'gr', ":'<,'>Gitsigns reset_hunk", desc = 'Reset Hunk' }, - { 'gu', ":'<,'>Gitsigns undo_stage_hunk", desc = 'Undo Stage Hunk' }, - - { 'l', group = ' LSP' }, - { 'la', ':Lspsaga range_code_action', desc = 'Code Action' }, - - { 'o', group = ' Options' }, - { 'oc', ':CodeSnap', desc = 'CodeSnap into clipboard' }, - { 'oC', ':CodeSnapSave', desc = 'CodeSnap in ~/Pictures' }, - - { 'y', group = ' Yank' }, - { 'yg', ':lua require"gitlinker".get_buf_range_url("v")', desc = 'Copy Git URL' }, - } - - local no_leader_mappings = { - mode = 'n', - { '', ':resize -10', desc = 'Decrease window height' }, - { '', ':vertical resize -10', desc = 'Decrease window width' }, - { '', ':vertical resize +10', desc = 'Increase window width' }, - { '', ':resize +10', desc = 'Increase window height' }, - - { '', ':NavigatorLeft', desc = 'Move Left' }, - { '', ':NavigatorDown', desc = 'Move Down' }, - { '', ':NavigatorUp', desc = 'Move Up' }, - { '', ':NavigatorRight', desc = 'Move Right' }, - { '', ':NavigatorPrevious', desc = 'Previous Pane' }, - - -- { '', ':bprevious', desc = 'Previous Buffer' }, - -- { '', ':bnext', desc = 'Next Buffer' }, - { '', ':bnext', desc = 'Next Buffer' }, - { '', ':bprevious', desc = 'Previous Buffer' }, - - { 'K', ':Lspsaga hover_doc', desc = 'LSP Hover' }, - { 'Q', ':qall!', desc = 'Force Quit!' }, - { 'U', ':redo', desc = 'Redo' }, - - { '[', group = ' Previous' }, - { '[g', ':Gitsigns prev_hunk', desc = 'Git Hunk' }, - { '[o', group = 'Textobjects' }, - - { ']', group = ' Next' }, - { ']g', ':Gitsigns next_hunk', desc = 'Git Hunk' }, - { ']o', group = 'Textobjects' }, - - { 'gd', ':Lspsaga goto_definition', desc = 'Goto Definition' }, - } - - wk.add(normal_mappings) - wk.add(visual_mappings) - wk.add(no_leader_mappings) - end, -} diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json new file mode 100644 index 0000000..90d74cd --- /dev/null +++ b/nvim-pack-lock.json @@ -0,0 +1,184 @@ +{ + "plugins": { + "Comment.nvim": { + "rev": "e30b7f2008e52442154b66f7c519bfd2f1e32acb", + "src": "https://github.com/numToStr/Comment.nvim" + }, + "Lspsaga.nvim": { + "rev": "e6c04f88836d79f2fd7e46fd170e7ee986c789d4", + "src": "https://github.com/nvimdev/Lspsaga.nvim" + }, + "LuaSnip": { + "rev": "a62e1083a3cfe8b6b206e7d3d33a51091df25357", + "src": "https://github.com/L3MON4D3/LuaSnip" + }, + "Navigator.nvim": { + "rev": "91d86506ac2a039504d5205d32a1d4bc7aa57072", + "src": "https://github.com/numToStr/Navigator.nvim" + }, + "bento.nvim": { + "rev": "aee8a542bc1839ff1764992ef2aa41c981d0bba4", + "src": "https://github.com/serhez/bento.nvim" + }, + "better-escape.nvim": { + "rev": "3f4bc0b326606264ff75967f59091b5ddada0554", + "src": "https://github.com/max397574/better-escape.nvim" + }, + "blink.cmp": { + "rev": "d3874d2a13aa19b095bdd10d37a82a8f0aa7cad3", + "src": "https://github.com/saghen/blink.cmp", + "version": "'v0.*'" + }, + "blink.lib": { + "rev": "f29d8bac6549bc1e7d699c83f680823d7def98bd", + "src": "https://github.com/saghen/blink.lib" + }, + "conform.nvim": { + "rev": "dca1a190aa85f9065979ef35802fb77131911106", + "src": "https://github.com/stevearc/conform.nvim" + }, + "friendly-snippets": { + "rev": "6cd7280adead7f586db6fccbd15d2cac7e2188b9", + "src": "https://github.com/rafamadriz/friendly-snippets" + }, + "gitignore": { + "rev": "0344f643768c4d64af4add8c1bdddf6f7d4c9010", + "src": "https://github.com/wintermute-cell/gitignore.nvim" + }, + "gitignore.nvim": { + "rev": "0344f643768c4d64af4add8c1bdddf6f7d4c9010", + "src": "https://github.com/wintermute-cell/gitignore.nvim" + }, + "gitsigns.nvim": { + "rev": "dd3f588bacbeb041be6facf1742e42097f62165d", + "src": "https://github.com/lewis6991/gitsigns.nvim" + }, + "gruvbox.nvim": { + "rev": "154eb5ff5b96d0641307113fa385eaf0d36d9796", + "src": "https://github.com/ellisonleao/gruvbox.nvim" + }, + "guess-indent.nvim": { + "rev": "84a4987ff36798c2fc1169cbaff67960aed9776f", + "src": "https://github.com/NMAC427/guess-indent.nvim" + }, + "hardtime.nvim": { + "rev": "b4e431934af1fe224a3a801f632c008278cb7628", + "src": "https://github.com/m4xshen/hardtime.nvim" + }, + "indent-blankline.nvim": { + "rev": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03", + "src": "https://github.com/lukas-reineke/indent-blankline.nvim" + }, + "markview.nvim": { + "rev": "dbf74b6db11c1468d5128a38b26b6d99dc7316e9", + "src": "https://github.com/OXY2DEV/markview.nvim" + }, + "mason-conform.nvim": { + "rev": "48da2ebd5efbaf8a99566eadc3ece82d523f03c5", + "src": "https://github.com/zapling/mason-conform.nvim" + }, + "mason-lspconfig.nvim": { + "rev": "1423254f58a3407a5afd5ade0ccd901f3eecc6ba", + "src": "https://github.com/mason-org/mason-lspconfig.nvim", + "version": "'main'" + }, + "mason-nvim-lint": { + "rev": "cafbc5d82d8eb4af0daf0057332a325ddf2f436b", + "src": "https://github.com/rshkarin/mason-nvim-lint" + }, + "mason.nvim": { + "rev": "cb8445f8ce85d957416c106b780efd51c6298f89", + "src": "https://github.com/mason-org/mason.nvim", + "version": "'main'" + }, + "mdx.nvim": { + "rev": "6c3dc7c4a4b58b5d86404c21a9b4655282ca08c5", + "src": "https://github.com/davidmh/mdx.nvim" + }, + "mini.nvim": { + "rev": "48555f1615f08c6318150aacb52bf7d61a5af798", + "src": "https://github.com/nvim-mini/mini.nvim" + }, + "neodim": { + "rev": "1b8bda59a53b49ec2b59885e9fe78f8e90a1de76", + "src": "https://github.com/zbirenbaum/neodim" + }, + "neoscroll.nvim": { + "rev": "c8d29979cb0cb3a2437a8e0ae683fd82f340d3b8", + "src": "https://github.com/karb94/neoscroll.nvim" + }, + "nvim-autopairs": { + "rev": "59bce2eef357189c3305e25bc6dd2d138c1683f5", + "src": "https://github.com/windwp/nvim-autopairs" + }, + "nvim-highlight-colors": { + "rev": "e4c7af0211866162d999ce0bdd6a029302e19139", + "src": "https://github.com/brenoprata10/nvim-highlight-colors" + }, + "nvim-lint": { + "rev": "eab58b48eb11d7745c11c505e0f3057165902461", + "src": "https://github.com/mfussenegger/nvim-lint" + }, + "nvim-lspconfig": { + "rev": "cd576dd72d31ddffcbfa6d064c0dd697ca218758", + "src": "https://github.com/neovim/nvim-lspconfig" + }, + "nvim-treesitter": { + "rev": "4916d6592ede8c07973490d9322f187e07dfefac", + "src": "https://github.com/nvim-treesitter/nvim-treesitter" + }, + "nvim-ts-autotag": { + "rev": "88c1453db4ba7dd24131086fe51fdf74e587d275", + "src": "https://github.com/windwp/nvim-ts-autotag" + }, + "smartcolumn.nvim": { + "rev": "b9cdbdf42f7ac5a659204cd5926017c7ff724a19", + "src": "https://github.com/m4xshen/smartcolumn.nvim" + }, + "snacks.nvim": { + "rev": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e", + "src": "https://github.com/folke/snacks.nvim" + }, + "suda.vim": { + "rev": "c492741b4679b3cdd4d9e34138209784e061d916", + "src": "https://github.com/lambdalisue/suda.vim" + }, + "tiny-code-action.nvim": { + "rev": "0d040ed81f7953118b81cd12681fcdfcac069803", + "src": "https://github.com/rachartier/tiny-code-action.nvim" + }, + "tiny-glimmer.nvim": { + "rev": "cc285167914e947fc130523d02927fdaf24636a6", + "src": "https://github.com/rachartier/tiny-glimmer.nvim" + }, + "tiny-inline-diagnostic.nvim": { + "rev": "147af4e49f51dd48f41972de26552872b8ba7b25", + "src": "https://github.com/rachartier/tiny-inline-diagnostic.nvim" + }, + "todo-comments.nvim": { + "rev": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668", + "src": "https://github.com/folke/todo-comments.nvim" + }, + "toggleterm.nvim": { + "rev": "9a88eae817ef395952e08650b3283726786fb5fb", + "src": "https://github.com/akinsho/toggleterm.nvim", + "version": "'*'" + }, + "vim-visual-multi": { + "rev": "a6975e7c1ee157615bbc80fc25e4392f71c344d4", + "src": "https://github.com/mg979/vim-visual-multi" + }, + "vim-wakatime": { + "rev": "24495fb7cc9613eaf0ce45540fb8d096a30d08e9", + "src": "https://github.com/wakatime/vim-wakatime" + }, + "which-key.nvim": { + "rev": "3aab2147e74890957785941f0c1ad87d0a44c15a", + "src": "https://github.com/folke/which-key.nvim" + }, + "windsurf.vim": { + "rev": "3c0a4f8a7be75113a6e19be13b7cc37210d6e26a", + "src": "https://github.com/Exafunction/windsurf.vim" + } + } +} diff --git a/plugin/00-colorscheme.lua b/plugin/00-colorscheme.lua new file mode 100644 index 0000000..ce5a106 --- /dev/null +++ b/plugin/00-colorscheme.lua @@ -0,0 +1,34 @@ +add("ellisonleao/gruvbox.nvim") + +local palette = require("gruvbox").palette +require("gruvbox").setup({ + bold = false, + italic = { + strings = false, + emphasis = false, + comments = false, + folds = false, + }, + contrast = "hard", + transparent_mode = true, + overrides = { + -- builtin + SignColumn = { bg = "None" }, + CursorLineNr = { bg = "None" }, + Whitespace = { fg = palette.dark0 }, + EndOfBuffer = { fg = palette.dark0_hard }, + Visual = { fg = "None", bg = palette.dark1 }, + Label = { link = "GruvboxPurple" }, + + -- blink.cmp + BlinkCmpMenu = { link = "Normal" }, + BlinkCmpMenuBorder = { link = "BlinkCmpMenu" }, + BlinkCmpMenuSelection = { fg = "None", bg = palette.dark1 }, + BlinkCmpLabelMatch = { fg = palette.bright_green }, + BlinkCmpScrollBarGutter = { bg = palette.dark2 }, + BlinkCmpScrollBarThumb = { bg = palette.light1 }, + + -- indent guides + MiniIndentscopeSymbol = { fg = palette.dark1 }, + }, +}) diff --git a/plugin/01-lsp.lua b/plugin/01-lsp.lua new file mode 100644 index 0000000..470c893 --- /dev/null +++ b/plugin/01-lsp.lua @@ -0,0 +1,74 @@ +add({ + { src = "mason-org/mason.nvim", version = "main" }, -- lsp installer manager + { src = "mason-org/mason-lspconfig.nvim", version = "main" }, -- lsp installer + "neovim/nvim-lspconfig", -- lsp config + "nvimdev/Lspsaga.nvim", -- lsp ui + "rachartier/tiny-inline-diagnostic.nvim", -- inline diagnostic + "rachartier/tiny-code-action.nvim", -- code action +}) + +-- lsp installer +require("mason").setup({ + ui = { + icons = { + package_installed = "✓", + package_pending = "➜", + package_uninstalled = "✗", + }, + border = "rounded", + backdrop = 100, + }, +}) + +require("mason-lspconfig").setup({ + ensure_installed = require("extensions").lsp_server, + automatic_installation = false, -- Don't auto-install or auto-configure +}) + +-- improve neovim lsp experience +vim.api.nvim_create_autocmd("LspAttach", { + callback = function() + require("lspsaga").setup({ + ui = { + theme = "round", + border = "rounded", + devicon = true, + title = true, + winblend = 1, + expand = " ", + collapse = " ", + preview = "", + code_action = "󰠠 ", + diagnostic = " ", + incoming = " ", + outgoing = " ", + hover = " ", + }, + }) + + --inline diagnostic + require("tiny-inline-diagnostic").setup({ + options = { + show_source = true, + multiple_diag_under_cursor = true, + }, + }) + + --code action + require("tiny-code-action").setup({ + picker = { + "buffer", + opts = { + auto_preview = true, + hotkeys = true, + hotkeys_mode = "sequential", + }, + }, + }) + end, +}) + +vim.diagnostic.config({ virtual_text = false }) -- Disable default virtual text +vim.keymap.set("n", ".", function() + require("tiny-code-action").code_action() +end, { desc = "Code action" }) diff --git a/plugin/code_quality.lua b/plugin/code_quality.lua new file mode 100644 index 0000000..5804022 --- /dev/null +++ b/plugin/code_quality.lua @@ -0,0 +1,82 @@ +add({ + "mfussenegger/nvim-lint", -- linter + "rshkarin/mason-nvim-lint", -- linter installer + "stevearc/conform.nvim", -- autoformater + "zapling/mason-conform.nvim", -- formatter installer +}) + +-- linter +require("lint").linters_by_ft = { + ["*"] = { "codespell" }, + ["javascript"] = { "eslint_d", "cspell" }, + ["typescript"] = { "eslint_d", "cspell" }, + ["javascriptreact"] = { "eslint_d", "cspell" }, + ["typescriptreact"] = { "eslint_d", "cspell" }, + ["dockerfile"] = { "hadolint" }, + ["markdown"] = { "write_good", "markdownlint" }, + ["text"] = { "write_good" }, + ["sh"] = { "shellcheck" }, + ["yaml"] = { "actionlint" }, + ["python"] = { "ruff" }, +} +require("mason-nvim-lint").setup({ + ensure_installed = require("extensions").linter, + automatic_installation = false, +}) + +-- formatter +require("conform").setup({ + formatters = { + ["markdown-toc"] = { + condition = function(_, ctx) + for _, line in ipairs(vim.api.nvim_buf_get_lines(ctx.buf, 0, -1, false)) do + if line:find("") then + return true + end + end + end, + }, + ["markdownlint-cli2"] = { + condition = function(_, ctx) + local diag = vim.tbl_filter(function(d) + return d.source == "markdownlint" + end, vim.diagnostic.get(ctx.buf)) + return #diag > 0 + end, + }, + }, + formatters_by_ft = { + ["lua"] = { "stylua" }, + ["c"] = { "clang_format" }, + ["cpp"] = { "clang_format" }, + ["h"] = { "clang_format" }, + ["python"] = { "ruff_fix", "ruff_format", "ruff_organize_imports" }, + ["javascript"] = { "biome" }, + ["typescript"] = { "biome" }, + ["typescriptreact"] = { "biome" }, + ["markdown"] = { "prettier", "markdownlint-cli2", "markdown-toc" }, + ["markdown.mdx"] = { "prettier", "markdownlint-cli2", "markdown-toc" }, + ["mdx"] = { "prettier" }, + ["_"] = { "trim_whitespace" }, + }, + options = { + stop_after_first = true, + }, + format_after_save = function(bufnr) + if not vim.b[bufnr].conform_disable then + return { + lsp_format = "fallback", + } + end + end, +}) + +vim.keymap.set("n", "tf", function() + vim.b.conform_disable = not vim.b.conform_disable + local status = vim.b.conform_disable and "disabled" or "enabled" + vim.notify("Autoformat " .. status, vim.log.levels.INFO) +end, { desc = "Toggle autoformat" }) +require("mason-conform").setup({ + ensure_installed = require("extensions").formatter, + automatic_installation = true, +}) diff --git a/plugin/completion.lua b/plugin/completion.lua new file mode 100644 index 0000000..c18c6ee --- /dev/null +++ b/plugin/completion.lua @@ -0,0 +1,75 @@ +add({ + "saghen/blink.lib", + { src = "saghen/blink.cmp", version = "v0.*" }, + "L3MON4D3/LuaSnip", + "rafamadriz/friendly-snippets", +}) + +require("blink.cmp").setup({ + fuzzy = { implementation = "prefer_rust" }, + snippets = { preset = "luasnip" }, + sources = { + default = { "lsp", "path", "snippets", "buffer" }, + providers = {}, + }, + + completion = { + ghost_text = { enabled = true }, + + list = { + selection = { + preselect = false, + auto_insert = true, + }, + }, + documentation = { + window = { border = "rounded" }, + auto_show = true, + auto_show_delay_ms = 50, + }, + menu = { + border = "rounded", + draw = { + components = { + kind_icon = { + text = function(ctx) + local kind_icon, _, _ = require("mini.icons").get("lsp", ctx.kind) + return kind_icon + end, + highlight = function(ctx) + local _, hl, _ = require("mini.icons").get("lsp", ctx.kind) + return hl + end, + }, + kind = { + highlight = function(ctx) + local _, hl, _ = require("mini.icons").get("lsp", ctx.kind) + return hl + end, + }, + }, + }, + }, + }, + signature = { + window = { border = "rounded" }, + }, + keymap = { + preset = "none", + [""] = { "select_prev", "snippet_backward", "fallback" }, + [""] = { "select_next", "snippet_forward", "fallback" }, + [""] = { "accept", "fallback" }, + [""] = { "hide", "show" }, + [""] = { "show", "show_documentation", "hide_documentation" }, + [""] = { "scroll_documentation_up", "fallback" }, + [""] = { "scroll_documentation_down", "fallback" }, + }, +}) + +local luasnip = require("luasnip") +require("luasnip.loaders.from_vscode").lazy_load() +require("luasnip.loaders.from_vscode").lazy_load({ + paths = { vim.fn.stdpath("config") .. "/snippets" }, +}) + +luasnip.filetype_extend("mdx", { "markdown" }) diff --git a/plugin/editor.lua b/plugin/editor.lua new file mode 100644 index 0000000..7f5783f --- /dev/null +++ b/plugin/editor.lua @@ -0,0 +1,72 @@ +add({ + "windwp/nvim-autopairs", -- autopairs + "windwp/nvim-ts-autotag", -- autotag + "folke/todo-comments.nvim", -- todo comment highlights + "wakatime/vim-wakatime", --wakaTime coding time tracker + "lambdalisue/suda.vim", -- edit files as sudo (:SudaWrite) + "numToStr/Comment.nvim", -- smart comment toggling + "NMAC427/guess-indent.nvim", -- auto-detect tab/space indentation + "brenoprata10/nvim-highlight-colors", -- color highlighting + "davidmh/mdx.nvim", -- syntax highlighter for mdx + "nvim-treesitter/nvim-treesitter", -- nvim-treesitter + "Exafunction/windsurf.vim", -- windsurf ai for autocompletion + "numToStr/Navigator.nvim", -- navigator + "m4xshen/hardtime.nvim", -- workflow + "lukas-reineke/indent-blankline.nvim", --indent guides + "mg979/vim-visual-multi", -- multiple cursors +}) + +vim.g.VM_maps = { + ["Find Under"] = "", -- Alt + d | Select word under cursor and start multi-cursor + ["Find Subword Under"] = "", -- Alt + d | Select subword under cursor + ["Select All"] = "", -- Ctrl + Alt + d | Select all occurrences in the buffer + ["Add Cursor Down"] = "", -- Ctrl + Alt + j | Add a cursor on the line below + ["Add Cursor Up"] = "", -- Ctrl + Alt + k | Add a cursor on the line above +} + +-- lazy load insert mode enhancements +vim.api.nvim_create_autocmd("InsertEnter", { + callback = function() + require("nvim-autopairs").setup({}) + require("nvim-ts-autotag").setup({}) + end, + once = true, +}) + +-- lazy load general editor enhancements +vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile" }, { + callback = function() + require("todo-comments").setup({ signs = false }) + require("Comment").setup() + require("guess-indent").setup({}) + require("nvim-highlight-colors").setup({ render = "background" }) + require("Navigator").setup({ + auto_save = "current", + disable_on_zoom = false, + mux = "auto", + }) + end, +}) + +require("hardtime").setup({}) +require("ibl").setup({}) + +require("nvim-treesitter").setup({ + ensure_installed = require("extensions").ts_parsers, + auto_install = true, + highlight = { + enable = true, + additional_vim_regex_highlighting = true, + }, + indent = { + enable = true, + }, +}) + +-- windsurf +vim.keymap.set("i", "", function() + return vim.fn["codeium#Accept"]() +end, { expr = true, silent = true }) +vim.keymap.set("i", "", function() + return vim.fn["codeium#Clear"]() +end, { expr = true, silent = true }) diff --git a/plugin/git.lua b/plugin/git.lua new file mode 100644 index 0000000..74cdca3 --- /dev/null +++ b/plugin/git.lua @@ -0,0 +1,34 @@ +add({ + "lewis6991/gitsigns.nvim", + "wintermute-cell/gitignore.nvim", -- .gitignore generator +}) + +vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, { + callback = function() + require("gitsigns").setup({ + signcolumn = true, + current_line_blame = true, + attach_to_untracked = false, + current_line_blame_formatter = ", - ", + watch_gitdir = { + follow_files = true, + }, + current_line_blame_opts = { + virt_text = true, + virt_text_pos = "eol", -- 'eol' | 'overlay' | 'right_align' + delay = 1000, + ignore_whitespace = false, + virt_text_priority = 100, + use_focus = true, + }, + signs = { + add = { text = " " }, + change = { text = "󱗜 " }, + delete = { text = "󰍵 " }, + topdelete = { text = "󱥨 " }, + changedelete = { text = "󰾟 " }, + untracked = { text = "󰰧 " }, + }, + }) + end, +}) diff --git a/plugin/mini.lua b/plugin/mini.lua new file mode 100644 index 0000000..23d603c --- /dev/null +++ b/plugin/mini.lua @@ -0,0 +1,153 @@ +add("echasnovski/mini.nvim") + +require("mini.ai").setup() -- extend and create a/i textobjects +require("mini.pairs").setup() -- autopairs +require("mini.icons").setup() -- icons +require("mini.bracketed").setup() -- go forward/backward with square brackets + +-- File explorer +require("mini.files").setup({ + mappings = { + close = "q", + go_in = "L", + go_in_plus = "l", + go_out = "h", + go_out_plus = "H", + mark_goto = "'", + mark_set = "m", + reset = "", + reveal_cwd = "@", + show_help = "g?", + synchronize = "", + trim_left = "<", + trim_right = ">", + }, +}) + +require("mini.misc").setup({ + -- restore cursor position on file reopen + require("mini.misc").setup_restore_cursor(), + -- automated change of current directory + require("mini.misc").setup_auto_root(), +}) + +-- splitjoin +require("mini.splitjoin").setup({ + mappings = { + toggle = "tj", + split = "", + join = "", + }, +}) + +-- surround action +require("mini.surround").setup({ + mappings = { + add = "msa", + delete = "msd", + find = "msf", + find_left = "msF", + highlight = "msh", + replace = "msr", + update_n_lines = "msn", + + suffix_last = "l", + suffix_next = "n", + }, +}) + +-- indents +require("mini.indentscope").setup({ + draw = { animation = require("mini.indentscope").gen_animation.linear({ ease = "out", duration = 15 }) }, + options = { border = "top", try_as_border = true, indent_at_cursor = false }, +}) + +vim.api.nvim_create_autocmd("BufEnter", { + pattern = "*", + callback = function(args) + if vim.bo[args.buf].buftype ~= "" then + vim.b[args.buf].miniindentscope_disable = true + end + end, +}) + +-- statusline +require("mini.statusline").setup({ + use_icons = true, + content = { + active = function() + local mode, mode_hl = MiniStatusline.section_mode({ trunc_width = 120 }) + local git = MiniStatusline.section_git({ trunc_width = 40 }) + local diff = MiniStatusline.section_diff({ trunc_width = 80 }) + local diagnostics = MiniStatusline.section_diagnostics({ trunc_width = 60 }) + local lsp = MiniStatusline.section_lsp({ trunc_width = 40 }) + local filename = MiniStatusline.section_filename({ trunc_width = 140 }) + + local function section_filetype(args) + if MiniStatusline.is_truncated(args.trunc_width) or vim.bo.filetype == "" or vim.bo.buftype ~= "" then + return "" + end + local ok, icons = pcall(require, "mini.icons") + local icon = ok and select(1, icons.get("filetype", vim.bo.filetype)) or "" + return string.format("%s %s│", icon, vim.bo.filetype) + end + + local function section_lsp_clients(args) + if MiniStatusline.is_truncated(args.trunc_width) then + return "" + end + local clients = vim.lsp.get_clients({ bufnr = 0 }) + if not clients or #clients == 0 then + return "" + end + local names = vim.tbl_map(function(c) + return c.name + end, clients) + return string.format(" %s", table.concat(names, ", ")) + end + + local function section_searchcount(args) + if vim.v.hlsearch == 0 then + return "" + end + local ok, s = pcall(vim.fn.searchcount, { recompute = true }) + if not ok or s.current == nil or s.total == 0 then + return "" + end + local icon = MiniStatusline.is_truncated(args.trunc_width) and "" or " " + if s.incomplete == 1 then + return icon .. "?/?│" + end + local fmt = ">%d" + local cur = s.current > s.maxcount and fmt:format(s.maxcount) or s.current + local tot = s.total > s.maxcount and fmt:format(s.maxcount) or s.total + return ("%s%s/%s│"):format(icon, cur, tot) + end + + local function section_location(args) + return MiniStatusline.is_truncated(args.trunc_width) and "%-2l│%-2v" or "󰉸 %-2l│󱥖 %-2v" + end + + local filetype = section_filetype({ trunc_width = 70 }) + local searchcount = section_searchcount({ trunc_width = 80 }) + local loc = section_location({ trunc_width = 120 }) + local lsp_clients = section_lsp_clients({ trunc_width = 60 }) + + return MiniStatusline.combine_groups({ + { hl = mode_hl, strings = { mode:upper() } }, + { hl = "MiniStatuslineDevinfo", strings = { git, diff, diagnostics, lsp } }, + "%<", + { hl = "MiniStatuslineFilename", strings = { filename } }, + "%=", + { hl = "MiniStatuslineDevinfo", strings = { lsp_clients } }, + { hl = mode_hl, strings = { filetype, searchcount, loc } }, + }) + end, + + inactive = function() + return MiniStatusline.combine_groups({ + { hl = "MiniStatuslineInactive", strings = { vim.fn.expand("%:t") } }, + }) + end, + }, +}) diff --git a/plugin/snacks.lua b/plugin/snacks.lua new file mode 100644 index 0000000..060928c --- /dev/null +++ b/plugin/snacks.lua @@ -0,0 +1,367 @@ +add("folke/snacks.nvim") + +local function files_layout(preview_width, height, width) + preview_width = preview_width or 0.6 + height = height or 0.8 + width = width or 0.9 + return { + layout = { + box = "horizontal", + width = width, + min_width = 120, + height = height, + { + box = "vertical", + border = "rounded", + title = "{title} {live} {flags}", + { win = "input", height = 1, border = "bottom" }, + { win = "list", border = "none" }, + }, + { win = "preview", title = "{preview}", border = "rounded", width = preview_width }, + }, + } +end + +local function palette_layout(height, width) + height = height or 0.4 + width = width or 0.6 + return { + preview = false, + layout = { + backdrop = false, + row = 1, + width = width, + min_width = 80, + height = height, + border = "rounded", + box = "vertical", + { + win = "input", + height = 1, + border = "rounded", + title = "{title} {live} {flags}", + title_pos = "center", + }, + { win = "list", border = "hpad" }, + { win = "preview", title = "{preview}", border = "rounded" }, + }, + } +end + +local Snacks = require("snacks") +Snacks.setup({ + animate = { + enabled = true, + duration = 20, -- ms per step + easing = "linear", + fps = 60, + }, + bigfile = { + enabled = true, + notify = true, + size = 1000 * 1024, -- 1 MB instead of 100 KB + }, + bufdelete = { enabled = true }, + dashboard = { + preset = { + header = [[ +░█░█░█▀▀░█░█░█▀▀░█▀█░█▀▄░█▀▀░█░█ +░█▀▄░█▀▀░░█░░█░░░█░█░█░█░█▀▀░▄▀▄ +░▀░▀░▀▀▀░░▀░░▀▀▀░▀▀▀░▀▀░░▀▀▀░▀░▀ + ]], + }, + sections = { + { section = "header" }, + { + icon = " ", + title = "Keymaps", + section = "keys", + indent = 2, + padding = 1, + }, + { + icon = " ", + title = "Recent Files", + section = "recent_files", + indent = 2, + padding = 1, + }, + { + icon = " ", + title = "Projects", + section = "projects", + indent = 2, + padding = 1, + }, + + }, + }, + debug = { enabled = true }, + dim = { + enabled = true, + scope = { + min_size = 5, + max_size = 20, + siblings = true, + }, + }, + explorer = { enabled = false }, + projects = { + dirs = { + "~/Project", + "~/.config/Modus" + } + }, + git = { enabled = true }, + gitbrowse = { enabled = true }, + image = { enabled = true }, + indent = { + enabled = true, + priority = 1, + char = "▍", + only_scope = false, + only_current = false, + hl = { + "SnacksIndent1", + "SnacksIndent2", + "SnacksIndent3", + "SnacksIndent4", + "SnacksIndent5", + "SnacksIndent6", + "SnacksIndent7", + "SnacksIndent8", + }, + }, + input = { + enabled = true, + icon = " ", + icon_hl = "SnacksInputIcon", + icon_pos = "left", + prompt_pos = "title", + win = { style = "input" }, + expand = true, + }, + layout = { enabled = true }, + lazygit = { enabled = true }, + notifier = { + enabled = true, + timeout = 2000, + width = { min = 40, max = 0.4 }, + height = { min = 1, max = 0.6 }, + margin = { top = 0, right = 1, bottom = 0 }, + padding = true, + sort = { "level", "added" }, + level = vim.log.levels.TRACE, + icons = { + debug = " ", + error = " ", + info = " ", + trace = " ", + warn = " ", + }, + style = "compact", + top_down = true, + date_format = "%R", + more_format = " ↓ %d lines ", + refresh = 50, + }, + notify = { enabled = true }, + picker = { + enabled = true, + icon = " ", + icon_hl = "SnacksPickerIcon", + icon_pos = "left", + prompt_pos = "title", + win = { style = "picker" }, + expand = true, + matchers = { + frecency = true, + cwd_bonus = false, + }, + sources = { + -- layout options: dropdown, horizontal, vertical, vscode, ivy, ivy_split, telescope, top, left, right, bottom, sidebar + buffers = { layout = files_layout() }, + commands = { layout = palette_layout() }, + command_history = { layout = palette_layout() }, + files = { + hidden = true, + layout = files_layout(), + }, + icons = { + icon_sources = { "nerd_fonts", "emoji" }, + layout = palette_layout(), + }, + git_files = { layout = files_layout() }, + git_branches = { layout = { preset = "vertical" } }, + git_status = { layout = files_layout() }, + help = { layout = { preset = "ivy_split" } }, + man = { layout = { preset = "ivy_split" } }, + notifications = { layout = palette_layout() }, + projects = { layout = files_layout(0.8) }, + recent = { layout = files_layout() }, + search_history = { layout = palette_layout() }, + smart = { layout = files_layout() }, + undo = { layout = { preset = "ivy" } }, + zoxide = { layout = files_layout(0.7) }, + }, + layout = "custom", + layouts = { + custom = { + layout = { + box = "vertical", + backdrop = false, + row = -1, + width = 0, + height = 0.4, + border = "top", + title = " {title} {live} {flags}", + title_pos = "left", + { + box = "horizontal", + { win = "list", border = "rounded" }, + { win = "preview", title = "{preview}", width = 0.6, border = "left" }, + }, + { win = "input", height = 1, border = "top" }, + }, + }, + }, + }, + profiler = { enabled = true }, + quickfile = { enabled = true }, + rename = { enabled = true }, + scope = { + enabled = true, + keys = { + textobject = { + ii = { + min_size = 2, -- minimum size of the scope + edge = false, -- inner scope + cursor = false, + treesitter = { blocks = { enabled = false } }, + desc = "inner scope", + }, + ai = { + cursor = false, + min_size = 2, -- minimum size of the scope + treesitter = { blocks = { enabled = false } }, + desc = "full scope", + }, + }, + jump = { + ["[a"] = { + min_size = 1, -- allow single line scopes + bottom = false, + cursor = false, + edge = true, + treesitter = { blocks = { enabled = false } }, + desc = "jump to top edge of scope", + }, + ["]a"] = { + min_size = 1, -- allow single line scopes + bottom = true, + cursor = false, + edge = true, + treesitter = { blocks = { enabled = false } }, + desc = "jump to bottom edge of scope", + }, + }, + }, + }, + scratch = { + enabled = true, + name = "SCRATCH", + ft = function() + if vim.bo.buftype == "" and vim.bo.filetype ~= "" then + return vim.bo.filetype + end + return "markdown" + end, + icon = nil, + root = vim.fn.stdpath("data") .. "/scratch", + autowrite = true, + filekey = { + cwd = true, + branch = true, + count = true, + }, + win = { + width = 120, + height = 40, + bo = { buftype = "", buflisted = false, bufhidden = "hide", swapfile = false }, + minimal = false, + noautocmd = false, + zindex = 20, + wo = { winhighlight = "NormalFloat:Normal" }, + border = "rounded", + title_pos = "center", + footer_pos = "center", + + keys = { + ["execute"] = { + "", + function(_) + vim.cmd("%SnipRun") + end, + desc = "Execute buffer", + mode = { "n", "x" }, + }, + }, + }, + win_by_ft = { + lua = { + keys = { + ["source"] = { + "cr", + function(self) + local name = "scratch." .. vim.fn.fnamemodify(vim.api.nvim_buf_get_name(self.buf), ":e") + Snacks.debug.run({ buf = self.buf, name = name }) + end, + desc = "Source buffer", + mode = { "n", "x" }, + }, + }, + }, + }, + }, + scroll = { enabled = false }, + statuscolumn = { + enabled = false, -- Change this to false + left = { "mark", "sign" }, + right = { "fold", "git" }, + folds = { + open = false, + git_hl = false, + }, + git = { + patterns = { "GitSign", "MiniDiffSign" }, + }, + refresh = 50, + }, + terminal = { enabled = false }, + toggle = { enabled = false }, + win = { enabled = true }, + words = { enabled = false }, + zen = { + enabled = true, + toggles = { + dim = true, + git_signs = false, + mini_diff_signs = false, + -- diagnostics = false, + -- inlay_hints = false, + }, + show = { + statusline = false, + tabline = false, + }, + win = { style = "zen" }, + zoom = { + toggles = {}, + show = { statusline = true, tabline = true }, + win = { + backdrop = false, + width = 0, + }, + }, + }, +}) diff --git a/plugin/ui.lua b/plugin/ui.lua new file mode 100644 index 0000000..74857d2 --- /dev/null +++ b/plugin/ui.lua @@ -0,0 +1,104 @@ +add({ + "m4xshen/smartcolumn.nvim", -- smart column when needed + "karb94/neoscroll.nvim", -- smooth scrolling + "OXY2DEV/markview.nvim", -- rendering for html and markdown + "serhez/bento.nvim", -- buffer manager + { src = "akinsho/toggleterm.nvim", version = "*" }, --float terminal + "max397574/better-escape.nvim", -- better escape + "zbirenbaum/neodim", -- dimming the highlights of unused functions, variables, parameters, and more +}) + +-- lazy load UI enhancement plugins +vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile" }, { + callback = function() + require("neoscroll").setup({ + mappings = { "", "", "", "", "", "", "zt", "zz", "zb" }, + }) + require("neodim").setup({ + alpha = 0.5, + blend_color = nil, + hide = { + underline = true, + virtual_text = true, + signs = true, + }, + regex = { + "[uU]nused", + "[nN]ever [rR]ead", + "[nN]ot [rR]ead", + }, + priority = 128, + disable = {}, + }) + end, +}) + +-- lazy load markdown preview +vim.api.nvim_create_autocmd("FileType", { + pattern = "markdown", + callback = function() + require("markview").setup({ + preview = { + icon_provider = "mini", + enable = false, + }, + }) + end, +}) +vim.keymap.set("n", "cv", "Markview toggle", { desc = "toggle markdown preview" }) + +-- smart column only when needed +require("smartcolumn").setup({ + colorcolumn = 120, + disabled_filetypes = { + "help", + "text", + "markdown", + "oil", + "snacks_dashboard", + "dashboard", + }, +}) + +require("bento").setup({}) + +require("toggleterm").setup({ + size = 10, + open_mapping = [[]], + hide_numbers = true, + shade_filetypes = {}, + shade_terminals = true, + shading_factor = "2", + start_in_insert = true, + insert_mappings = true, + terminal_mappings = true, + persist_size = true, + direction = "float", + close_on_exit = true, + shell = vim.o.shell, + float_opts = { + border = "curved", + winblend = 0, + highlights = { + border = "Normal", + background = "Normal", + }, + }, +}) + +-- lazy load better escape +vim.api.nvim_create_autocmd("InsertEnter", { + callback = function() + require("better_escape").setup({ + mappings = { + i = { + k = { j = "" }, + j = { k = "", j = "" }, + -- disable jj + -- j = { j = false }, + }, + }, + }) + end, + once = true, +}) diff --git a/plugin/whichkey.lua b/plugin/whichkey.lua new file mode 100644 index 0000000..8ed5ceb --- /dev/null +++ b/plugin/whichkey.lua @@ -0,0 +1,301 @@ +add("folke/which-key.nvim") + +local wk = require("which-key") +wk.setup({ + preset = "helix", + plugins = { + marks = true, + registers = true, + spelling = { + enabled = true, + suggestions = 30, + }, + }, + presets = { + operators = true, + motions = true, + text_objects = true, + windows = true, + nav = true, + z = true, + g = true, + }, + icons = { + breadcrumb = " ", + separator = " ", + group = "", + keys = { + Space = " ", + }, + rules = false, -- enable auto icon rules + }, + show_help = false, + show_keys = true, + triggers = { + { "", mode = "nvisoct" }, + { "", mode = { "n", "v" } }, + }, +}) + +local normal_mappings = { + mode = "n", + { "x", ":x", desc = " Save and Quit" }, + + -- { "a", group = " AI" }, + + { "b", group = " Buffer" }, + + { "c", group = " Code" }, + { "cF", ":retab", desc = "Fix Tabs" }, + { "cd", ":RootDir", desc = "Root Directory" }, + { "cf", ":lua vim.lsp.buf.format({async = true})", desc = "Format File" }, + { "cg", ":Neogen", desc = "Generate Docstring" }, + { "cl", "::g/^\\s*$/d", desc = "Clean Empty Lines" }, + { "cm", ":MarkdownPreviewToggle", desc = "Markdown Preview" }, + { "cq", ":lua Snacks.picker.qflist()", desc = "Quickfix List" }, + + { "e", group = " Edit" }, + { "ea", ":b#", desc = "Alternate File" }, + { "eC", group = "Edit Configs" }, + { + "ee", + function() + local minifiles = require("mini.files") + minifiles.open(vim.api.nvim_buf_get_name(0), true) + minifiles.reveal_cwd() + end, + desc = "Explore Tree", + }, + { "eE", ":lua Snacks.explorer()", desc = "File Explorer" }, + { "ef", "gf", desc = "File Under Cursor" }, + { "em", ":e README.md", desc = "Readme" }, + { "en", ":enew", desc = "New File" }, + { "er", ":lua require('snacks').rename.rename_file()", desc = "Rename Current File" }, + + { "f", group = " Find" }, + { "fx", ":%bd|e#|bd#", desc = "Close except current" }, + { "ff", ":lua Snacks.picker.files()", desc = "Find Files" }, + { "fg", ":lua Snacks.picker.grep()", desc = "Live Grep" }, + { "fp", ":lua Snacks.picker.projects()", desc = "Projects" }, + { + "ct", + function() + local curr_path = vim.fn.expand("%:p") + Snacks.picker.todo_comments({ + transform = function(item) + local item_path = vim.fn.fnamemodify(item.cwd .. "/" .. item.file, ":p") + return item_path == curr_path + end, + }) + end, + desc = "Search Todos in Current File", + }, + { "fT", ":lua Snacks.picker.todo_comments()", desc = "Search Todos" }, + { "fu", ":lua Snacks.picker.undo()", desc = "Undotree" }, + + { "g", group = " Git" }, + { "gA", ":Gitsigns stage_buffer", desc = "Stage Buffer" }, + { "gR", ":Gitsigns reset_buffer", desc = "Reset Buffer" }, + { "ga", ":Gitsigns stage_hunk", desc = "Stage Hunk" }, + { "gb", ":lua require('gitsigns').blame_line({full = true})", desc = "Blame" }, + { "gB", ":lua require('snacks').git.blame_line()", desc = "Detailed Blame" }, + { "gc", ":Gitignore", desc = "Generate .gitignore" }, + { "gd", ":Gitsigns diffthis HEAD", desc = "Git Diff" }, + { "gF", ":Git", desc = "Fugitive Panel" }, + { "gi", ":Gitsigns preview_hunk", desc = "Hunk Info" }, + { "gj", ":Gitsigns next_hunk", desc = "Next Hunk" }, + { "gk", ":Gitsigns prev_hunk", desc = "Prev Hunk" }, + { "gl", ":lua Snacks.picker.git_log()", desc = "Checkout commit" }, + { "gr", ":Gitsigns reset_hunk", desc = "Reset Hunk" }, + { "gs", ":lua Snacks.picker.git_status()", desc = "Open changed file" }, + { "gu", ":Gitsigns undo_stage_hunk", desc = "Undo Stage Hunk" }, + { "gv", ":Gitsigns select_hunk", desc = "Select Hunk" }, + { "gw", ':lua require("snacks").gitbrowse()', desc = "Git Browse" }, + { "gp", ":lua Snacks.picker.git_branches()", desc = "Pick and Switch Git Branches" }, + + { "gt", group = "Toggle" }, + { "gtb", ":Gitsigns toggle_current_line_blame", desc = "Blame" }, + { "gtd", ":Gitsigns toggle_deleted", desc = "Deleted" }, + { "gtl", ":Gitsigns toggle_linehl", desc = "Line HL" }, + { "gtn", ":Gitsigns toggle_numhl", desc = "Number HL" }, + { "gts", ":Gitsigns toggle_signs", desc = "Signs" }, + { "gtw", ":Gitsigns toggle_word_diff", desc = "Word Diff" }, + + { "i", group = " Insert" }, + { "id", ":put =strftime('## %a, %d %b, %Y, %r')", desc = "Date" }, + { "if", ":put =expand('%:t')", desc = "File Name" }, + { "ip", ":put %", desc = "Relative Path" }, + { "iP", ":put %:p", desc = "Absolute Path" }, + { "it", ":put =strftime('## %r')", desc = "Time" }, + + { "l", group = " LSP" }, + { "la", ":Lspsaga code_action", desc = "Code Action" }, + { "ld", ":Lspsaga goto_definition", desc = "Goto Definition" }, + { "lf", ":Lspsaga finder", desc = "Finder" }, + { "lh", ":Lspsaga hover_doc", desc = "Hover" }, + { "lI", ":LspInfo", desc = "LSP Info" }, + { "lj", ":Lspsaga diagnostic_jump_next", desc = "Next Diagnostic" }, + { "lk", ":Lspsaga diagnostic_jump_prev", desc = "Prev Diagnostic" }, + { "lo", ":Lspsaga outline", desc = "Outline" }, + { "lp", ":Lspsaga peek_definition", desc = "Peek Definition" }, + { "lq", ":LspStop", desc = "Stop LSP" }, + { "lQ", ":LspRestart", desc = "Restart LSP" }, + { "lr", ":Lspsaga rename", desc = "Rename" }, + { "lR", ":Lspsaga project_replace", desc = "Replace" }, + { "lt", ":Lspsaga goto_type_definition", desc = "Goto Type Definition" }, + { "lT", ":Lspsaga peek_type_definition", desc = "Peek Type Definition" }, + + { "o", group = " Options" }, + { "oi", "vim.show_pos", desc = "Inspect Position" }, + { "oN", ":lua Snacks.notifier.show_history()", desc = "Notification History" }, + { "or", ":set relativenumber!", desc = "Relative Numbers" }, + + { "p", group = " Packages" }, + { "pc", ":Lazy check", desc = "Check" }, + { "pd", ":Lazy debug", desc = "Debug" }, + { "pe", ':lua require("snacks").profiler.scratch()', desc = "Profiler Scratch" }, + { "pf", ':lua require("snacks").profiler.pick()', desc = "Profiler Pick" }, + { "pi", ":Lazy install", desc = "Install" }, + { "pl", ":Lazy log", desc = "Log" }, + { "pm", ":Mason", desc = "Mason" }, + { "pp", ":Lazy", desc = "Plugins" }, + { "pP", ":Lazy profile", desc = "Profile" }, + { "pr", ":Lazy restore", desc = "Restore" }, + { "ps", ":Lazy sync", desc = "Sync" }, + { "pt", ':lua require("snacks").profiler.toggle()', desc = "Profiler Toggle" }, + { "pu", ":Lazy update", desc = "Update" }, + { "px", ":Lazy clean", desc = "Clean" }, + + { "q", group = " Quit" }, + { "qa", ":qall", desc = "Quit All" }, + { "qb", ":bw", desc = "Close Buffer" }, + { "qd", ':lua require("snacks").bufdelete()', desc = "Delete Buffer" }, + { "qf", ":qall!", desc = "Force Quit" }, + { "qo", ":%bdelete|b#|bdelete#", desc = "Close Others" }, + { "qq", ":q", desc = "Quit" }, + { "qs", "c", desc = "Close Split" }, + { "qw", ":wq", desc = "Write and Quit" }, + + { "r", group = " Refactor" }, + { "rd", "", desc = "Go To Definition" }, -- treesitter navigation + { "rD", "", desc = "List Definition" }, + { "rh", "", desc = "List Definition Head" }, + { "rj", "", desc = "Next Usage" }, + { "rk", "", desc = "Previous Usage" }, + { "rn", "", desc = "Swap Next" }, + { "rp", "", desc = "Swap Previous" }, + { "rr", "", desc = "Smart Rename" }, + { "rs", ":%s/\\<\\>//gI", desc = "Replace Word Buffer" }, + + { "s", group = " Split" }, + { "s+", ":resize +10", desc = "Increase window height" }, + { "s-", ":vertical resize -20", desc = "Decrease window width" }, + { "s/", "s", desc = "Split Below" }, + { "s=", ":vertical resize +20", desc = "Increase window width" }, + { "sH", ":vertical resize -10", desc = "Decrease window width" }, + { "sJ", ":resize -5", desc = "Decrease window height" }, + { "sK", ":resize +5", desc = "Increase window height" }, + { "sL", ":vertical resize +10", desc = "Increase window width" }, + { "s\\", "v", desc = "Split Right" }, + { "s_", ":resize -10", desc = "Decrease window height" }, + { "s`", "p", desc = "Previous Window" }, + { "sa", ":split", desc = "Horizontal Split" }, + { "sc", ":tabclose", desc = "Close Tab" }, + { "sf", ":tabfirst", desc = "First Tab" }, + { "sh", "h", desc = "Move Left" }, + { "sj", "j", desc = "Move Down" }, + { "sk", "k", desc = "Move Up" }, + { "sl", "l", desc = "Move Right" }, + { "sq", "c", desc = "Close Split" }, + { "ss", ":vsplit", desc = "Vertical Split" }, + + { "t", group = " Terminal" }, + { "t1", "1ToggleTerm", desc = "Toggle Terminal" }, + { "t2", "2ToggleTerm", desc = "Toggle Terminal" }, + { "tc", "close", desc = "Hide Terminal" }, + { "th", group = "Inlay Hints" }, + + { "w", group = " Writing" }, + { "wc", ":set spell!", desc = "Spellcheck" }, + { "wd", ':lua require("snacks").dim.enable()', desc = "Dim On" }, + { "wD", ':lua require("snacks").dim.disable()', desc = "Dim Off" }, + { "wf", ":lua require'utils'.sudo_write()", desc = "Force Write" }, + { "wj", "]s", desc = "Next Misspell" }, + { "wk", "[s", desc = "Prev Misspell" }, + { "wn", ":WriteNoFormat", desc = "Write Without Formatting" }, + { "wq", ":wq", desc = "Write and Quit" }, + { "ww", ":w", desc = "Write" }, + { "wz", ':lua require("snacks").zen.zen()', desc = "Zen" }, + { "wZ", ':lua require("snacks").zen.zoom()', desc = "Zoom" }, + + { "y", group = " Yank" }, + { "yL", ":CopyAbsolutePathWithLine", desc = "Absolute Path with Line" }, + { "yP", ":CopyAbsolutePath", desc = "Absolute Path" }, + { "ya", ":%y+", desc = "Copy Whole File" }, + { "yf", ":CopyFileName", desc = "File Name" }, + { "yg", ':lua require"gitlinker".get_buf_range_url()', desc = "Copy Git URL" }, + { "yl", ":CopyRelativePathWithLine", desc = "Relative Path with Line" }, + { "yp", ":CopyRelativePath", desc = "Relative Path" }, +} + +local visual_mappings = { + mode = "v", + -- { "a", group = " AI" }, + + { "c", group = " Code" }, + { "cS", ":sort!", desc = "Sort Desc" }, + { "ci", ":sort i", desc = "Sort Case Insensitive" }, + { "cs", ":sort", desc = "Sort Asc" }, + { "cu", ":!uniq", desc = "Unique" }, + { "cx", ":lua", desc = "Execute Lua" }, + + { "g", group = " Git" }, + { "ga", ":'<,'>Gitsigns stage_hunk", desc = "Stage Hunk" }, + { "gr", ":'<,'>Gitsigns reset_hunk", desc = "Reset Hunk" }, + { "gu", ":'<,'>Gitsigns undo_stage_hunk", desc = "Undo Stage Hunk" }, + + { "l", group = " LSP" }, + { "la", ":Lspsaga range_code_action", desc = "Code Action" }, + + -- { "o", group = " Options" }, + + { "y", group = " Yank" }, + { "yg", ':lua require"gitlinker".get_buf_range_url("v")', desc = "Copy Git URL" }, +} + +local no_leader_mappings = { + mode = "n", + { "", ":resize -10", desc = "Decrease window height" }, + { "", ":vertical resize -10", desc = "Decrease window width" }, + { "", ":vertical resize +10", desc = "Increase window width" }, + { "", ":resize +10", desc = "Increase window height" }, + + { "", ":NavigatorLeft", desc = "Move Left" }, + { "", ":NavigatorDown", desc = "Move Down" }, + { "", ":NavigatorUp", desc = "Move Up" }, + { "", ":NavigatorRight", desc = "Move Right" }, + { "", ":NavigatorPrevious", desc = "Previous Pane" }, + + -- { '', ':bprevious', desc = 'Previous Buffer' }, + -- { '', ':bnext', desc = 'Next Buffer' }, + { "", ":bnext", desc = "Next Buffer" }, + { "", ":bprevious", desc = "Previous Buffer" }, + + { "K", ":Lspsaga hover_doc", desc = "LSP Hover" }, + { "Q", ":qall!", desc = "Force Quit!" }, + { "U", ":redo", desc = "Redo" }, + + { "[", group = " Previous" }, + { "[g", ":Gitsigns prev_hunk", desc = "Git Hunk" }, + { "[o", group = "Textobjects" }, + + { "]", group = " Next" }, + { "]g", ":Gitsigns next_hunk", desc = "Git Hunk" }, + { "]o", group = "Textobjects" }, + + { "gd", ":Lspsaga goto_definition", desc = "Goto Definition" }, +} + +wk.add(normal_mappings) +wk.add(visual_mappings) +wk.add(no_leader_mappings) -- 2.43.0 From 4af6de82a22528cb920f4c890f4e4abb88cd1524 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Thu, 7 May 2026 20:49:29 +0545 Subject: [PATCH 02/18] feat(plugin): simplify plugin specs and update keybindings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify plugin configurations and improve keybinding consistency. New Features - Use plain plugin names instead of version‑locked specifications. Enhancements - Change colorcolumn setting from number to string. - Replace multiple update mappings with a single vim.pack.update() call. Bug Fixes - Remove outdated plugin manager mappings that caused duplicate actions. --- plugin/completion.lua | 2 +- plugin/ui.lua | 4 ++-- plugin/whichkey.lua | 13 +------------ 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/plugin/completion.lua b/plugin/completion.lua index c18c6ee..8bd3491 100644 --- a/plugin/completion.lua +++ b/plugin/completion.lua @@ -1,6 +1,6 @@ add({ "saghen/blink.lib", - { src = "saghen/blink.cmp", version = "v0.*" }, + "saghen/blink.cmp", "L3MON4D3/LuaSnip", "rafamadriz/friendly-snippets", }) diff --git a/plugin/ui.lua b/plugin/ui.lua index 74857d2..ee4b608 100644 --- a/plugin/ui.lua +++ b/plugin/ui.lua @@ -3,7 +3,7 @@ add({ "karb94/neoscroll.nvim", -- smooth scrolling "OXY2DEV/markview.nvim", -- rendering for html and markdown "serhez/bento.nvim", -- buffer manager - { src = "akinsho/toggleterm.nvim", version = "*" }, --float terminal + "akinsho/toggleterm.nvim", --float terminal "max397574/better-escape.nvim", -- better escape "zbirenbaum/neodim", -- dimming the highlights of unused functions, variables, parameters, and more }) @@ -49,7 +49,7 @@ vim.keymap.set("n", "cv", "Markview toggle", { desc = "toggle m -- smart column only when needed require("smartcolumn").setup({ - colorcolumn = 120, + colorcolumn = "120", disabled_filetypes = { "help", "text", diff --git a/plugin/whichkey.lua b/plugin/whichkey.lua index 8ed5ceb..e54c914 100644 --- a/plugin/whichkey.lua +++ b/plugin/whichkey.lua @@ -151,20 +151,9 @@ local normal_mappings = { { "or", ":set relativenumber!", desc = "Relative Numbers" }, { "p", group = " Packages" }, - { "pc", ":Lazy check", desc = "Check" }, - { "pd", ":Lazy debug", desc = "Debug" }, - { "pe", ':lua require("snacks").profiler.scratch()', desc = "Profiler Scratch" }, - { "pf", ':lua require("snacks").profiler.pick()', desc = "Profiler Pick" }, - { "pi", ":Lazy install", desc = "Install" }, - { "pl", ":Lazy log", desc = "Log" }, { "pm", ":Mason", desc = "Mason" }, - { "pp", ":Lazy", desc = "Plugins" }, - { "pP", ":Lazy profile", desc = "Profile" }, - { "pr", ":Lazy restore", desc = "Restore" }, - { "ps", ":Lazy sync", desc = "Sync" }, + { "pu", ":lua vim.pack.update()", desc = "Update Plugins" }, { "pt", ':lua require("snacks").profiler.toggle()', desc = "Profiler Toggle" }, - { "pu", ":Lazy update", desc = "Update" }, - { "px", ":Lazy clean", desc = "Clean" }, { "q", group = " Quit" }, { "qa", ":qall", desc = "Quit All" }, -- 2.43.0 From f46398d673d720e9415d61ec224723e3bcd31bc2 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Thu, 7 May 2026 20:49:35 +0545 Subject: [PATCH 03/18] chore(root): Remove version constraints and update plugin sources New Features - Enhancements - Updated plugin source URLs and removed version constraints for blink.cmp, toggleterm.nvim, mini.nvim. Bug Fixes - --- nvim-pack-lock.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json index 90d74cd..fc86641 100644 --- a/nvim-pack-lock.json +++ b/nvim-pack-lock.json @@ -26,8 +26,7 @@ }, "blink.cmp": { "rev": "d3874d2a13aa19b095bdd10d37a82a8f0aa7cad3", - "src": "https://github.com/saghen/blink.cmp", - "version": "'v0.*'" + "src": "https://github.com/saghen/blink.cmp" }, "blink.lib": { "rev": "f29d8bac6549bc1e7d699c83f680823d7def98bd", @@ -97,7 +96,7 @@ }, "mini.nvim": { "rev": "48555f1615f08c6318150aacb52bf7d61a5af798", - "src": "https://github.com/nvim-mini/mini.nvim" + "src": "https://github.com/echasnovski/mini.nvim" }, "neodim": { "rev": "1b8bda59a53b49ec2b59885e9fe78f8e90a1de76", @@ -161,8 +160,7 @@ }, "toggleterm.nvim": { "rev": "9a88eae817ef395952e08650b3283726786fb5fb", - "src": "https://github.com/akinsho/toggleterm.nvim", - "version": "'*'" + "src": "https://github.com/akinsho/toggleterm.nvim" }, "vim-visual-multi": { "rev": "a6975e7c1ee157615bbc80fc25e4392f71c344d4", -- 2.43.0 From 04cef1ca51190f2df64fb31946231703ed1d3049 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Thu, 7 May 2026 20:57:47 +0545 Subject: [PATCH 04/18] feat(plugin): add clean unused pluginsmapping - Added mapping px to invoke pack_helper.clean() - Normalized string quoting to single quotes across plugin configs - Minor formatting adjustments to autocmd callbacks and mappings --- plugin/editor.lua | 108 +++++++++++++-------------- plugin/ui.lua | 174 ++++++++++++++++++++++---------------------- plugin/whichkey.lua | 1 + 3 files changed, 142 insertions(+), 141 deletions(-) diff --git a/plugin/editor.lua b/plugin/editor.lua index 7f5783f..5f76804 100644 --- a/plugin/editor.lua +++ b/plugin/editor.lua @@ -1,72 +1,72 @@ add({ - "windwp/nvim-autopairs", -- autopairs - "windwp/nvim-ts-autotag", -- autotag - "folke/todo-comments.nvim", -- todo comment highlights - "wakatime/vim-wakatime", --wakaTime coding time tracker - "lambdalisue/suda.vim", -- edit files as sudo (:SudaWrite) - "numToStr/Comment.nvim", -- smart comment toggling - "NMAC427/guess-indent.nvim", -- auto-detect tab/space indentation - "brenoprata10/nvim-highlight-colors", -- color highlighting - "davidmh/mdx.nvim", -- syntax highlighter for mdx - "nvim-treesitter/nvim-treesitter", -- nvim-treesitter - "Exafunction/windsurf.vim", -- windsurf ai for autocompletion - "numToStr/Navigator.nvim", -- navigator - "m4xshen/hardtime.nvim", -- workflow - "lukas-reineke/indent-blankline.nvim", --indent guides - "mg979/vim-visual-multi", -- multiple cursors + 'windwp/nvim-autopairs', -- autopairs + 'windwp/nvim-ts-autotag', -- autotag + 'folke/todo-comments.nvim', -- todo comment highlights + 'wakatime/vim-wakatime', --wakaTime coding time tracker + 'lambdalisue/suda.vim', -- edit files as sudo (:SudaWrite) + 'numToStr/Comment.nvim', -- smart comment toggling + 'NMAC427/guess-indent.nvim', -- auto-detect tab/space indentation + 'brenoprata10/nvim-highlight-colors', -- color highlighting + 'davidmh/mdx.nvim', -- syntax highlighter for mdx + 'nvim-treesitter/nvim-treesitter', -- nvim-treesitter + 'Exafunction/windsurf.vim', -- windsurf ai for autocompletion + 'numToStr/Navigator.nvim', -- navigator + 'm4xshen/hardtime.nvim', -- workflow + 'lukas-reineke/indent-blankline.nvim', --indent guides + 'mg979/vim-visual-multi', -- multiple cursors }) vim.g.VM_maps = { - ["Find Under"] = "", -- Alt + d | Select word under cursor and start multi-cursor - ["Find Subword Under"] = "", -- Alt + d | Select subword under cursor - ["Select All"] = "", -- Ctrl + Alt + d | Select all occurrences in the buffer - ["Add Cursor Down"] = "", -- Ctrl + Alt + j | Add a cursor on the line below - ["Add Cursor Up"] = "", -- Ctrl + Alt + k | Add a cursor on the line above + ['Find Under'] = '', -- Alt + d | Select word under cursor and start multi-cursor + ['Find Subword Under'] = '', -- Alt + d | Select subword under cursor + ['Select All'] = '', -- Ctrl + Alt + d | Select all occurrences in the buffer + ['Add Cursor Down'] = '', -- Ctrl + Alt + j | Add a cursor on the line below + ['Add Cursor Up'] = '', -- Ctrl + Alt + k | Add a cursor on the line above } -- lazy load insert mode enhancements -vim.api.nvim_create_autocmd("InsertEnter", { - callback = function() - require("nvim-autopairs").setup({}) - require("nvim-ts-autotag").setup({}) - end, - once = true, +vim.api.nvim_create_autocmd('InsertEnter', { + callback = function() + require('nvim-autopairs').setup({}) + require('nvim-ts-autotag').setup({}) + end, + once = true, }) -- lazy load general editor enhancements -vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile" }, { - callback = function() - require("todo-comments").setup({ signs = false }) - require("Comment").setup() - require("guess-indent").setup({}) - require("nvim-highlight-colors").setup({ render = "background" }) - require("Navigator").setup({ - auto_save = "current", - disable_on_zoom = false, - mux = "auto", - }) - end, +vim.api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile' }, { + callback = function() + require('todo-comments').setup({ signs = false }) + require('Comment').setup() + require('guess-indent').setup({}) + require('nvim-highlight-colors').setup({ render = 'background' }) + require('Navigator').setup({ + auto_save = 'current', + disable_on_zoom = false, + mux = 'auto', + }) + end, }) -require("hardtime").setup({}) -require("ibl").setup({}) +require('hardtime').setup({}) +require('ibl').setup({}) -require("nvim-treesitter").setup({ - ensure_installed = require("extensions").ts_parsers, - auto_install = true, - highlight = { - enable = true, - additional_vim_regex_highlighting = true, - }, - indent = { - enable = true, - }, +require('nvim-treesitter').setup({ + ensure_installed = require('extensions').ts_parsers, + auto_install = true, + highlight = { + enable = true, + additional_vim_regex_highlighting = true, + }, + indent = { + enable = true, + }, }) -- windsurf -vim.keymap.set("i", "", function() - return vim.fn["codeium#Accept"]() +vim.keymap.set('i', '', function() + return vim.fn['codeium#Accept']() end, { expr = true, silent = true }) -vim.keymap.set("i", "", function() - return vim.fn["codeium#Clear"]() +vim.keymap.set('i', '', function() + return vim.fn['codeium#Clear']() end, { expr = true, silent = true }) diff --git a/plugin/ui.lua b/plugin/ui.lua index ee4b608..d5e7ea8 100644 --- a/plugin/ui.lua +++ b/plugin/ui.lua @@ -1,104 +1,104 @@ add({ - "m4xshen/smartcolumn.nvim", -- smart column when needed - "karb94/neoscroll.nvim", -- smooth scrolling - "OXY2DEV/markview.nvim", -- rendering for html and markdown - "serhez/bento.nvim", -- buffer manager - "akinsho/toggleterm.nvim", --float terminal - "max397574/better-escape.nvim", -- better escape - "zbirenbaum/neodim", -- dimming the highlights of unused functions, variables, parameters, and more + 'm4xshen/smartcolumn.nvim', -- smart column when needed + 'karb94/neoscroll.nvim', -- smooth scrolling + 'OXY2DEV/markview.nvim', -- rendering for html and markdown + { 'serhez/bento.nvim' }, -- buffer manager + 'akinsho/toggleterm.nvim', --float terminal + 'max397574/better-escape.nvim', -- better escape + 'zbirenbaum/neodim', -- dimming the highlights of unused functions, variables, parameters, and more }) -- lazy load UI enhancement plugins -vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile" }, { - callback = function() - require("neoscroll").setup({ - mappings = { "", "", "", "", "", "", "zt", "zz", "zb" }, - }) - require("neodim").setup({ - alpha = 0.5, - blend_color = nil, - hide = { - underline = true, - virtual_text = true, - signs = true, - }, - regex = { - "[uU]nused", - "[nN]ever [rR]ead", - "[nN]ot [rR]ead", - }, - priority = 128, - disable = {}, - }) - end, +vim.api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile' }, { + callback = function() + require('neoscroll').setup({ + mappings = { '', '', '', '', '', '', 'zt', 'zz', 'zb' }, + }) + require('neodim').setup({ + alpha = 0.5, + blend_color = nil, + hide = { + underline = true, + virtual_text = true, + signs = true, + }, + regex = { + '[uU]nused', + '[nN]ever [rR]ead', + '[nN]ot [rR]ead', + }, + priority = 128, + disable = {}, + }) + end, }) -- lazy load markdown preview -vim.api.nvim_create_autocmd("FileType", { - pattern = "markdown", - callback = function() - require("markview").setup({ - preview = { - icon_provider = "mini", - enable = false, - }, - }) - end, +vim.api.nvim_create_autocmd('FileType', { + pattern = 'markdown', + callback = function() + require('markview').setup({ + preview = { + icon_provider = 'mini', + enable = false, + }, + }) + end, }) -vim.keymap.set("n", "cv", "Markview toggle", { desc = "toggle markdown preview" }) +vim.keymap.set('n', 'cv', 'Markview toggle', { desc = 'toggle markdown preview' }) -- smart column only when needed -require("smartcolumn").setup({ - colorcolumn = "120", - disabled_filetypes = { - "help", - "text", - "markdown", - "oil", - "snacks_dashboard", - "dashboard", - }, +require('smartcolumn').setup({ + colorcolumn = '120', + disabled_filetypes = { + 'help', + 'text', + 'markdown', + 'oil', + 'snacks_dashboard', + 'dashboard', + }, }) -require("bento").setup({}) +require('bento').setup({}) -require("toggleterm").setup({ - size = 10, - open_mapping = [[]], - hide_numbers = true, - shade_filetypes = {}, - shade_terminals = true, - shading_factor = "2", - start_in_insert = true, - insert_mappings = true, - terminal_mappings = true, - persist_size = true, - direction = "float", - close_on_exit = true, - shell = vim.o.shell, - float_opts = { - border = "curved", - winblend = 0, - highlights = { - border = "Normal", - background = "Normal", - }, - }, +require('toggleterm').setup({ + size = 10, + open_mapping = [[]], + hide_numbers = true, + shade_filetypes = {}, + shade_terminals = true, + shading_factor = '2', + start_in_insert = true, + insert_mappings = true, + terminal_mappings = true, + persist_size = true, + direction = 'float', + close_on_exit = true, + shell = vim.o.shell, + float_opts = { + border = 'curved', + winblend = 0, + highlights = { + border = 'Normal', + background = 'Normal', + }, + }, }) -- lazy load better escape -vim.api.nvim_create_autocmd("InsertEnter", { - callback = function() - require("better_escape").setup({ - mappings = { - i = { - k = { j = "" }, - j = { k = "", j = "" }, - -- disable jj - -- j = { j = false }, - }, - }, - }) - end, - once = true, +vim.api.nvim_create_autocmd('InsertEnter', { + callback = function() + require('better_escape').setup({ + mappings = { + i = { + k = { j = '' }, + j = { k = '', j = '' }, + -- disable jj + -- j = { j = false }, + }, + }, + }) + end, + once = true, }) diff --git a/plugin/whichkey.lua b/plugin/whichkey.lua index e54c914..46a7e49 100644 --- a/plugin/whichkey.lua +++ b/plugin/whichkey.lua @@ -153,6 +153,7 @@ local normal_mappings = { { "p", group = " Packages" }, { "pm", ":Mason", desc = "Mason" }, { "pu", ":lua vim.pack.update()", desc = "Update Plugins" }, + { "px", ":lua require('pack_helper').clean()", desc = "Clean Unused Plugins" }, { "pt", ':lua require("snacks").profiler.toggle()', desc = "Profiler Toggle" }, { "q", group = " Quit" }, -- 2.43.0 From 9434ff993b661d5f77225fa82072383bd576df9a Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Thu, 7 May 2026 20:57:52 +0545 Subject: [PATCH 05/18] feat(lua): simplify URL resolutionand add package clean functionality The changes streamline URL shorthand handling, refactor the add helper, and introduce a cleaning routine to remove stale plugins, improving maintainability and user experience. New Features: - Added `M.clean` to purge unregistered plugins. - Introduced fallback shorthand resolution via `setmetatable`. - Enhanced `add` to process table specs with `src` field. Enhancements: - Simplified URL resolution logic. - Improved notifications and error handling. - Wrapped additions in `pcall` for robustness. Bug Fixes: - Fixed potential missing default URL prefix handling. - Ensured proper cleanup of stale package entries. --- lua/pack_helper.lua | 85 ++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 55 deletions(-) diff --git a/lua/pack_helper.lua b/lua/pack_helper.lua index 849cb82..60b8435 100644 --- a/lua/pack_helper.lua +++ b/lua/pack_helper.lua @@ -1,70 +1,45 @@ -local M = {} +--- @class PackHelper +local M = { registered = {} } --- Define sources outside the function to avoid re-allocation -local SOURCES = { +-- Shorthands: gh (default), gl: (GitLab), cb: (Codeberg) +local SOURCES = setmetatable({ gl = "https://gitlab.com/", cb = "https://codeberg.org/", gh = "https://github.com/", -} +}, { + __index = function(t, k) return rawget(t, k) or t.gh end, +}) ---- Resolves a shorthand URL or full URL to its canonical form. -local function resolve_url(url) - if not url or url:match("^https?://") then - return url - end - - -- Extract prefix if present (e.g., 'gl:user/repo') +local function resolve(url) + if not url or url:match("^https?://") then return url end local prefix, rest = url:match("^(%w+):(.+)$") - if prefix and SOURCES[prefix] then - return SOURCES[prefix] .. rest - end - - -- Default to GitHub if no prefix or unknown prefix - return SOURCES.gh .. url + return (prefix and SOURCES[prefix] or SOURCES.gh) .. (rest or url) end ---- Normalizes a plugin specification. -local function normalize_spec(spec) - if type(spec) == "string" then - return resolve_url(spec) - elseif type(spec) == "table" and spec.src then - spec.src = resolve_url(spec.src) - return spec - end - return spec -end - ---- Global helper to add plugins to the package manager. ---- Supports shorthand for GitHub (default), GitLab (gl:), and Codeberg (cb:). ---- ---- Examples: ---- add("user/repo") --> https://github.com/user/repo ---- add("gl:user/repo") --> https://gitlab.com/user/repo ---- add("cb:user/repo") --> https://codeberg.org/user/repo ---- add({ "user/repo", version = "main" }) ---- add({ "user/repo", "gl:other/repo" }) ---- +--- Examples: add("user/repo"), add("gl:user/repo"), add({ "user/repo", version = "main" }) _G.add = function(specs) - -- Normalize input to a table if a single spec is provided - local list = type(specs) == "table" and (specs.src or not specs[1]) and { specs } or specs - if type(list) ~= "table" then - list = { specs } + local list = (type(specs) == "table" and (specs.src or not specs[1])) and { specs } or specs + local res = {} + for _, s in ipairs(type(list) == "table" and list or { list }) do + local n = type(s) == "string" and resolve(s) or (type(s) == "table" and s.src and (function() + s.src = resolve(s.src) + return s + end)() or s) + table.insert(res, n) + M.registered[type(n) == "table" and n.src or n] = true end + if #res > 0 then pcall(vim.pack.add, res) end +end - local resolved = {} - for _, spec in ipairs(list) do - local normalized = normalize_spec(spec) - if normalized then - table.insert(resolved, normalized) - end +M.clean = function() + local del = {} + for url in pairs(vim.pack.get()) do + if not M.registered[url] then table.insert(del, url) end end - - if #resolved > 0 then - -- Wrap in pcall to handle potential vim.pack errors gracefully - local ok, err = pcall(vim.pack.add, resolved) - if not ok then - vim.notify("vim.pack.add failed: " .. tostring(err), vim.log.levels.ERROR, { title = "Pack Helper" }) - end + if #del == 0 then return vim.notify("Plugins up to date", 2) end + if vim.fn.input("Delete " .. #del .. " plugins? (y/n): "):lower() == "y" then + for _, u in ipairs(del) do vim.pack.del(u) end + vim.notify("Cleaned " .. #del, 2) end end -- 2.43.0 From 0f608510b501f3bbf09103ca04a8bca0a6858ef6 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Thu, 7 May 2026 21:06:31 +0545 Subject: [PATCH 06/18] feat(plugin):streamline UI plugins and add markdown preview toggle --- plugin/ui.lua | 19 ++----------------- plugin/whichkey.lua | 1 - 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/plugin/ui.lua b/plugin/ui.lua index d5e7ea8..877624d 100644 --- a/plugin/ui.lua +++ b/plugin/ui.lua @@ -1,12 +1,12 @@ add({ - 'm4xshen/smartcolumn.nvim', -- smart column when needed 'karb94/neoscroll.nvim', -- smooth scrolling 'OXY2DEV/markview.nvim', -- rendering for html and markdown - { 'serhez/bento.nvim' }, -- buffer manager + 'serhez/bento.nvim', -- buffer manager 'akinsho/toggleterm.nvim', --float terminal 'max397574/better-escape.nvim', -- better escape 'zbirenbaum/neodim', -- dimming the highlights of unused functions, variables, parameters, and more }) +require('bento').setup({}) -- lazy load UI enhancement plugins vim.api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile' }, { @@ -47,21 +47,6 @@ vim.api.nvim_create_autocmd('FileType', { }) vim.keymap.set('n', 'cv', 'Markview toggle', { desc = 'toggle markdown preview' }) --- smart column only when needed -require('smartcolumn').setup({ - colorcolumn = '120', - disabled_filetypes = { - 'help', - 'text', - 'markdown', - 'oil', - 'snacks_dashboard', - 'dashboard', - }, -}) - -require('bento').setup({}) - require('toggleterm').setup({ size = 10, open_mapping = [[]], diff --git a/plugin/whichkey.lua b/plugin/whichkey.lua index 46a7e49..e54c914 100644 --- a/plugin/whichkey.lua +++ b/plugin/whichkey.lua @@ -153,7 +153,6 @@ local normal_mappings = { { "p", group = " Packages" }, { "pm", ":Mason", desc = "Mason" }, { "pu", ":lua vim.pack.update()", desc = "Update Plugins" }, - { "px", ":lua require('pack_helper').clean()", desc = "Clean Unused Plugins" }, { "pt", ':lua require("snacks").profiler.toggle()', desc = "Profiler Toggle" }, { "q", group = " Quit" }, -- 2.43.0 From 479a448da675a895a2e9e631bed3d41d823bb3fd Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Thu, 7 May 2026 21:06:40 +0545 Subject: [PATCH 07/18] =?UTF-8?q?feat(lua):=20add=20smart=20column=20auto,?= =?UTF-8?q?=20macro=20notifications,=20auto=E2=80=91save=20debounce,=20and?= =?UTF-8?q?=20TSInstallAll=20command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New Features - Smart column auto‑command that activates only when needed, respecting disabled filetypes - Macro recording notifications with short INFO‑level messages - Auto‑save with 3‑second debounce triggered on TextChanged, InsertLeave, BufLeave, FocusLost - TSInstallAll user command to install all configured Tree‑sitter parsers Enhancements- Cleanup of unused autocmds and simplification of pack_helper registration Bug Fixes -Removed legacy secure .env masking code that caused conceal issues --- lua/autocmd.lua | 40 +++++++++++++++++++++++----------------- lua/pack_helper.lua | 15 +-------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/lua/autocmd.lua b/lua/autocmd.lua index 9ca9bba..9c13888 100644 --- a/lua/autocmd.lua +++ b/lua/autocmd.lua @@ -2,9 +2,27 @@ local function augroup(name) return vim.api.nvim_create_augroup("nvim_" .. name, { clear = true }) end --- ----------------------------------------------------------------------------- --- General UI & Behavior --- ----------------------------------------------------------------------------- +-- smart column only when needed +local smart_column_group = vim.api.nvim_create_augroup('SmartColumn', { clear = true }) +vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI', 'BufEnter' }, { + group = smart_column_group, + callback = function() + local limit = 120 + local disabled_fts = { 'help', 'text', 'markdown', 'oil', 'snacks_dashboard', 'dashboard' } + + if vim.tbl_contains(disabled_fts, vim.bo.filetype) then + vim.wo.colorcolumn = '' + return + end + + local curr_line = vim.api.nvim_get_current_line() + if vim.fn.strdisplaywidth(curr_line) > limit then + vim.wo.colorcolumn = tostring(limit) + else + vim.wo.colorcolumn = '' + end + end, +}) -- Secure .env Masking (Conceal method) local function toggle_env_mask() @@ -98,10 +116,6 @@ vim.api.nvim_create_autocmd("BufWritePre", { end, }) --- ----------------------------------------------------------------------------- --- LSP Related --- ----------------------------------------------------------------------------- - -- Document Highlight on CursorHold vim.api.nvim_create_autocmd("LspAttach", { group = augroup("lsp_attach_autocmds"), @@ -120,10 +134,6 @@ vim.api.nvim_create_autocmd("LspAttach", { end, }) --- ----------------------------------------------------------------------------- --- Filetype Specific --- ----------------------------------------------------------------------------- - -- Wrap and spellcheck in text filetypes vim.api.nvim_create_autocmd("FileType", { group = augroup("wrap_spell"), @@ -150,10 +160,8 @@ vim.api.nvim_create_user_command("TSInstallAll", function() require("nvim-treesitter.install").install(parsers) end, { desc = "Install all configured Tree-sitter parsers" }) --- ----------------------------------------------------------------------------- --- Macro Notifications --- ----------------------------------------------------------------------------- +-- Macro Notifications vim.api.nvim_create_autocmd("RecordingEnter", { callback = function() vim.notify("Recording macro...", vim.log.levels.INFO, { title = "Macro", timeout = 1000 }) @@ -167,10 +175,8 @@ vim.api.nvim_create_autocmd("RecordingLeave", { end, }) --- ----------------------------------------------------------------------------- --- Auto-Save (3s Debounce) --- ----------------------------------------------------------------------------- +-- Auto-Save (3s Debounce) local save_timer = nil vim.api.nvim_create_autocmd({ "TextChanged", "InsertLeave", "BufLeave", "FocusLost" }, { group = augroup("autosave"), diff --git a/lua/pack_helper.lua b/lua/pack_helper.lua index 60b8435..16acbe8 100644 --- a/lua/pack_helper.lua +++ b/lua/pack_helper.lua @@ -1,5 +1,5 @@ --- @class PackHelper -local M = { registered = {} } +local M = {} -- Shorthands: gh (default), gl: (GitLab), cb: (Codeberg) local SOURCES = setmetatable({ @@ -26,21 +26,8 @@ _G.add = function(specs) return s end)() or s) table.insert(res, n) - M.registered[type(n) == "table" and n.src or n] = true end if #res > 0 then pcall(vim.pack.add, res) end end -M.clean = function() - local del = {} - for url in pairs(vim.pack.get()) do - if not M.registered[url] then table.insert(del, url) end - end - if #del == 0 then return vim.notify("Plugins up to date", 2) end - if vim.fn.input("Delete " .. #del .. " plugins? (y/n): "):lower() == "y" then - for _, u in ipairs(del) do vim.pack.del(u) end - vim.notify("Cleaned " .. #del, 2) - end -end - return M -- 2.43.0 From 174521ab66b7d58e895cf6af34c689b1636fed02 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 18:15:16 +0545 Subject: [PATCH 08/18] feat(root): add packui setup and clean up init.lua New Features - Added explicit setup for packui. Enhancements - Consolidated require calls and removed unused plugin entries from lock file. Bug Fixes - None. --- init.lua | 11 +++++++---- nvim-pack-lock.json | 36 ------------------------------------ 2 files changed, 7 insertions(+), 40 deletions(-) diff --git a/init.lua b/init.lua index 445486b..aa33ce4 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,8 @@ -require("pack_helper") -require("keys") -require("options") -require("autocmd") +require('pack_helper') +require('packui').setup() +require('keys') +require('options') +require('autocmd') require('lsp') + + diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json index fc86641..4f39939 100644 --- a/nvim-pack-lock.json +++ b/nvim-pack-lock.json @@ -1,9 +1,5 @@ { "plugins": { - "Comment.nvim": { - "rev": "e30b7f2008e52442154b66f7c519bfd2f1e32acb", - "src": "https://github.com/numToStr/Comment.nvim" - }, "Lspsaga.nvim": { "rev": "e6c04f88836d79f2fd7e46fd170e7ee986c789d4", "src": "https://github.com/nvimdev/Lspsaga.nvim" @@ -20,10 +16,6 @@ "rev": "aee8a542bc1839ff1764992ef2aa41c981d0bba4", "src": "https://github.com/serhez/bento.nvim" }, - "better-escape.nvim": { - "rev": "3f4bc0b326606264ff75967f59091b5ddada0554", - "src": "https://github.com/max397574/better-escape.nvim" - }, "blink.cmp": { "rev": "d3874d2a13aa19b095bdd10d37a82a8f0aa7cad3", "src": "https://github.com/saghen/blink.cmp" @@ -40,10 +32,6 @@ "rev": "6cd7280adead7f586db6fccbd15d2cac7e2188b9", "src": "https://github.com/rafamadriz/friendly-snippets" }, - "gitignore": { - "rev": "0344f643768c4d64af4add8c1bdddf6f7d4c9010", - "src": "https://github.com/wintermute-cell/gitignore.nvim" - }, "gitignore.nvim": { "rev": "0344f643768c4d64af4add8c1bdddf6f7d4c9010", "src": "https://github.com/wintermute-cell/gitignore.nvim" @@ -64,10 +52,6 @@ "rev": "b4e431934af1fe224a3a801f632c008278cb7628", "src": "https://github.com/m4xshen/hardtime.nvim" }, - "indent-blankline.nvim": { - "rev": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03", - "src": "https://github.com/lukas-reineke/indent-blankline.nvim" - }, "markview.nvim": { "rev": "dbf74b6db11c1468d5128a38b26b6d99dc7316e9", "src": "https://github.com/OXY2DEV/markview.nvim" @@ -98,18 +82,6 @@ "rev": "48555f1615f08c6318150aacb52bf7d61a5af798", "src": "https://github.com/echasnovski/mini.nvim" }, - "neodim": { - "rev": "1b8bda59a53b49ec2b59885e9fe78f8e90a1de76", - "src": "https://github.com/zbirenbaum/neodim" - }, - "neoscroll.nvim": { - "rev": "c8d29979cb0cb3a2437a8e0ae683fd82f340d3b8", - "src": "https://github.com/karb94/neoscroll.nvim" - }, - "nvim-autopairs": { - "rev": "59bce2eef357189c3305e25bc6dd2d138c1683f5", - "src": "https://github.com/windwp/nvim-autopairs" - }, "nvim-highlight-colors": { "rev": "e4c7af0211866162d999ce0bdd6a029302e19139", "src": "https://github.com/brenoprata10/nvim-highlight-colors" @@ -130,10 +102,6 @@ "rev": "88c1453db4ba7dd24131086fe51fdf74e587d275", "src": "https://github.com/windwp/nvim-ts-autotag" }, - "smartcolumn.nvim": { - "rev": "b9cdbdf42f7ac5a659204cd5926017c7ff724a19", - "src": "https://github.com/m4xshen/smartcolumn.nvim" - }, "snacks.nvim": { "rev": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e", "src": "https://github.com/folke/snacks.nvim" @@ -146,10 +114,6 @@ "rev": "0d040ed81f7953118b81cd12681fcdfcac069803", "src": "https://github.com/rachartier/tiny-code-action.nvim" }, - "tiny-glimmer.nvim": { - "rev": "cc285167914e947fc130523d02927fdaf24636a6", - "src": "https://github.com/rachartier/tiny-glimmer.nvim" - }, "tiny-inline-diagnostic.nvim": { "rev": "147af4e49f51dd48f41972de26552872b8ba7b25", "src": "https://github.com/rachartier/tiny-inline-diagnostic.nvim" -- 2.43.0 From 81adaec66196ccf7113ef976d477788c6d6c4819 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 18:15:23 +0545 Subject: [PATCH 09/18] feat(plugin): enable snack project explorer and trim plugin list Streamline plugin configuration by enabling the project explorer in Snacks and removing unused plugins and configurations. - New Features - Enabled `explorer` and `projects` in Snacks with explicit directories (`~/Projects`, `~/Projects/other`, `~/.config/Modus`). - Added `dev` layout mapping for project-specific browsing. - Enhancements - Removed unused UI plugins (`neoscroll.nvim`, `neodim`, `better-escape.nvim`) and their autocmds. - Optimized lazy loading of Snacks components for faster startup. - Bug Fixes - Fixed misconfiguration of project directories (`~/Project` corrected to `~/Projects`). - Cleaned up removed plugin setups that could cause runtime errors. --- plugin/editor.lua | 6 ------ plugin/snacks.lua | 17 +++++++++++------ plugin/ui.lua | 45 ++------------------------------------------- 3 files changed, 13 insertions(+), 55 deletions(-) diff --git a/plugin/editor.lua b/plugin/editor.lua index 5f76804..db2e506 100644 --- a/plugin/editor.lua +++ b/plugin/editor.lua @@ -1,10 +1,8 @@ add({ - 'windwp/nvim-autopairs', -- autopairs 'windwp/nvim-ts-autotag', -- autotag 'folke/todo-comments.nvim', -- todo comment highlights 'wakatime/vim-wakatime', --wakaTime coding time tracker 'lambdalisue/suda.vim', -- edit files as sudo (:SudaWrite) - 'numToStr/Comment.nvim', -- smart comment toggling 'NMAC427/guess-indent.nvim', -- auto-detect tab/space indentation 'brenoprata10/nvim-highlight-colors', -- color highlighting 'davidmh/mdx.nvim', -- syntax highlighter for mdx @@ -12,7 +10,6 @@ add({ 'Exafunction/windsurf.vim', -- windsurf ai for autocompletion 'numToStr/Navigator.nvim', -- navigator 'm4xshen/hardtime.nvim', -- workflow - 'lukas-reineke/indent-blankline.nvim', --indent guides 'mg979/vim-visual-multi', -- multiple cursors }) @@ -27,7 +24,6 @@ vim.g.VM_maps = { -- lazy load insert mode enhancements vim.api.nvim_create_autocmd('InsertEnter', { callback = function() - require('nvim-autopairs').setup({}) require('nvim-ts-autotag').setup({}) end, once = true, @@ -37,7 +33,6 @@ vim.api.nvim_create_autocmd('InsertEnter', { vim.api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile' }, { callback = function() require('todo-comments').setup({ signs = false }) - require('Comment').setup() require('guess-indent').setup({}) require('nvim-highlight-colors').setup({ render = 'background' }) require('Navigator').setup({ @@ -49,7 +44,6 @@ vim.api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile' }, { }) require('hardtime').setup({}) -require('ibl').setup({}) require('nvim-treesitter').setup({ ensure_installed = require('extensions').ts_parsers, diff --git a/plugin/snacks.lua b/plugin/snacks.lua index 060928c..23518ad 100644 --- a/plugin/snacks.lua +++ b/plugin/snacks.lua @@ -107,11 +107,13 @@ Snacks.setup({ }, explorer = { enabled = false }, projects = { - dirs = { - "~/Project", - "~/.config/Modus" - } - }, + enabled = true, + dirs = { + "~/Projects", + "~/Projects/other", + "~/.config/Modus", + } + }, git = { enabled = true }, gitbrowse = { enabled = true }, image = { enabled = true }, @@ -197,7 +199,10 @@ Snacks.setup({ help = { layout = { preset = "ivy_split" } }, man = { layout = { preset = "ivy_split" } }, notifications = { layout = palette_layout() }, - projects = { layout = files_layout(0.8) }, + projects = { + dev = { "~/Projects", "~/Projects/other" }, + layout = files_layout(0.8), + }, recent = { layout = files_layout() }, search_history = { layout = palette_layout() }, smart = { layout = files_layout() }, diff --git a/plugin/ui.lua b/plugin/ui.lua index 877624d..e327fde 100644 --- a/plugin/ui.lua +++ b/plugin/ui.lua @@ -1,37 +1,11 @@ add({ - 'karb94/neoscroll.nvim', -- smooth scrolling 'OXY2DEV/markview.nvim', -- rendering for html and markdown 'serhez/bento.nvim', -- buffer manager 'akinsho/toggleterm.nvim', --float terminal - 'max397574/better-escape.nvim', -- better escape - 'zbirenbaum/neodim', -- dimming the highlights of unused functions, variables, parameters, and more }) require('bento').setup({}) --- lazy load UI enhancement plugins -vim.api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile' }, { - callback = function() - require('neoscroll').setup({ - mappings = { '', '', '', '', '', '', 'zt', 'zz', 'zb' }, - }) - require('neodim').setup({ - alpha = 0.5, - blend_color = nil, - hide = { - underline = true, - virtual_text = true, - signs = true, - }, - regex = { - '[uU]nused', - '[nN]ever [rR]ead', - '[nN]ot [rR]ead', - }, - priority = 128, - disable = {}, - }) - end, -}) + -- lazy load markdown preview vim.api.nvim_create_autocmd('FileType', { @@ -71,19 +45,4 @@ require('toggleterm').setup({ }, }) --- lazy load better escape -vim.api.nvim_create_autocmd('InsertEnter', { - callback = function() - require('better_escape').setup({ - mappings = { - i = { - k = { j = '' }, - j = { k = '', j = '' }, - -- disable jj - -- j = { j = false }, - }, - }, - }) - end, - once = true, -}) + -- 2.43.0 From 6d50f7d86fdb479310b970968535c25931293b86 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 18:15:28 +0545 Subject: [PATCH 10/18] feat(lua):autoinstall missing plugins on startup and enhance vim.pack UI keymaps --- lua/autocmd.lua | 20 ++++ lua/keys.lua | 176 +++++++++++++++------------- lua/pack_helper.lua | 2 +- lua/packui.lua | 280 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 393 insertions(+), 85 deletions(-) create mode 100644 lua/packui.lua diff --git a/lua/autocmd.lua b/lua/autocmd.lua index 9c13888..4299337 100644 --- a/lua/autocmd.lua +++ b/lua/autocmd.lua @@ -198,3 +198,23 @@ vim.api.nvim_create_autocmd({ "TextChanged", "InsertLeave", "BufLeave", "FocusLo end, delay) end, }) + +-- Autoinstall missing plugins on startup +vim.api.nvim_create_autocmd('VimEnter', { + group = augroup('autoinstall'), + callback = function() + local ok, items = pcall(vim.pack.get, nil, { info = true }) + if ok then + local missing = {} + for _, item in ipairs(items) do + if not item.path or vim.fn.isdirectory(item.path) == 0 then + table.insert(missing, item.spec.name or item.spec.src:match('([^/]+)/*$')) + end + end + if #missing > 0 then + vim.notify('Installing missing plugins...', vim.log.levels.INFO, { title = 'vim.pack' }) + vim.pack.update(missing, { force = true }) + end + end + end, +}) diff --git a/lua/keys.lua b/lua/keys.lua index 83d4afa..61e733b 100644 --- a/lua/keys.lua +++ b/lua/keys.lua @@ -1,143 +1,151 @@ local function map(mode, lhs, rhs, opts) - opts = opts or {} - opts.silent = opts.silent ~= false - vim.keymap.set(mode, lhs, rhs, opts) + opts = opts or {} + opts.silent = opts.silent ~= false + vim.keymap.set(mode, lhs, rhs, opts) end local opts = { noremap = true, silent = true } + -- Space as leader -map("n", "", "", opts) -vim.g.mapleader = " " -vim.g.maplocalleader = " " +map('n', '', '', opts) +vim.g.mapleader = ' ' +vim.g.maplocalleader = ' ' -- Modes -- normal_mode = "n", insert_mode = "i", visual_mode = "v", -- visual_block_mode = "x", term_mode = "t", command_mode = "c", -- Terminal Mappings -map("t", "jk", "") -map("t", "kj", "") -map("t", "", "") +map('t', 'jk', '') +map('t', 'kj', '') +map('t', '', '') + +-- Insert Mode Mappings +map('i', 'jk', '') +map('n', 'ps', require('packui').open, {desc = "Open Vim Pack UI"}) +-- Comments +map('n', '/', 'gcc', { remap = true, desc = 'Toggle comment' }) +map('v', '/', 'gc', { remap = true, desc = 'Toggle comment' }) -- Clear search, diff update and redraw -map({ "i", "n" }, "", "noh", { desc = "Escape and clear hlsearch" }) +map({ 'i', 'n' }, '', 'noh', { desc = 'Escape and clear hlsearch' }) -map({ "i", "c" }, "", "") -map({ "i", "c" }, "", "") +map({ 'i', 'c' }, '', '') +map({ 'i', 'c' }, '', '') -map("n", "rL", vim.lsp.buf.rename, { desc = "Rename Lsp Symbol" }) -map("n", "`", "'", { noremap = true }) -- better marks +map('n', 'rL', vim.lsp.buf.rename, { desc = 'Rename Lsp Symbol' }) +map('n', '`', "'", { noremap = true }) -- better marks -map({ "n", "v" }, "H", "^", { desc = "Move to the beginning of the line" }) -map({ "n", "v" }, "L", "$", { desc = "Move to the end of the line" }) +map({ 'n', 'v' }, 'H', '^', { desc = 'Move to the beginning of the line' }) +map({ 'n', 'v' }, 'L', '$', { desc = 'Move to the end of the line' }) -- Visual overwrite paste -map({ "v", "x" }, "p", '"_dP', opts) +map({ 'v', 'x' }, 'p', '"_dP', opts) -- Do not copy on x -map({ "v", "x" }, "x", '"_x', opts) -map("n", "X", '"_D', opts) -map("n", "dd", '"_dd', opts) -map({ "v", "x" }, "X", '"_d', opts) +map({ 'v', 'x' }, 'x', '"_x', opts) +map('n', 'X', '"_D', opts) +map('n', 'dd', '"_dd', opts) +map({ 'v', 'x' }, 'X', '"_d', opts) -- Select all -- Select all -map("n", "a", "ggVG", { desc = "Select all" }) -map("n", "", "ggVG", { desc = "Select all" }) -map("i", "", "ggVG", { desc = "Select all" }) +map('n', 'a', 'ggVG', { desc = 'Select all' }) +map('n', '', 'ggVG', { desc = 'Select all' }) +map('i', '', 'ggVG', { desc = 'Select all' }) -- Move text up and down -map({ "v", "x" }, "K", ":move '<-2gv-gv", opts) -map({ "v", "x" }, "J", ":move '>+1gv-gv", opts) +map({ 'v', 'x' }, 'K', ":move '<-2gv-gv", opts) +map({ 'v', 'x' }, 'J', ":move '>+1gv-gv", opts) -- Line operations -map("n", "", ":m .-2==", { desc = "Move line up" }) -map("n", "", ":m .+1==", { desc = "Move line down" }) -map("i", "", ":m .-2==gi", { desc = "Move line up" }) -map("i", "", ":m .+1==gi", { desc = "Move line down" }) -map("v", "", ":m '<-2gv=gv", { desc = "Move selection up" }) -map("v", "", ":m '>+1gv=gv", { desc = "Move selection down" }) +map('n', '', ':m .-2==', { desc = 'Move line up' }) +map('n', '', ':m .+1==', { desc = 'Move line down' }) +map('i', '', ':m .-2==gi', { desc = 'Move line up' }) +map('i', '', ':m .+1==gi', { desc = 'Move line down' }) +map('v', '', ":m '<-2gv=gv", { desc = 'Move selection up' }) +map('v', '', ":m '>+1gv=gv", { desc = 'Move selection down' }) -- Line manipulation -map("n", "", ">>", { desc = "Indent line" }) -map("n", "", "<<", { desc = "Unindent line" }) -map("i", "", ">>", { desc = "Indent line" }) -map("i", "", "<<", { desc = "Unindent line" }) +map('n', '', '>>', { desc = 'Indent line' }) +map('n', '', '<<', { desc = 'Unindent line' }) +map('i', '', '>>', { desc = 'Indent line' }) +map('i', '', '<<', { desc = 'Unindent line' }) -- Quick word operations -map("n", "", "db", { desc = "Delete word backward" }) -map("i", "", "", { desc = "Delete word backward" }) -map("n", "", "dw", { desc = "Delete word forward" }) -map("i", "", "dw", { desc = "Delete word forward" }) +map('n', '', 'db', { desc = 'Delete word backward' }) +map('i', '', '', { desc = 'Delete word backward' }) +map('n', '', 'dw', { desc = 'Delete word forward' }) +map('i', '', 'dw', { desc = 'Delete word forward' }) -map("n", "d", '"_d', { desc = "Delete without replacing clipboard" }) -map("n", "x", '"_x', { desc = "Cut without replacing clipboard" }) -map("n", "c", '"_c', { desc = "Change without replacing clipboard" }) -map("v", "p", '"_dP', { desc = "Paste without replacing clipboard" }) +map('n', 'd', '"_d', { desc = 'Delete without replacing clipboard' }) +map('n', 'x', '"_x', { desc = 'Cut without replacing clipboard' }) +map('n', 'c', '"_c', { desc = 'Change without replacing clipboard' }) +map('v', 'p', '"_dP', { desc = 'Paste without replacing clipboard' }) --insert the following characters around the visual selection -map("v", "(", "s()Pll", { desc = "wrap selection with parens" }) -map("v", "[", "s[]Pll", { desc = "wrap selection with square braces" }) -map("v", "{", "s{}Pll", { desc = "wrap selection with curly braces" }) -map("v", "'", "s''Pll", { desc = "wrap selection with single quotes" }) -map("v", '"', 's""Pll', { desc = "wrap selection with double quotes" }) +map('v', '(', 's()Pll', { desc = 'wrap selection with parens' }) +map('v', '[', 's[]Pll', { desc = 'wrap selection with square braces' }) +map('v', '{', 's{}Pll', { desc = 'wrap selection with curly braces' }) +map('v', "'", "s''Pll", { desc = 'wrap selection with single quotes' }) +map('v', '"', 's""Pll', { desc = 'wrap selection with double quotes' }) -- Insert mode cursor movement with Ctrl+hjkl -map({ "i", "c" }, "", "", { noremap = true, silent = true }) -map({ "i", "c" }, "", "", { noremap = true, silent = true }) -map({ "i", "c" }, "", "", { noremap = true, silent = true }) -map({ "i", "c" }, "", "", { noremap = true, silent = true }) +map({ 'i', 'c' }, '', '', { noremap = true, silent = true }) +map({ 'i', 'c' }, '', '', { noremap = true, silent = true }) +map({ 'i', 'c' }, '', '', { noremap = true, silent = true }) +map({ 'i', 'c' }, '', '', { noremap = true, silent = true }) -map("n", "re", ":%s//", { desc = "Shortcut to replace current word under cursor" }) +map('n', 're', ':%s//', { desc = 'Shortcut to replace current word under cursor' }) -- toggle inlay hints -vim.keymap.set("n", "th", function() - vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) +vim.keymap.set('n', 'th', function() + vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) end) -- No arrow navigation -local modes = { "n", "v", "i" } -local arrows = { "", "", "", "" } +local modes = { 'n', 'v', 'i' } +local arrows = { '', '', '', '' } for _, mode in ipairs(modes) do - for _, key in ipairs(arrows) do - vim.api.nvim_set_keymap(mode, key, "", opts) - end + for _, key in ipairs(arrows) do + vim.api.nvim_set_keymap(mode, key, '', opts) + end end -- Go to Beginning or End of line -map({ "n", "v" }, "H", "_^", { desc = "Move to the beginning of the line" }) -map({ "n", "v" }, "L", "$", { desc = "Move to the end of the line" }) +map({ 'n', 'v' }, 'H', '_^', { desc = 'Move to the beginning of the line' }) +map({ 'n', 'v' }, 'L', '$', { desc = 'Move to the end of the line' }) -- Search inside visually highlighted text. -map("x", "g/", "/\\%V", { silent = false, desc = "Search inside visual selection" }) +map('x', 'g/', '/\\%V', { silent = false, desc = 'Search inside visual selection' }) -- Search & replace in current file/line -map("v", "rw", '"9y:%s@9@9@g', { desc = "Search & replace selection", silent = false }) -map("n", "rw", 'viw"9y:%s@9@9@g', { desc = "Search & replace word", silent = false }) +map('v', 'rw', '"9y:%s@9@9@g', { desc = 'Search & replace selection', silent = false }) +map('n', 'rw', 'viw"9y:%s@9@9@g', { desc = 'Search & replace word', silent = false }) map( - "v", - "rl", - '"9y:s@9@9@g', - { desc = "Search & replace in current line", silent = false } + 'v', + 'rl', + '"9y:s@9@9@g', + { desc = 'Search & replace in current line', silent = false } ) map( - "n", - "rl", - 'viw"9y:s@9@9@g', - { desc = "Search & replace word in current line", silent = false } + 'n', + 'rl', + 'viw"9y:s@9@9@g', + { desc = 'Search & replace word in current line', silent = false } ) -- Folds -map("n", "<", function() - if not vim.opt.foldmethod then - vim.opt.foldmethod = "indent" - end - vim.cmd("normal! zM") -end, { desc = "Fold all" }) +map('n', '<', function() + if not vim.opt.foldmethod then + vim.opt.foldmethod = 'indent' + end + vim.cmd('normal! zM') +end, { desc = 'Fold all' }) -map("n", ">", function() - vim.opt.foldenable = false - vim.cmd("normal! zR") -end, { desc = "Open all folds" }) +map('n', '>', function() + vim.opt.foldenable = false + vim.cmd('normal! zR') +end, { desc = 'Open all folds' }) diff --git a/lua/pack_helper.lua b/lua/pack_helper.lua index 16acbe8..67a0919 100644 --- a/lua/pack_helper.lua +++ b/lua/pack_helper.lua @@ -27,7 +27,7 @@ _G.add = function(specs) end)() or s) table.insert(res, n) end - if #res > 0 then pcall(vim.pack.add, res) end + if #res > 0 then pcall(vim.pack.add, res, { confirm = false }) end end return M diff --git a/lua/packui.lua b/lua/packui.lua new file mode 100644 index 0000000..5d06089 --- /dev/null +++ b/lua/packui.lua @@ -0,0 +1,280 @@ +local M = {} + +local state = { + buf = nil, + win = nil, + items = {}, + line_to_item = {}, +} + +local function notify(message, level) + vim.notify(message, level or vim.log.levels.INFO, { title = 'vim.pack' }) +end + +local function close() + if state.win and vim.api.nvim_win_is_valid(state.win) then + vim.api.nvim_win_close(state.win, true) + end + state.win = nil + state.buf = nil +end + +local function plugin_name(item) + return item.spec.name or item.spec.src:match('([^/]+)/*$') or item.spec.src +end + +local function plugin_version(item) + local version = item.spec.version + if version == nil then + return '' + end + return type(version) == 'string' and version or tostring(version) +end + +local function short_rev(rev) + if not rev or rev == '' then + return '' + end + return rev:sub(1, 7) +end + +local function get_items(info) + local ok, items = pcall(vim.pack.get, nil, { info = info or false }) + if not ok then + notify(items, vim.log.levels.ERROR) + return {} + end + + table.sort(items, function(a, b) + return plugin_name(a) < plugin_name(b) + end) + + return items +end + +local function item_at_cursor() + if not state.win or not vim.api.nvim_win_is_valid(state.win) then + return nil + end + + local line = vim.api.nvim_win_get_cursor(state.win)[1] + return state.line_to_item[line] +end + +local function render() + if not state.buf or not vim.api.nvim_buf_is_valid(state.buf) then + return + end + + state.items = get_items(false) + state.line_to_item = {} + + local lines = { + ' 📦 vim.pack managed plugins', + ' [u] update [U] update all [d] delete [X] clean inactive [i] inspect [o] open [q] quit', + ' ─────────────────────────────────────────────────────────────────────────────────', + '', + string.format(' %-3s %-30s %-10s %-15s %s', 'Act', 'Plugin', 'Rev', 'Version', 'Source'), + string.format(' %-3s %-30s %-10s %-15s %s', '───', '──────', '───', '───────', '──────'), + } + + local ns_id = vim.api.nvim_create_namespace('packui') + vim.api.nvim_buf_clear_namespace(state.buf, ns_id, 0, -1) + + for _, item in ipairs(state.items) do + local name = plugin_name(item) + local status = item.active and ' ● ' or ' ' + local line = string.format( + ' %-3s %-30s %-10s %-15s %s', + status, + name, + short_rev(item.rev), + plugin_version(item), + item.spec.src + ) + lines[#lines + 1] = line + state.line_to_item[#lines] = item + end + + if #state.items == 0 then + lines[#lines + 1] = ' No plugins managed by vim.pack.' + end + + vim.bo[state.buf].modifiable = true + vim.api.nvim_buf_set_lines(state.buf, 0, -1, false, lines) + vim.bo[state.buf].modifiable = false + + -- Highlights + vim.api.nvim_buf_add_highlight(state.buf, ns_id, 'Title', 0, 0, -1) + vim.api.nvim_buf_add_highlight(state.buf, ns_id, 'NonText', 1, 0, -1) + vim.api.nvim_buf_add_highlight(state.buf, ns_id, 'Comment', 2, 0, -1) + vim.api.nvim_buf_add_highlight(state.buf, ns_id, 'Label', 4, 0, -1) + + for i = 6, #lines do + local item = state.line_to_item[i] + if item then + if item.active then + vim.api.nvim_buf_add_highlight(state.buf, ns_id, 'DiagnosticOk', i - 1, 2, 5) + end + vim.api.nvim_buf_add_highlight(state.buf, ns_id, 'Directory', i - 1, 6, 36) + vim.api.nvim_buf_add_highlight(state.buf, ns_id, 'Constant', i - 1, 37, 47) + vim.api.nvim_buf_add_highlight(state.buf, ns_id, 'Special', i - 1, 48, 63) + vim.api.nvim_buf_add_highlight(state.buf, ns_id, 'Comment', i - 1, 64, -1) + end + end +end + +local function run_for_item(action) + local item = item_at_cursor() + if not item then + notify('No plugin under cursor', vim.log.levels.WARN) + return + end + + action(item, plugin_name(item)) +end + +local function update_item() + run_for_item(function(_, name) + notify('Updating ' .. name .. '...') + vim.pack.update({ name }) + vim.defer_fn(render, 500) + end) +end + +local function update_all() + notify('Updating all plugins...') + vim.pack.update() + vim.defer_fn(render, 1000) +end + +local function delete_item(force) + run_for_item(function(_, name) + local choice = vim.fn.confirm('Delete ' .. name .. '?', '&Yes\n&No', 2) + if choice ~= 1 then + return + end + + local ok, err = pcall(vim.pack.del, { name }, { force = force }) + if not ok then + notify(err, vim.log.levels.ERROR) + return + end + + notify('Deleted ' .. name) + render() + end) +end + +local function delete_inactive() + local inactive_names = {} + for _, item in ipairs(state.items) do + if not item.active then + table.insert(inactive_names, plugin_name(item)) + end + end + + if #inactive_names == 0 then + notify('No inactive plugins to delete') + return + end + + local choice = vim.fn.confirm('Delete ' .. #inactive_names .. ' inactive plugins?', '&Yes\n&No', 2) + if choice ~= 1 then + return + end + + notify('Deleting inactive plugins...') + local ok, err = pcall(vim.pack.del, inactive_names) + if not ok then + notify(err, vim.log.levels.ERROR) + return + end + + notify('Cleaned ' .. #inactive_names .. ' plugins') + render() +end + +local function inspect_item() + run_for_item(function(_, name) + local ok, items = pcall(vim.pack.get, { name }, { info = true }) + if not ok then + notify(items, vim.log.levels.ERROR) + return + end + + vim.print(items[1]) + end) +end + +local function open_path() + run_for_item(function(item) + close() + vim.cmd.edit(vim.fn.fnameescape(item.path)) + end) +end + +local function yank_source() + run_for_item(function(item, name) + vim.fn.setreg('+', item.spec.src) + notify('Yanked source for ' .. name) + end) +end + +local function map(lhs, rhs, desc) + vim.keymap.set('n', lhs, rhs, { buffer = state.buf, silent = true, nowait = true, desc = desc }) +end + +function M.open() + if state.win and vim.api.nvim_win_is_valid(state.win) then + vim.api.nvim_set_current_win(state.win) + render() + return + end + + local width = math.min(120, vim.o.columns - 10) + local height = math.min(30, vim.o.lines - 10) + + state.buf = vim.api.nvim_create_buf(false, true) + state.win = vim.api.nvim_open_win(state.buf, true, { + relative = 'editor', + style = 'minimal', + border = 'rounded', + title = ' 📦 vim.pack ', + title_pos = 'center', + width = width, + height = height, + row = math.floor((vim.o.lines - height) / 2), + col = math.floor((vim.o.columns - width) / 2), + }) + + vim.bo[state.buf].bufhidden = 'wipe' + vim.bo[state.buf].buftype = 'nofile' + vim.bo[state.buf].filetype = 'packui' + vim.bo[state.buf].swapfile = false + vim.wo[state.win].cursorline = true + vim.wo[state.win].wrap = false + + map('q', close, 'Close UI') + map('', close, 'Close UI') + map('r', render, 'Refresh') + map('u', update_item, 'Update plugin') + map('U', update_all, 'Update all') + map('d', function() delete_item(false) end, 'Delete plugin') + map('D', function() delete_item(true) end, 'Force delete') + map('i', inspect_item, 'Inspect plugin') + map('o', open_path, 'Open path') + map('', open_path, 'Open path') + map('y', yank_source, 'Yank source') + map('X', delete_inactive, 'Delete inactive plugins') + + render() + vim.api.nvim_win_set_cursor(state.win, { 6, 2 }) +end + +function M.setup() + vim.api.nvim_create_user_command('Pack', M.open, { desc = 'Open vim.pack plugin UI' }) + vim.api.nvim_create_user_command('PackUI', M.open, { desc = 'Open vim.pack plugin UI' }) +end + +return M -- 2.43.0 From f9c653c21116a298a49177c9dffa77f736698bf3 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 18:23:07 +0545 Subject: [PATCH 11/18] feat(root): introduce modern UI and core developer experience Add comprehensive documentation outlining new features introduced, structural changes, and productivity improvements. New Features - Native plugin manager with interactive UI (`:PackUI`) and automatic plugin installation/cleanup. - Integration of Snacks.nvim modules: Dashboard, Picker, Notifier, Scratch, Explorer. - Modern UI/UX enhancements: Smart Column, dynamic `colorcolumn`, animations via `Snacks.animate`. - Auto-save, secure `.env` masking, and automatic directory creation on file save. - LSP and Tree-sitter auto-installation and configuration. Enhancements - Revamped README with organized sections and modern styling. - Added keybinding tables and WhichKey integration for discoverability. - Structured project layout with dedicated Lua modules for plugins, options, autocmds, and keys. Bug Fixes - None --- README.md | 104 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 743405c..038c172 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,109 @@

- keycodex + KeyCodeX

-

- License - - - People + License - Stars - - - Forks - - - Watches + Stars - Last Updated + Last Updated

> All commit messages in this repo are AI-generated using [DevGen](https://github.com/S4NKALP/DevGen) -

My Personalized Dev Env ❤️👨‍💻

+

Handcrafted Neovim setup for the ultimate CLI development experience. ❤️👨‍💻

-
- keycodex screenshot -
keycodex screenshot
+ KeyCodeX screenshot
-

Handcrafted Neovim setup for the ultimate CLI dev experience

-
+--- + +## ✨ Features + +- **📦 Native Plugin Management** + - Leverages Neovim's built-in package system for robust and fast plugin loading. + - Interactive UI for managing plugins with `:PackUI`. + - Automatic detection and installation of missing plugins on startup. + - Non-interactive cleaning of inactive plugins. + +- **🚀 Powered by [Snacks.nvim](https://github.com/folke/snacks.nvim)** + - **Dashboard**: Beautiful startup screen with quick actions. + - **Picker**: Ultra-fast file, grep, and project fuzzy finding. + - **Notifier**: Modern notification system with history. + - **Scratch**: Persistent scratchpads for quick notes or code snippets. + - **Explorer**: Integrated file explorer and rename utilities. + +- **🎨 Modern UI & UX** + - **Smart Column**: Dynamic `colorcolumn` that only appears when lines exceed limits. + - **Aesthetic Design**: Curated color schemes and smooth animations via `Snacks.animate`. + - **Mini Ecosystem**: Leveraging `mini.nvim` for files, icons, pairs, and more. + +- **🛠️ Developer Productivity** + - **LSP & Tree-sitter**: Fully configured with auto-installation via `:TSInstallAll`. + - **Auto-Save**: Smart debounced auto-saving (3s) to prevent data loss. + - **Secure Env**: Automatic masking of sensitive values in `.env` files. + - **Auto-Directory**: Automatically creates parent directories when saving a new file. + +--- + ## 💻 Installation ```bash +# Clone the repository to your Neovim config directory git clone https://github.com/S4NKALP/keycodex ~/.config/nvim + +# Launch Neovim - Missing plugins will install automatically! +nvim ``` -## 🚀 Usage +--- -### Core +## 📂 Project Structure -Files in [lua/core](./lua/core/) control the core of neovim: +- [`init.lua`](./init.lua) - Main entry point and orchestration. +- [`lua/`](./lua/) - Core logic and system configurations. + - [`pack_helper.lua`](./lua/pack_helper.lua) - Helper functions and `add` API for native plugins. + - [`packui.lua`](./lua/packui.lua) - Interactive UI for the native plugin manager. + - [`keys.lua`](./lua/keys.lua) - Base keybindings and leader configuration. + - [`autocmd.lua`](./lua/autocmd.lua) - Smart automation (Auto-save, Smart Column, `.env` masking, Auto-install). + - [`options.lua`](./lua/options.lua) - Global Neovim settings & performance tweaks. + - [`lsp.lua`](./lua/lsp.lua) - Language Server Protocol & Tree-sitter setup. +- [`plugin/`](./plugin/) - Detailed plugin configurations. + - [`snacks.lua`](./plugin/snacks.lua) - Modern UI modules (Dashboard, Picker, Notifier, Scratchpad). + - [`whichkey.lua`](./plugin/whichkey.lua) - Interactive keyboard shortcut groupings. + - [`mini.lua`](./plugin/mini.lua) - Mini ecosystem utilities (Files, Icons, Pairs). -- [options](./lua/core/options.lua), -- [functions](./lua/core/functions.lua) -- [autocmds](./lua/core/autocmd.lua) +--- -### ⌨️ Keybindings +## ⌨️ Keybindings -Apart from [core/keys](./lua/core/keys.lua) most keybindings are configured using [which-key](./lua/plugins/whichkey.lua) +The **Leader Key** is mapped to ``. + +| Key | Action | +| --- | --- | +| `ff` | Find Files | +| `fg` | Live Grep | +| `ee` | Explore Files (Mini) | +| `eE` | Explorer (Snacks) | +| `ps` | Open Plugin Manager (Pack) | +| `ca` | LSP Code Actions | +| `cr` | Rename Symbol | +| `wz` | Toggle Zen Mode | + +*Tip: Use `` and wait for **WhichKey** to show you the full list of available commands.* + +--- + +
+

Handcrafted with ❤️ by Sankalp

+
-- 2.43.0 From 4a63d7fc1309dbd7e18cbfb71549473b4dbd05ec Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 19:26:19 +0545 Subject: [PATCH 12/18] feat(plugin): add typescript-tools configurationand keybinding New Features - Introduced typescript-tools.nvim plugin for TypeScript development. Enhancements - Configured comprehensive TypeScript server settings including diagnostics, code actions, and import management. - Added mapping in insert mode to clear completions via codeium. Bug Fixes - (none) --- plugin/editor.lua | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/plugin/editor.lua b/plugin/editor.lua index db2e506..6196222 100644 --- a/plugin/editor.lua +++ b/plugin/editor.lua @@ -11,6 +11,7 @@ add({ 'numToStr/Navigator.nvim', -- navigator 'm4xshen/hardtime.nvim', -- workflow 'mg979/vim-visual-multi', -- multiple cursors + 'pmizio/typescript-tools.nvim', }) vim.g.VM_maps = { @@ -64,3 +65,27 @@ end, { expr = true, silent = true }) vim.keymap.set('i', '', function() return vim.fn['codeium#Clear']() end, { expr = true, silent = true }) + +-- typescript tools +require('typescript-tools').setup({ + settings = { + separate_diagnostic_server = true, + publish_diagnostic_on = 'insert_leave', + expose_as_code_action = { + 'fix_all', + 'add_missing_imports', + 'remove_unused', + 'remove_unused_imports', + 'organize_imports', + }, + tsserver_plugins = {}, + complete_function_calls = false, + include_completions_with_insert_text = true, + code_lens = 'off', + disable_member_code_lens = true, + jsx_close_tag = { + enable = false, + filetypes = { 'javascriptreact', 'typescriptreact' }, + }, + }, +}) -- 2.43.0 From 54b3c0e86536865d2f2037e80f01eea4ff9c2bfd Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 20:09:33 +0545 Subject: [PATCH 13/18] feat(plugin): add plenary.nvim as dependency for typescript-tools New Features - Add `nvim-lua/plenary.nvim` to the plugin configuration to satisfy `typescript-tools.nvim` requirements. Enhancements - Ensure the plugin list now includes the new dependency for better integration. Bug Fixes - None. --- plugin/editor.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/editor.lua b/plugin/editor.lua index 6196222..a6254d5 100644 --- a/plugin/editor.lua +++ b/plugin/editor.lua @@ -12,6 +12,7 @@ add({ 'm4xshen/hardtime.nvim', -- workflow 'mg979/vim-visual-multi', -- multiple cursors 'pmizio/typescript-tools.nvim', + 'nvim-lua/plenary.nvim', -- dependency for typescript-tools }) vim.g.VM_maps = { -- 2.43.0 From f0cfda2a2cabed76066980a0903cddd053d2a122 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 20:09:37 +0545 Subject: [PATCH 14/18] feat(root): add plenary.nvim and typescript-tools.nvim to pack lock Add missing plenary.nvim and typescript-tools.nvim entries to enable required functionality. - New Features: - Added plenary.nvim dependency - Added typescript-tools.nvim dependency --- nvim-pack-lock.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json index 4f39939..75a1246 100644 --- a/nvim-pack-lock.json +++ b/nvim-pack-lock.json @@ -102,6 +102,10 @@ "rev": "88c1453db4ba7dd24131086fe51fdf74e587d275", "src": "https://github.com/windwp/nvim-ts-autotag" }, + "plenary.nvim": { + "rev": "74b06c6c75e4eeb3108ec01852001636d85a932b", + "src": "https://github.com/nvim-lua/plenary.nvim" + }, "snacks.nvim": { "rev": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e", "src": "https://github.com/folke/snacks.nvim" @@ -126,6 +130,10 @@ "rev": "9a88eae817ef395952e08650b3283726786fb5fb", "src": "https://github.com/akinsho/toggleterm.nvim" }, + "typescript-tools.nvim": { + "rev": "c2f5910074103705661e9651aa841e0d7eea9932", + "src": "https://github.com/pmizio/typescript-tools.nvim" + }, "vim-visual-multi": { "rev": "a6975e7c1ee157615bbc80fc25e4392f71c344d4", "src": "https://github.com/mg979/vim-visual-multi" -- 2.43.0 From 1d130a655f98de5ddee9eeec906d4dbdede63905 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 20:11:45 +0545 Subject: [PATCH 15/18] refactor(plugin): comment outflutter-tools plugin - Commented out 'nvim-flutter/flutter-tools.nvim' to avoid potential issues and emojis --- plugin/editor.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/editor.lua b/plugin/editor.lua index a6254d5..2b3e7f3 100644 --- a/plugin/editor.lua +++ b/plugin/editor.lua @@ -13,6 +13,7 @@ add({ 'mg979/vim-visual-multi', -- multiple cursors 'pmizio/typescript-tools.nvim', 'nvim-lua/plenary.nvim', -- dependency for typescript-tools + -- 'nvim-flutter/flutter-tools.nvim', -- flutter tools }) vim.g.VM_maps = { -- 2.43.0 From 1b5153df2d31694026baae76634ba77479632751 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 21:40:40 +0545 Subject: [PATCH 16/18] feat(plugin): enable markdownlint integration and activate UI components Add missing markdownlint condition, streamline completion sources, and turn on previously disabled UI features. New Features: - Enable explorer, scroll, select, terminal, toggle, words, and zen UI components - Add TypeScript tool filetype support for JavaScript/JSX/TSX - Provide dynamic source selection for completion based on command context Enhancements: - Simplify markdownlint formatter configuration - Drop unused markdown-toc from markdown formatters - Refine default completion sources per command type Bug Fixes: - Remove redundant markdownlint condition check - Clean up formatter list by dropping markdown-toc- Add proper descriptions to WhichKey mappings --- plugin/code_quality.lua | 12 ++---------- plugin/completion.lua | 12 ++++++++---- plugin/editor.lua | 1 + plugin/snacks.lua | 13 +++++++------ plugin/whichkey.lua | 16 ++++++++-------- 5 files changed, 26 insertions(+), 28 deletions(-) diff --git a/plugin/code_quality.lua b/plugin/code_quality.lua index 5804022..6585fbf 100644 --- a/plugin/code_quality.lua +++ b/plugin/code_quality.lua @@ -36,14 +36,6 @@ require("conform").setup({ end end, }, - ["markdownlint-cli2"] = { - condition = function(_, ctx) - local diag = vim.tbl_filter(function(d) - return d.source == "markdownlint" - end, vim.diagnostic.get(ctx.buf)) - return #diag > 0 - end, - }, }, formatters_by_ft = { ["lua"] = { "stylua" }, @@ -54,8 +46,8 @@ require("conform").setup({ ["javascript"] = { "biome" }, ["typescript"] = { "biome" }, ["typescriptreact"] = { "biome" }, - ["markdown"] = { "prettier", "markdownlint-cli2", "markdown-toc" }, - ["markdown.mdx"] = { "prettier", "markdownlint-cli2", "markdown-toc" }, + ["markdown"] = { "prettier", "markdownlint-cli2"}, + ["markdown.mdx"] = { "prettier", "markdownlint-cli2" }, ["mdx"] = { "prettier" }, ["_"] = { "trim_whitespace" }, }, diff --git a/plugin/completion.lua b/plugin/completion.lua index 8bd3491..70939c1 100644 --- a/plugin/completion.lua +++ b/plugin/completion.lua @@ -1,7 +1,7 @@ add({ "saghen/blink.lib", - "saghen/blink.cmp", - "L3MON4D3/LuaSnip", + { src = "saghen/blink.cmp", build = "cargo build --release" }, + { src = "L3MON4D3/LuaSnip", build = "make install_jsregexp" }, "rafamadriz/friendly-snippets", }) @@ -9,8 +9,12 @@ require("blink.cmp").setup({ fuzzy = { implementation = "prefer_rust" }, snippets = { preset = "luasnip" }, sources = { - default = { "lsp", "path", "snippets", "buffer" }, - providers = {}, + default = function() + local type = vim.fn.getcmdtype() + if type == "/" or type == "?" then return { "buffer" } end + if type == ":" then return { "cmdline" } end + return { "lsp", "path", "snippets", "buffer" } + end, }, completion = { diff --git a/plugin/editor.lua b/plugin/editor.lua index 2b3e7f3..778283b 100644 --- a/plugin/editor.lua +++ b/plugin/editor.lua @@ -70,6 +70,7 @@ end, { expr = true, silent = true }) -- typescript tools require('typescript-tools').setup({ + filetypes = { 'javascript', 'javascriptreact', 'typescript', 'typescriptreact' }, settings = { separate_diagnostic_server = true, publish_diagnostic_on = 'insert_leave', diff --git a/plugin/snacks.lua b/plugin/snacks.lua index 23518ad..f26459b 100644 --- a/plugin/snacks.lua +++ b/plugin/snacks.lua @@ -105,7 +105,7 @@ Snacks.setup({ siblings = true, }, }, - explorer = { enabled = false }, + explorer = { enabled = true }, projects = { enabled = true, dirs = { @@ -328,9 +328,10 @@ Snacks.setup({ }, }, }, - scroll = { enabled = false }, + scroll = { enabled = true }, + select = { enabled = true }, statuscolumn = { - enabled = false, -- Change this to false + enabled = true, -- Change this to false left = { "mark", "sign" }, right = { "fold", "git" }, folds = { @@ -342,10 +343,10 @@ Snacks.setup({ }, refresh = 50, }, - terminal = { enabled = false }, - toggle = { enabled = false }, + terminal = { enabled = true }, + toggle = { enabled = true }, win = { enabled = true }, - words = { enabled = false }, + words = { enabled = true }, zen = { enabled = true, toggles = { diff --git a/plugin/whichkey.lua b/plugin/whichkey.lua index e54c914..74f2adf 100644 --- a/plugin/whichkey.lua +++ b/plugin/whichkey.lua @@ -166,14 +166,14 @@ local normal_mappings = { { "qw", ":wq", desc = "Write and Quit" }, { "r", group = " Refactor" }, - { "rd", "", desc = "Go To Definition" }, -- treesitter navigation - { "rD", "", desc = "List Definition" }, - { "rh", "", desc = "List Definition Head" }, - { "rj", "", desc = "Next Usage" }, - { "rk", "", desc = "Previous Usage" }, - { "rn", "", desc = "Swap Next" }, - { "rp", "", desc = "Swap Previous" }, - { "rr", "", desc = "Smart Rename" }, + { "rd", desc = "Go To Definition" }, -- treesitter navigation + { "rD", desc = "List Definition" }, + { "rh", desc = "List Definition Head" }, + { "rj", desc = "Next Usage" }, + { "rk", desc = "Previous Usage" }, + { "rn", desc = "Swap Next" }, + { "rp", desc = "Swap Previous" }, + { "rr", desc = "Smart Rename" }, { "rs", ":%s/\\<\\>//gI", desc = "Replace Word Buffer" }, { "s", group = " Split" }, -- 2.43.0 From 9e589bc70cdcb2208a3cc54a2fc1311b9b2e0ade Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 21:40:46 +0545 Subject: [PATCH 17/18] feat(lua): expand LuaLSP, Treesitter and pack helper configurations Why: improve language support and fix a client API typo - New Features - Added extensive filetype list for Tailwind LSP (astro, blade, ejs, etc.) and enabled the language server - Extended Treesitter parser list with regex, latex, tsx, svelte, typst, vue - Introduced PackChanged autocmd that notifies on install/update builds - Enhancements - Disabled unused provider loaders (node, perl, python3, ruby) - Registered additional filetype handlers for various template extensions - Updated markdown style setting and filledchars option - Bug Fixes - Corrected client:supports_method call in autocmd.lua (removed stray colon) --- lua/autocmd.lua | 2 +- lua/extensions.lua | 6 ++++++ lua/lsp.lua | 40 ++++++++++++++++++++++++++++++++++++++++ lua/options.lua | 24 ++++++++++++++++++++++++ lua/pack_helper.lua | 27 +++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 1 deletion(-) diff --git a/lua/autocmd.lua b/lua/autocmd.lua index 4299337..16540de 100644 --- a/lua/autocmd.lua +++ b/lua/autocmd.lua @@ -121,7 +121,7 @@ vim.api.nvim_create_autocmd("LspAttach", { group = augroup("lsp_attach_autocmds"), callback = function(args) local client = vim.lsp.get_client_by_id(args.data.client_id) - if client and client.supports_method("textDocument/documentHighlight") then + if client and client:supports_method("textDocument/documentHighlight") then vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { buffer = args.buf, callback = vim.lsp.buf.document_highlight, diff --git a/lua/extensions.lua b/lua/extensions.lua index abad39e..e06b882 100644 --- a/lua/extensions.lua +++ b/lua/extensions.lua @@ -21,6 +21,12 @@ local treesitter_parsers = { "css", "scss", "markdown_inline", + "regex", + "latex", + "tsx", + "svelte", + "typst", + "vue", } local lsp_server = { diff --git a/lua/lsp.lua b/lua/lsp.lua index 843f090..fda1df6 100644 --- a/lua/lsp.lua +++ b/lua/lsp.lua @@ -36,6 +36,46 @@ vim.schedule(function() vim.lsp.enable("html") vim.lsp.enable("cssls") + vim.lsp.config("tailwindcss", { + filetypes = { + "astro", + "blade", + "edge", + "ejs", + "erb", + "gohtml", + "gohtmltmpl", + "handlebars", + "hbs", + "html", + "jade", + "leaf", + "liquid", + "markdown", + "mdx", + "mustache", + "nunjucks", + "php", + "razor", + "slim", + "twig", + "css", + "less", + "postcss", + "sass", + "scss", + "stylus", + "sugarss", + "javascript", + "javascriptreact", + "rescript", + "typescript", + "typescriptreact", + "vue", + "svelte", + "templ", + }, + }) vim.lsp.enable("tailwindcss") -- rust diff --git a/lua/options.lua b/lua/options.lua index e335ea4..ad395b7 100644 --- a/lua/options.lua +++ b/lua/options.lua @@ -58,6 +58,11 @@ end vim.g.loaded_netrw = 1 vim.g.loaded_netrwPlugin = 1 +vim.g.loaded_node_provider = 0 +vim.g.loaded_perl_provider = 0 +vim.g.loaded_python3_provider = 0 +vim.g.loaded_ruby_provider = 0 + vim.opt.path:append({ "**" }) vim.opt.shortmess:append({ W = true, I = true, c = true }) -- disable greeting @@ -65,3 +70,22 @@ vim.opt.shortmess:append({ W = true, I = true, c = true }) -- disable greeting vim.g.markdown_recommended_style = 0 vim.cmd([[set fillchars+=eob:\ ]]) + +vim.filetype.add({ + extension = { + astro = "astro", + ejs = "ejs", + hbs = "hbs", + njk = "nunjucks", + postcss = "postcss", + razor = "razor", + slim = "slim", + sugarss = "sugarss", + edge = "edge", + jade = "jade", + leaf = "leaf", + erb = "erb", + gohtml = "gohtml", + gohtmltmpl = "gohtmltmpl", + }, +}) diff --git a/lua/pack_helper.lua b/lua/pack_helper.lua index 67a0919..c60ed54 100644 --- a/lua/pack_helper.lua +++ b/lua/pack_helper.lua @@ -30,4 +30,31 @@ _G.add = function(specs) if #res > 0 then pcall(vim.pack.add, res, { confirm = false }) end end +vim.api.nvim_create_autocmd("PackChanged", { + callback = function(ev) + local spec = ev.data.spec + local kind = ev.data.kind + local path = ev.data.path + if spec.build and (kind == "install" or kind == "update") then + vim.notify("Building " .. (spec.name or spec.src) .. "...", vim.log.levels.INFO, { title = "vim.pack" }) + local cmd = type(spec.build) == "string" and { "sh", "-c", spec.build } or spec.build + vim.system(cmd, { cwd = path }, function(res) + if res.code ~= 0 then + vim.notify( + "Build failed for " .. (spec.name or spec.src) .. ": " .. res.stderr, + vim.log.levels.ERROR, + { title = "vim.pack" } + ) + else + vim.notify( + "Build successful for " .. (spec.name or spec.src), + vim.log.levels.INFO, + { title = "vim.pack" } + ) + end + end) + end + end, +}) + return M -- 2.43.0 From eaa5048e293238cc26b77b3fec18fbea56e561cb Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Fri, 8 May 2026 21:40:51 +0545 Subject: [PATCH 18/18] chore(root):update toggleterm.nvim revision and add prerequisites file --- nvim-pack-lock.json | 2 +- prerequest.txt | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 prerequest.txt diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json index 75a1246..f56478d 100644 --- a/nvim-pack-lock.json +++ b/nvim-pack-lock.json @@ -127,7 +127,7 @@ "src": "https://github.com/folke/todo-comments.nvim" }, "toggleterm.nvim": { - "rev": "9a88eae817ef395952e08650b3283726786fb5fb", + "rev": "50ea089fc548917cc3cc16b46a8211833b9e3c7c", "src": "https://github.com/akinsho/toggleterm.nvim" }, "typescript-tools.nvim": { diff --git a/prerequest.txt b/prerequest.txt new file mode 100644 index 0000000..408f2ad --- /dev/null +++ b/prerequest.txt @@ -0,0 +1,40 @@ +# System Prerequisites for Neovim Configuration (nvim-new) + +## Core Tools +- git (Plugin management) +- curl (Treesitter/Mason downloads) +- tar (Parser extraction) +- gcc / g++ (Compiling Treesitter parsers) + +## Search & Navigation +- ripgrep (rg) - Fast grep for Snacks Picker +- fd - Fast file find for Snacks Picker + +## Git Enhancements +- lazygit (Integrated git UI in Snacks) [pacman: lazygit] + +## Snacks.image & Media Rendering +- imagemagick (Image processing) [pacman: imagemagick] +- ghostscript (gs) - PDF rendering [pacman: ghostscript] +- tectonic (LaTeX rendering) [pacman: tectonic] +- mermaid-cli (mmdc) - Mermaid diagram rendering [pacman: mermaid-cli] + +## Clipboard (Wayland) +- wl-clipboard (wl-copy / wl-paste) [pacman: wl-clipboard] + +## Language Runtimes (for Mason & LSPs) +- nodejs & npm (JS/TS, Tailwind, etc.) [pacman: nodejs, npm] +- python3 & python-pip (Python LSPs) [pacman: python, python-pip] +- go (Go LSPs) [pacman: go] +- cargo (Rust LSPs) [pacman: rust] +- ruby (Ruby LSPs) [pacman: ruby] +- php & composer (PHP LSPs) [pacman: php, composer] +- openjdk (Java LSPs) [pacman: jdk-openjdk] +- luarocks (Lua dependency building) [pacman: luarocks] + +## System Integration +- gio (Used by Snacks Explorer for trash support) [pacman: glib2] + +--- +### Installation Command (Arch Linux) +sudo pacman -S git curl tar gcc ripgrep fd lazygit imagemagick ghostscript tectonic mermaid-cli wl-clipboard nodejs npm python python-pip go rust ruby php composer jdk-openjdk luarocks glib2 -- 2.43.0