diff --git a/init.lua b/init.lua index c706f35..84f176b 100644 --- a/init.lua +++ b/init.lua @@ -1,20 +1,20 @@ -require("options") +vim.loader.enable() -local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" -if not vim.loop.fs_stat(lazypath) then - vim.fn.system({ - "git", - "clone", - "--filter=blob:none", - "https://github.com/folke/lazy.nvim.git", - "--branch=stable", -- latest stable release - lazypath, - }) -end -vim.opt.rtp:prepend(lazypath) +require("vim._core.ui2").enable({}) +require("options") require("keymaps") require("autocmd") require("commands") -require("lazy").setup("plugins", { change_detection = { notify = false } }) +vim.api.nvim_create_autocmd("PackChanged", { + callback = function(ev) + local name, kind = ev.data.spec.name, ev.data.kind + if name == "nvim-treesitter" and kind == "update" then + if not ev.data.active then + vim.cmd.packadd("nvim-treesitter") + end + vim.cmd("TSUpdate") + end + end, +}) diff --git a/lazy-lock.json b/lazy-lock.json deleted file mode 100644 index 1280170..0000000 --- a/lazy-lock.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "LuaSnip": { "branch": "master", "commit": "5a1e39223db9a0498024a77b8441169d260c8c25" }, - "auto-dark-mode.nvim": { "branch": "master", "commit": "c31de126963ffe9403901b4b0990dde0e6999cc6" }, - "auto-session": { "branch": "main", "commit": "dcbc339a1a0e6505f755d980ad11f892b6a8d492" }, - "barbar.nvim": { "branch": "master", "commit": "53b5a2f34b68875898f0531032fbf090e3952ad7" }, - "blink.cmp": { "branch": "main", "commit": "4b18c32adef2898f95cdef6192cbd5796c1a332d" }, - "codediff.nvim": { "branch": "main", "commit": "7e5cda21dab96901cbc4bf3b15828aa8c7b490a7" }, - "conform.nvim": { "branch": "master", "commit": "c2526f1cde528a66e086ab1668e996d162c75f4f" }, - "copilot.lua": { "branch": "master", "commit": "3faffefbd6ddeb52578535ec6b730e0b72d7fd1a" }, - "cutlass.nvim": { "branch": "main", "commit": "d01b5c1943050fcda8edf5c89d4419c41a65890e" }, - "definition-or-references.nvim": { "branch": "main", "commit": "7318f9479d2db357d2908599c3ec14bec7c589dd" }, - "fidget.nvim": { "branch": "main", "commit": "7fa433a83118a70fe24c1ce88d5f0bd3453c0970" }, - "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" }, - "gitsigns.nvim": { "branch": "main", "commit": "31217271a7314c343606acb4072a94a039a19fb5" }, - "harpoon": { "branch": "harpoon2", "commit": "87b1a3506211538f460786c23f98ec63ad9af4e5" }, - "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, - "live-server.nvim": { "branch": "main", "commit": "d6a253569ebb813c622f56971f55f56d044f6ab5" }, - "lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" }, - "markdown-preview.nvim": { "branch": "main", "commit": "e2d58c41372ed58de2b781b8bdf74fd027c6a3f3" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "ae609525ddf01c153c39305730b1791800ffe4fe" }, - "mason-tool-installer.nvim": { "branch": "main", "commit": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc" }, - "mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" }, - "multicursor.nvim": { "branch": "1.0", "commit": "630dd29dd696bc977cb81d7dd2fa6bb280f60fc4" }, - "neo-tree.nvim": { "branch": "v3.x", "commit": "f3df514fff2bdd4318127c40470984137f87b62e" }, - "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, - "nvim-autopairs": { "branch": "master", "commit": "59bce2eef357189c3305e25bc6dd2d138c1683f5" }, - "nvim-highlight-colors": { "branch": "main", "commit": "e2cb22089cc2358b2b995c09578224f142de6039" }, - "nvim-hlslens": { "branch": "main", "commit": "be2d7b2be01860b5445a007ff2bc72b29896db6b" }, - "nvim-lspconfig": { "branch": "master", "commit": "66fd02ad1c7ea31616d3ca678fa04e6d0b360824" }, - "nvim-scrollbar": { "branch": "main", "commit": "f8e87b96cd6362ef8579be456afee3b38fd7e2a8" }, - "nvim-surround": { "branch": "main", "commit": "1098d7b3c34adcfa7feb3289ee434529abd4afd1" }, - "nvim-treesitter": { "branch": "main", "commit": "45a07f869b0cffba342276f2c77ba7c116d35db8" }, - "nvim-web-devicons": { "branch": "master", "commit": "746ffbb17975ebd6c40142362eee1b0249969c5c" }, - "onedarkpro.nvim": { "branch": "main", "commit": "743bf248cf238a0625f3a204eecefafcf6281a9f" }, - "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, - "scope.nvim": { "branch": "main", "commit": "228aabdb1b9cc74f0c0ccec88e79873857236e49" }, - "snacks.nvim": { "branch": "main", "commit": "fe7cfe9800a182274d0f868a74b7263b8c0c020b" }, - "ts-comments.nvim": { "branch": "main", "commit": "123a9fb12e7229342f807ec9e6de478b1102b041" }, - "wildfire.nvim": { "branch": "master", "commit": "918a1873c2b8010baa034f373cf28c53ce4f038f" } -} diff --git a/lua/commands.lua b/lua/commands.lua index cfda12f..8e9e296 100644 --- a/lua/commands.lua +++ b/lua/commands.lua @@ -15,7 +15,3 @@ create_cmd("QuickfixListToggle", function() vim.cmd("copen") end end, { desc = "Toggle quickfix list" }) - -create_cmd("ClearAllMarks", function() - vim.cmd("delmarks A-Z") -end, { desc = "Clear {A-Z} marks" }) diff --git a/lua/plugins/common/utils.lua b/lua/common/utils.lua similarity index 100% rename from lua/plugins/common/utils.lua rename to lua/common/utils.lua diff --git a/lua/keymaps.lua b/lua/keymaps.lua index 30e9f78..5afec98 100644 --- a/lua/keymaps.lua +++ b/lua/keymaps.lua @@ -1,4 +1,4 @@ -local f = require("plugins.common.utils") +local f = require("common.utils") local marks = require("marks") local function feedkeys(keys) @@ -173,3 +173,6 @@ end, { desc = "Delete mark in current line" }) -- Folds vim.keymap.set("n", "ff", "za", { desc = "Toggle fold" }) + +-- Search in visual mode +vim.keymap.set("x", "/", "`", close, { buffer = buf, nowait = true, silent = true }) end +function M.clear_all_marks() + vim.cmd("delmarks A-Z") +end + +vim.api.nvim_create_user_command("ClearAllMarks", function() + M.clear_all_marks() +end, { desc = "Clear {A-Z} marks" }) + return M diff --git a/lua/options.lua b/lua/options.lua index 61a80ba..6aea1bb 100644 --- a/lua/options.lua +++ b/lua/options.lua @@ -1,4 +1,4 @@ -local f = require("plugins.common.utils") +local f = require("common.utils") vim.o.clipboard = "unnamedplus" -- Enables system clipboard integration; yanked text will be available in the system clipboard vim.o.expandtab = true -- Converts tabs to spaces when you input them @@ -15,7 +15,7 @@ vim.o.softtabstop = 2 -- Defines the number of spaces to insert for a key vim.o.tabstop = 2 -- Sets the number of spaces a character counts for vim.o.splitright = true -- Opens new vertical splits to the right of the current split vim.o.timeoutlen = 500 -- Sets the time in milliseconds to wait for key codes -vim.o.ttimeoutlen = 0 -- Disables the time Neovim waits for a key code +vim.o.ttimeoutlen = 1 -- Disables the time Neovim waits for a key code vim.wo.scl = "yes" -- Sets "sidescrolloff" to "yes," making the cursor stay a certain number of columns away from the screen edge when scrolling horizontally vim.o.scrolloff = 20 -- Specifies the minimum number of screen lines to keep above and below the cursor vim.o.pumheight = 10 -- Sets the maximum height of the popup menu diff --git a/lua/plugins/autopairs.lua b/lua/plugins/autopairs.lua deleted file mode 100644 index 30d0444..0000000 --- a/lua/plugins/autopairs.lua +++ /dev/null @@ -1,17 +0,0 @@ -return { - "windwp/nvim-autopairs", - event = "InsertEnter", - config = function() - -- import nvim-autopairs - local autopairs = require("nvim-autopairs") - - -- configure autopairs - autopairs.setup({ - check_ts = true, -- enable treesitter - ts_config = { - lua = { "string" }, -- don't add pairs in lua string treesitter nodes - javascript = { "template_string" }, -- don't add pairs in javscript template_string treesitter nodes - }, - }) - end, -} diff --git a/lua/plugins/barbar.lua b/lua/plugins/barbar.lua deleted file mode 100644 index 926009c..0000000 --- a/lua/plugins/barbar.lua +++ /dev/null @@ -1,102 +0,0 @@ -local f = require("plugins.common.utils") - -return { - "romgrk/barbar.nvim", - event = "VeryLazy", - dependencies = { - "lewis6991/gitsigns.nvim", - "nvim-tree/nvim-web-devicons", - }, - init = function() - vim.g.barbar_auto_setup = false - end, - config = function() - local barbar = require("barbar") - local state = require("barbar.state") - local render = require("barbar.ui.render") - local harpoon = require("harpoon") - - barbar.setup({ - animation = false, - tabpages = false, - icons = { - button = false, - pinned = { filename = true, buffer_index = true }, - diagnostics = { - [vim.diagnostic.severity.ERROR] = { enabled = true, icon = f.diagnosticIcons.ERROR }, - }, - separator = { - left = " ", - }, - }, - }) - - f.HighlightGroups.register(function() - local default_error_hl = vim.api.nvim_get_hl(0, { name = "ErrorMsg" }) - local default_buffer_hl = - vim.tbl_extend("force", vim.api.nvim_get_hl(0, { name = "Directory" }), { bold = true }) - - vim.api.nvim_set_hl(0, "BufferVisibleERROR", default_error_hl) - vim.api.nvim_set_hl(0, "BufferCurrentERROR", default_error_hl) - vim.api.nvim_set_hl(0, "BufferCurrent", default_buffer_hl) - vim.api.nvim_set_hl(0, "BufferCurrentMod", default_buffer_hl) - vim.api.nvim_set_hl(0, "BufferCurrentSign", default_buffer_hl) - end) - - vim.keymap.set({ "n", "v" }, "", ":BufferPrevious", { silent = true }) - vim.keymap.set({ "n", "v" }, "", ":BufferNext", { silent = true }) - vim.keymap.set("n", "<", ":BufferMovePrevious", { silent = true }) - vim.keymap.set("n", ">", ":BufferMoveNext", { silent = true }) - - local function unpin_all() - for _, buf in ipairs(state.buffers) do - local data = state.get_buffer_data(buf) - data.pinned = false - end - end - - local function get_buffer_by_mark(mark) - for _, buf in ipairs(vim.api.nvim_list_bufs()) do - local buffer_path = vim.api.nvim_buf_get_name(buf) - - if buffer_path == "" or mark.value == "" then - goto continue - end - - local mark_pattern = mark.value:gsub("([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1") - if string.match(buffer_path, mark_pattern) then - return buf - end - - local buffer_path_pattern = buffer_path:gsub("([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1") - if string.match(mark.value, buffer_path_pattern) then - return buf - end - - ::continue:: - end - end - - local function refresh_all_harpoon_tabs() - local list = harpoon:list() - unpin_all() - for _, mark in ipairs(list.items) do - local buf = get_buffer_by_mark(mark) - if buf == nil then - vim.cmd("badd " .. mark.value) - buf = get_buffer_by_mark(mark) - end - if buf ~= nil then - state.toggle_pin(buf) - end - end - render.update() - end - - vim.api.nvim_create_autocmd({ "BufEnter", "BufAdd", "BufLeave", "User" }, { - pattern = { "*", "HarpoonRefresh" }, -- Add a specific pattern for User event - callback = refresh_all_harpoon_tabs, - }) - end, - version = "^1.0.0", -} diff --git a/lua/plugins/blink.lua b/lua/plugins/blink.lua deleted file mode 100644 index f6b580f..0000000 --- a/lua/plugins/blink.lua +++ /dev/null @@ -1,49 +0,0 @@ -local f = require("plugins.common.utils") -return { - "saghen/blink.cmp", - dependencies = { - "rafamadriz/friendly-snippets", - { "L3MON4D3/LuaSnip", version = "v2.*" }, - }, - version = "v1.*", - opts = { - sources = { - default = function() - if vim.bo.filetype == "copilot-chat" then - return {} - end - return { "lsp", "path", "buffer" } - end, - }, - keymap = { - preset = "enter", - [f.isMac() and "" or "⊘"] = { "show", "hide" }, - [""] = {}, - [""] = {}, - [""] = {}, - [""] = {}, - [""] = { "scroll_documentation_up", "fallback" }, - [""] = { "scroll_documentation_down", "fallback" }, - }, - appearance = { - nerd_font_variant = "normal", - }, - signature = { - enabled = true, - }, - completion = { - menu = { - draw = { - columns = { { "kind_icon" }, { "label", "label_description", gap = 1 }, { "kind" } }, - }, - }, - documentation = { - auto_show = true, - auto_show_delay_ms = 0, - }, - }, - snippets = { - preset = "luasnip", - }, - }, -} diff --git a/lua/plugins/codediff.lua b/lua/plugins/codediff.lua deleted file mode 100644 index 0d2cb7b..0000000 --- a/lua/plugins/codediff.lua +++ /dev/null @@ -1,21 +0,0 @@ -return { - "esmuellert/codediff.nvim", - dependencies = { "MunifTanjim/nui.nvim" }, - cmd = "CodeDiff", - keys = { - { "dd", "CodeDiff", desc = "Code diff" }, - }, - opts = { - explorer = { - position = "right", - width = 60, - view_mode = "tree", - }, - keymaps = { - view = { - next_file = "", - prev_file = "", - }, - }, - }, -} diff --git a/lua/plugins/colorizer.lua b/lua/plugins/colorizer.lua deleted file mode 100644 index 9344157..0000000 --- a/lua/plugins/colorizer.lua +++ /dev/null @@ -1,8 +0,0 @@ -return { - "brenoprata10/nvim-highlight-colors", - config = function() - require("nvim-highlight-colors").setup({ - enable_tailwind = true, - }) - end, -} diff --git a/lua/plugins/colorscheme.lua b/lua/plugins/colorscheme.lua deleted file mode 100644 index 0d63ea1..0000000 --- a/lua/plugins/colorscheme.lua +++ /dev/null @@ -1,35 +0,0 @@ -local f = require("plugins.common.utils") - -return { - { - -- windows with wsl does not listen for background change - -- last message in: https://chatgpt.com/share/681f1213-6938-8013-adcb-802845e8bb32 - "f-person/auto-dark-mode.nvim", - enabled = not f.isMac(), - opts = {}, - }, - { - "olimorris/onedarkpro.nvim", - priority = 1000, -- Ensure it loads first - config = function() - require("onedarkpro").setup({ - styles = { - functions = "bold", - }, - highlights = { - LspReferenceText = { link = "CursorColumn", extend = true }, - NeoTreeCursorLine = { bg = "${cursorline}", bold = true }, -- Neo-tree/onedarkpro bug fix - }, - }) - vim.cmd.colorscheme("onedark_vivid") - vim.api.nvim_create_autocmd("OptionSet", { - pattern = "background", - callback = function(_) - vim.cmd.colorscheme(vim.o.background == "light" and "onelight" or "onedark_vivid") - - f.HighlightGroups.executeAll() - end, - }) - end, - }, -} diff --git a/lua/plugins/comment.lua b/lua/plugins/comment.lua deleted file mode 100644 index fca81c7..0000000 --- a/lua/plugins/comment.lua +++ /dev/null @@ -1,6 +0,0 @@ -return { - "folke/ts-comments.nvim", - opts = {}, - event = "VeryLazy", - enabled = vim.fn.has("nvim-0.10.0") == 1, -} diff --git a/lua/plugins/conform.lua b/lua/plugins/conform.lua deleted file mode 100644 index f863073..0000000 --- a/lua/plugins/conform.lua +++ /dev/null @@ -1,55 +0,0 @@ -local f = require("plugins.common.utils") -local function use_biome_if_installed_locally(bufnr) - local biome_info = require("conform").get_formatter_info("biome", bufnr) - if biome_info and biome_info.available and biome_info.command:match("node_modules/.bin/biome") then - return { "biome" } - end - - return { "prettier" } -end - -return { - "stevearc/conform.nvim", - opts = { - formatters_by_ft = { - ["javascript"] = use_biome_if_installed_locally, - ["javascriptreact"] = use_biome_if_installed_locally, - ["typescript"] = use_biome_if_installed_locally, - ["typescriptreact"] = use_biome_if_installed_locally, - ["graphql"] = use_biome_if_installed_locally, - ["css"] = { "prettier" }, - ["scss"] = { "prettier" }, - ["html"] = { "prettier" }, - ["json"] = { "prettier" }, - ["jsonc"] = { "prettier" }, - ["yaml"] = { "prettier" }, - ["markdown.mdx"] = { "prettier" }, - ["lua"] = { "stylua" }, - ["markdown"] = function() - if not f.isMac() == 1 then - return { "prettier" } - end - return {} - end, - }, - format_on_save = { - lsp_format = "fallback", - timeout = 500, - }, - }, - config = function(_, opts) - local conform = require("conform") - vim.api.nvim_create_user_command("SaveWithoutFormat", function() - -- disable conform plugin for formatting on save - conform.setup({ format_on_save = false }) - - -- saving - vim.api.nvim_command("update") - - -- enabling conform plugin, not sure if it retrieves the original config in plugins/confom.lua - require("conform").setup({ format_on_save = true }) - end, { desc = "Save file without formatting" }) - - conform.setup(opts) - end, -} diff --git a/lua/plugins/copilot.lua b/lua/plugins/copilot.lua deleted file mode 100644 index 5a8d1f0..0000000 --- a/lua/plugins/copilot.lua +++ /dev/null @@ -1,21 +0,0 @@ -local f = require("plugins.common.utils") -return { - { - "zbirenbaum/copilot.lua", - cmd = "Copilot", - event = "InsertEnter", - enabled = f.isMac(), - opts = { - copilot_node_command = vim.fn.expand("$VOLTA_HOME") .. "/tools/image/node/22.21.0/bin/node", - suggestion = { - auto_trigger = true, - keymap = { - accept = "", - }, - }, - }, - config = function(_, opts) - require("copilot").setup(opts) - end, - }, -} diff --git a/lua/plugins/cutlass.lua b/lua/plugins/cutlass.lua deleted file mode 100644 index 9230f35..0000000 --- a/lua/plugins/cutlass.lua +++ /dev/null @@ -1,9 +0,0 @@ --- Cutlass overrides the delete operations c, C, s, S, d, D, x, X. --- to actually just delete and not affect the current yank -return { - "gbprod/cutlass.nvim", - opts = { - cut_key = "x", - override_del = true, - }, -} diff --git a/lua/plugins/definition-or-references.lua b/lua/plugins/definition-or-references.lua deleted file mode 100644 index 59b43d9..0000000 --- a/lua/plugins/definition-or-references.lua +++ /dev/null @@ -1,23 +0,0 @@ -return { - "KostkaBrukowa/definition-or-references.nvim", - config = function() - require("definition-or-references").setup({ - on_references_result = function() - Snacks.picker.lsp_references() - end, - }) - vim.keymap.set("n", "gd", require("definition-or-references").definition_or_references, { silent = true }) - vim.keymap.set( - "n", - "gs", - ':vs lua require("definition-or-references").definition_or_references()', - { silent = true } - ) - vim.keymap.set( - "n", - "gt", - 'tab split | lua require("definition-or-references").definition_or_references()', - { silent = true } - ) - end, -} diff --git a/lua/plugins/gitsigns.lua b/lua/plugins/gitsigns.lua deleted file mode 100644 index 7509839..0000000 --- a/lua/plugins/gitsigns.lua +++ /dev/null @@ -1,36 +0,0 @@ -return { - "lewis6991/gitsigns.nvim", - event = { "BufReadPre", "BufNewFile" }, - config = function() - local gitsigns = require("gitsigns") - local opts = { - current_line_blame = true, - current_line_blame_opts = { - delay = 300, - }, - current_line_blame_formatter = " , - ", - signs = { - delete = { text = "" }, - topdelete = { text = "" }, - }, - signs_staged = { - delete = { text = "" }, - topdelete = { text = "" }, - }, - on_attach = function(bufnr) - vim.keymap.set("n", "", function() - gitsigns.nav_hunk("prev") - end, { buffer = bufnr }) - vim.keymap.set("n", "", function() - gitsigns.nav_hunk("next") - end, { buffer = bufnr }) - vim.keymap.set("n", "gi", gitsigns.preview_hunk) - vim.keymap.set("n", "gu", gitsigns.reset_hunk) - vim.keymap.set("n", "gs", gitsigns.stage_hunk) - end, - } - - gitsigns.setup(opts) - require("scrollbar.handlers.gitsigns").setup() - end, -} diff --git a/lua/plugins/harpoon.lua b/lua/plugins/harpoon.lua deleted file mode 100644 index a917fbb..0000000 --- a/lua/plugins/harpoon.lua +++ /dev/null @@ -1,52 +0,0 @@ -return { - "ThePrimeagen/harpoon", - branch = "harpoon2", - dependencies = { "nvim-lua/plenary.nvim" }, - config = function() - local harpoon = require("harpoon") - local harpoon_extensions = require("harpoon.extensions") - harpoon.setup() - harpoon:extend(harpoon_extensions.builtins.highlight_current_file()) - - vim.keymap.set("n", "A", function() - harpoon:list():prepend() - vim.cmd(":do User") - end) - vim.keymap.set("n", "a", function() - harpoon:list():add() - vim.cmd(":do User") - end) - vim.keymap.set("n", "tt", function() - harpoon.ui:toggle_quick_menu(harpoon:list()) - end) - - vim.keymap.set("n", "h", function() - harpoon:list():select(1) - end) - vim.keymap.set("n", "j", function() - harpoon:list():select(2) - end) - vim.keymap.set("n", "k", function() - harpoon:list():select(3) - end) - vim.keymap.set("n", "l", function() - harpoon:list():select(4) - end) - vim.keymap.set("n", "H", function() - vim.cmd("vsplit") - harpoon:list():select(1) - end) - vim.keymap.set("n", "J", function() - vim.cmd("vsplit") - harpoon:list():select(2) - end) - vim.keymap.set("n", "K", function() - vim.cmd("vsplit") - harpoon:list():select(3) - end) - vim.keymap.set("n", "L", function() - vim.cmd("vsplit") - harpoon:list():select(4) - end) - end, -} diff --git a/lua/plugins/init.lua b/lua/plugins/init.lua deleted file mode 100644 index a564707..0000000 --- a/lua/plugins/init.lua +++ /dev/null @@ -1 +0,0 @@ -return {} diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua deleted file mode 100644 index b4e1971..0000000 --- a/lua/plugins/lsp.lua +++ /dev/null @@ -1,48 +0,0 @@ -return { - { - "WhoIsSethDaniel/mason-tool-installer.nvim", - dependencies = { - { "mason-org/mason.nvim", opts = {} }, - { "mason-org/mason-lspconfig.nvim", opts = {}, lazy = false }, - }, - opts = { - ensure_installed = { - "tailwindcss", - "jsonls", - "emmet_language_server", - "cssls", - { "eslint", version = "4.8.0" }, -- latest version throwing error when no config file is found - "lua_ls", - "tsgo", - "prettier", - "stylua", - { - "gopls", - condition = function() - return vim.fn.executable("go") == 1 -- Install only if Go is in the path - end, - }, - }, - }, - }, - { - "L3MON4D3/LuaSnip", - dependencies = { - "rafamadriz/friendly-snippets", - }, - event = "InsertEnter", - config = function() - require("luasnip.loaders.from_vscode").lazy_load() - end, - }, - { - "neovim/nvim-lspconfig", - cmd = { "LspInfo", "LspInstall", "LspStart" }, - event = { "BufReadPre", "BufNewFile" }, - dependencies = { - { "saghen/blink.cmp" }, - { "mason-org/mason-lspconfig.nvim" }, - { "j-hui/fidget.nvim", opts = {} }, - }, - }, -} diff --git a/lua/plugins/lualine.lua b/lua/plugins/lualine.lua deleted file mode 100644 index c2d131c..0000000 --- a/lua/plugins/lualine.lua +++ /dev/null @@ -1,61 +0,0 @@ -local f = require("plugins.common.utils") - -local custom_tabs = { - { - "tabs", - show_modified_status = false, - }, -} - -local custom_filename = { - { "filename", path = 1, symbols = { - modified = f.diagnosticIcons.modified, - } }, -} - -return { - "nvim-lualine/lualine.nvim", - dependencies = { - { "nvim-tree/nvim-web-devicons" }, - }, - opts = { - options = { - always_show_tabline = false, - }, - sections = { - lualine_a = { - function() - -- Get the current working directory - local cwd = vim.fn.getcwd() - - -- Extract the last folder from the path - return "󰉋 " .. vim.fn.fnamemodify(cwd, ":t") - end, - }, - lualine_b = {}, - lualine_c = custom_filename, - lualine_x = { - { - "diagnostics", - symbols = { - error = f.diagnosticIcons.ERROR, - warn = f.diagnosticIcons.WARN, - info = f.diagnosticIcons.INFO, - hint = f.diagnosticIcons.HINT, - }, - }, - "filetype", - }, - lualine_y = f.isMac() and {} or { "branch" }, - lualine_z = custom_tabs, - }, - inactive_sections = { - lualine_c = custom_filename, - lualine_x = {}, - lualine_z = custom_tabs, - }, - extensions = { - "neo-tree", - }, - }, -} diff --git a/lua/plugins/markdown-preview.lua b/lua/plugins/markdown-preview.lua deleted file mode 100644 index 06de3e3..0000000 --- a/lua/plugins/markdown-preview.lua +++ /dev/null @@ -1,12 +0,0 @@ -return { - "selimacerbas/markdown-preview.nvim", - dependencies = { "selimacerbas/live-server.nvim" }, - config = function() - require("markdown_preview").setup({ - -- all optional; sane defaults shown - port = 8421, - open_browser = true, - debounce_ms = 300, - }) - end, -} diff --git a/lua/plugins/multicursor.lua b/lua/plugins/multicursor.lua deleted file mode 100644 index c824d09..0000000 --- a/lua/plugins/multicursor.lua +++ /dev/null @@ -1,39 +0,0 @@ -local f = require("plugins.common.utils") -return { - "jake-stewart/multicursor.nvim", - branch = "1.0", - event = "VeryLazy", - config = function() - local mc = require("multicursor-nvim") - - mc.setup() - - -- Add cursors above/below the main cursor. - vim.keymap.set({ "n", "v" }, f.isMac() and "" or "", function() - mc.addCursor("k") - end) - vim.keymap.set({ "n", "v" }, f.isMac() and "" or "", function() - mc.addCursor("j") - end) - - -- Add a cursor and jump to the next word under cursor. - vim.keymap.set({ "n", "v" }, f.isMac() and "" or "", function() - mc.addCursor("*") - end) - - -- Add and remove cursors with alt + left click. - vim.keymap.set("n", "", mc.handleMouse) - - vim.keymap.set("n", "", function() - if not mc.cursorsEnabled() then - mc.enableCursors() - elseif mc.hasCursors() then - mc.clearCursors() - else - -- Default handler. - vim.cmd("nohlsearch") -- Clear highlighting on pressing Escape - vim.cmd("echo ''") -- clear the statusbar - end - end) - end, -} diff --git a/lua/plugins/neo-tree.lua b/lua/plugins/neo-tree.lua deleted file mode 100644 index 18b80e6..0000000 --- a/lua/plugins/neo-tree.lua +++ /dev/null @@ -1,115 +0,0 @@ -local f = require("plugins.common.utils") -local function on_move(data) - Snacks.rename.on_rename_file(data.source, data.destination) -end -return { - "nvim-neo-tree/neo-tree.nvim", - branch = "v3.x", - event = "VeryLazy", - dependencies = { - "nvim-lua/plenary.nvim", - "nvim-tree/nvim-web-devicons", -- not strictly required, but recommended - "MunifTanjim/nui.nvim", - "ThePrimeagen/harpoon", - }, - config = function() - vim.keymap.set( - "n", - f.isMac() and "" or "", - "Neotree toggle", - { desc = "Toggle file explorer on current file" } - ) - local events = require("neo-tree.events") - require("neo-tree").setup({ - commands = { - add_to_harpoon = function(state) - local node = state.tree:get_node() - local filepath = node:get_id() - local harpoon = require("harpoon") - -- Get the project root - local project_root = vim.fn.getcwd() - -- Convert the absolute path to a relative path - local relative_filepath = vim.fn.fnamemodify(filepath, ":." .. project_root) - local item = { - value = relative_filepath, - context = { - row = 1, - col = 0, - }, - } - harpoon:list():add(item) - vim.cmd(":do User") - end, - copy_path = function(state) - local node = state.tree:get_node() - local filepath = node:get_id() - local filename = node.name - local modify = vim.fn.fnamemodify - local results = { - modify(filepath, ":."), - filename, - filepath, - } - vim.ui.select({ - "1. Relative path: " .. results[1], - "2. Filename: " .. results[2], - "3. Absolute path: " .. results[3], - }, { prompt = "Choose to copy to clipboard:" }, function(choice) - if choice then - local i = tonumber(choice:sub(1, 1)) - if i then - local result = results[i] - vim.fn.setreg('"', result) - vim.fn.setreg("+", result) - vim.notify("Copied: " .. result) - else - vim.notify("Invalid selection") - end - else - vim.notify("Selection cancelled") - end - end) - end, - find_in_folder = function(state) - local node = state.tree:get_node() - local filepath = node:get_id() - Snacks.picker.grep({ dirs = { filepath } }) - end, - }, - window = { - width = 60, - position = "right", - mappings = { - [""] = false, - ["a"] = "add_to_harpoon", - ["y"] = "copy_path", - ["ff"] = "find_in_folder", - [""] = { "scroll_preview", config = { direction = 10 } }, - [""] = { "scroll_preview", config = { direction = -10 } }, - [""] = "close_window", - }, - }, - filesystem = { - filtered_items = { - hide_dotfiles = false, - always_show = {}, - }, - use_libuv_file_watcher = false, - follow_current_file = { - enabled = true, - leave_dirs_open = true, - }, - }, - event_handlers = { - { - event = events.FILE_MOVED, - handler = on_move, -- not working, review with updated snacks.nvim - }, - { - event = events.FILE_RENAMED, - handler = on_move, -- not working, review with updated snacks.nvim - }, - }, - }) - end, -} diff --git a/lua/plugins/nvim-surround.lua b/lua/plugins/nvim-surround.lua deleted file mode 100644 index 111a624..0000000 --- a/lua/plugins/nvim-surround.lua +++ /dev/null @@ -1,36 +0,0 @@ -return { - "kylechui/nvim-surround", - version = "*", -- Use for stability; omit to use `main` branch for the latest features - event = "VeryLazy", - config = function() - vim.keymap.set("v", "(", "(nvim-surround-visual)(lvi(", { desc = "Surround with brackets ()" }) - vim.keymap.set("v", "[", "(nvim-surround-visual)[lvi[", { desc = "Surround with square brackets []" }) - vim.keymap.set("v", "{", "(nvim-surround-visual){lvi{", { desc = "Surround with curly brackets {}" }) - vim.keymap.set("v", '"', '(nvim-surround-visual)"lvi"', { desc = 'Surround with curly brackets ""' }) - vim.keymap.set("v", "`", "(nvim-surround-visual)`lvi`", { desc = "Surround with curly brackets ``" }) - vim.keymap.set("v", "<", "(nvim-surround-visual)", { desc = "Surround with less/greater than <>" }) - -- surround selected text with input - vim.keymap.set( - "v", - "t", - "(nvim-surround-visual)t", - { desc = "Surround with anything from input, html tags" } - ) - require("nvim-surround").setup({ - surrounds = { - ["("] = { - add = { "(", ")" }, - }, - ["{"] = { - add = { "{", "}" }, - }, - ["<"] = { - add = { "<", ">" }, - }, - ["["] = { - add = { "[", "]" }, - }, - }, - }) - end, -} diff --git a/lua/plugins/scope.lua b/lua/plugins/scope.lua deleted file mode 100644 index 263d8d5..0000000 --- a/lua/plugins/scope.lua +++ /dev/null @@ -1,4 +0,0 @@ -return { - "tiagovla/scope.nvim", - config = true, -} diff --git a/lua/plugins/sessions.lua b/lua/plugins/sessions.lua deleted file mode 100644 index 7c2dc56..0000000 --- a/lua/plugins/sessions.lua +++ /dev/null @@ -1,12 +0,0 @@ -return { - "rmagatti/auto-session", - lazy = false, - dependencies = { - "tiagovla/scope.nvim", - }, - opts = { - suppressed_dirs = { "~/", "/" }, - pre_save_cmds = { "ScopeSaveState" }, - post_restore_cmds = { "ScopeLoadState" }, - }, -} diff --git a/lua/plugins/snacks.lua b/lua/plugins/snacks.lua deleted file mode 100644 index e7d54a2..0000000 --- a/lua/plugins/snacks.lua +++ /dev/null @@ -1,351 +0,0 @@ -local f = require("plugins.common.utils") -local TERMINAL_SHELL = "fish" - -local LAZYGIT_KEYMAP = f.isMac() and "" or "" - -local global_keys = { - [""] = { f.isMac() and "" or "" }, - [""] = { f.isMac() and "" or "" }, - [""] = { "list_scroll_down" }, - [""] = { "list_scroll_up" }, - ["s"] = "edit_vsplit", - ["t"] = "tab", - [""] = { - "history_forward", - mode = "i", - }, - [""] = { - "history_back", - mode = "i", - }, - [f.isMac() and "" or ""] = { "qflist", mode = { "n", "i" } }, - [""] = { "preview_scroll_down", mode = { "n", "i" } }, - [""] = { "preview_scroll_up", mode = { "n", "i" } }, - ["a"] = "add_to_harpoon", -} - -local buffer_keys = { - ["w"] = "bufdelete", - ["v"] = "list_down", - ["c"] = "list_up", -} - -return { - "folke/snacks.nvim", - priority = 1000, - lazy = false, - opts = { - image = {}, - indent = {}, - statuscolumn = { - left = { "sign", "git" }, - right = { "mark", "fold" }, - folds = { - open = true, - }, - git = { - patterns = { "GitSign" }, - }, - refresh = 100, - }, - words = { - debounce = 50, - enabled = true, - notify_jump = true, - }, - lazygit = { - config = { - editPreset = "nvim-remote", - os = { - edit = TERMINAL_SHELL - .. ' -c \'if test -z "$NVIM"; nvim -- {{filename}}; else; nvim --server "$NVIM" --remote-send "' - .. LAZYGIT_KEYMAP - .. '"; nvim --server "$NVIM" --remote {{filename}}; end\'', - - editAtLine = TERMINAL_SHELL - .. ' -c \'if test -z "$NVIM"; nvim +{{line}} -- {{filename}}; else; nvim --server "$NVIM" --remote-send "' - .. LAZYGIT_KEYMAP - .. '"; nvim --server "$NVIM" --remote {{filename}}; nvim --server "$NVIM" --remote-send ":{{line}}"; end\'', - }, - }, - win = { - height = 0.95, - width = 0.95, - keys = { - { - LAZYGIT_KEYMAP, - function() - Snacks.lazygit() - end, - mode = "t", - }, - }, - }, - }, - terminal = { - win = { - height = 0.95, - width = 0.95, - border = "rounded", - }, - }, - picker = { - actions = { - add_to_harpoon = function(picker) - local harpoon = require("harpoon") - local full_path = picker:current() - local cwd_path = picker:cwd() - - local item = { - value = full_path.file:gsub("^" .. vim.pesc(cwd_path) .. "/", ""), - context = { - row = 1, - col = 0, - }, - } - harpoon:list():add(item) - - vim.api.nvim_exec_autocmds("User", { - pattern = "HarpoonRefresh", -- Use a specific pattern for better targeting - }) - end, - }, - previewers = { - git = { - builtin = false, - }, - }, - formatters = { - filename = { - filename_first = true, - truncate = 80, - }, - file = { - filename_first = true, - truncate = 80, - }, - }, - win = { - input = { - keys = global_keys, - }, - list = { - keys = global_keys, - }, - }, - sources = { - git_log_line = { - focus = "list", - layout = { - preset = "vertical", - }, - }, - git_log_file = { - focus = "list", - layout = { - preset = "vertical", - }, - }, - buffers = { - focus = "list", - layout = { - preset = "vertical", - }, - win = { - input = { - keys = buffer_keys, - }, - list = { - keys = buffer_keys, - }, - }, - preview = function(ctx) - local previewers = require("snacks.picker.preview") - previewers.file(ctx) - - local path = require("snacks.picker.util").path(ctx.item) - if path then - local relative_path = require("snacks.picker.util").truncpath(path, 999) - ctx.preview:set_title(relative_path) - end - end, - }, - grep = { - args = { - "--hidden", - "-i", - }, - format = "filename", - }, - grep_word = { - format = "filename", - }, - files = { - cmd = "rg", - args = { - "--files", -- Search for files - "--hidden", -- Include hidden files and directories - "--iglob", - "!.git", -- Exclude the .git directory - }, - }, - select = { - focus = "list", - }, - lsp_references = { - focus = "list", - format = "filename", - }, - lsp_implementations = { - focus = "list", - format = "filename", - }, - }, - }, - }, - keys = { - { - LAZYGIT_KEYMAP, - function() - Snacks.lazygit() - end, - mode = "n", - desc = "Open Lazygit", - }, - { - f.isMac() and "" or "", - function() - Snacks.terminal(TERMINAL_SHELL) - end, - desc = "Open Terminal", - }, - { - f.isMac() and "" or "", - function() - Snacks.terminal.toggle(TERMINAL_SHELL) - end, - mode = "t", - desc = "Toggle Terminal when opened", - }, - { - "", - function() - Snacks.words.jump(1, true) - end, - desc = "Next occurence", - }, - { - "", - function() - Snacks.words.jump(-1, true) - end, - desc = "Prev occurence", - }, - { - "v", - function() - Snacks.picker.buffers({ - on_show = function(picker) - -- start in the next buffer - picker:action("list_down") - end, - }) - end, - }, - { - "p", - function() - Snacks.picker.files() - end, - }, - { - "ff", - function() - Snacks.picker.grep() - end, - mode = "n", - }, - { - "ff", - function() - Snacks.picker.grep_word({ - focus = "list", - live = true, - }) - end, - mode = "v", - }, - { - "fr", - function() - Snacks.picker.resume() - end, - }, - { - "fg", - function() - Snacks.picker.git_log_line() - end, - }, - { - "fG", - function() - Snacks.picker.git_log_file() - end, - }, - { - "fl", - function() - Snacks.picker.git_status({ focus = "list" }) - end, - }, - { - "gr", - function() - Snacks.picker.lsp_references() - end, - nowait = true, - }, - { - "gi", - function() - Snacks.picker.lsp_implementations() - end, - nowait = true, - }, - }, - config = function(_, opts) - local custom_default = require("snacks.picker.config.layouts").default - custom_default.layout.width = 0.95 - custom_default.layout.height = 0.9 - custom_default.layout[2].min_width = 85 - custom_default.layout[2].width = 85 - - local custom_vertical = require("snacks.picker.config.layouts").vertical - custom_vertical.layout.height = 0.95 - custom_vertical.layout.backdrop = true - custom_vertical.layout.width = 0.8 - custom_vertical.layout[3].height = 0.8 - - -- change the style of the path in all pickers - f.HighlightGroups.register(function() - vim.api.nvim_set_hl(0, "SnacksPickerDir", vim.api.nvim_get_hl(0, { name = "Comment", link = false })) - end) - - vim.api.nvim_create_user_command("CloseOtherBuffers", function() - Snacks.bufdelete.other() - end, { desc = "Close all other buffers" }) - - vim.api.nvim_create_user_command("SnacksPickers", function() - Snacks.picker() - end, { desc = "Show all Snacks pickers" }) - - vim.api.nvim_create_user_command("SymbolsPicker", function() - Snacks.picker.lsp_symbols({ - focus = "list", - }) - end, { desc = "Show Symbols for this file (Snack picker)" }) - - require("snacks").setup(opts) - end, -} diff --git a/lua/plugins/treesitter.lua b/lua/plugins/treesitter.lua deleted file mode 100644 index 7d393f2..0000000 --- a/lua/plugins/treesitter.lua +++ /dev/null @@ -1,48 +0,0 @@ --- in WSL nvim > 0.11.0 breaks treesitter main, check after 0.11.5 --- also takes too long to quit -return { - "nvim-treesitter/nvim-treesitter", - build = ":TSUpdate", - opts = { - ensure_installed = { - "bash", - "css", - "go", - "graphql", - "html", - "javascript", - "jsdoc", - "json", - "json5", - "lua", - "markdown", - "regex", - "scss", - "sql", - "terraform", - "toml", - "tsx", - "typescript", - "vue", - "yaml", - }, - }, - config = function(_, opts) - require("nvim-treesitter").setup() - require("nvim-treesitter").install(opts.ensure_installed) - - vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" - vim.treesitter.language.register("markdown", { "mdx" }) - - vim.api.nvim_create_autocmd("FileType", { - group = vim.api.nvim_create_augroup("EnableTreesitterHighlighting", { clear = true }), - desc = "Try to enable tree-sitter syntax highlighting", - pattern = "*", -- run on *all* filetypes - callback = function() - pcall(function() - vim.treesitter.start() - end) - end, - }) - end, -} diff --git a/lua/plugins/vim-scrollbar.lua b/lua/plugins/vim-scrollbar.lua deleted file mode 100644 index 450f687..0000000 --- a/lua/plugins/vim-scrollbar.lua +++ /dev/null @@ -1,35 +0,0 @@ -local f = require("plugins.common.utils") - -return { - "petertriho/nvim-scrollbar", - dependencies = { - { - "kevinhwang91/nvim-hlslens", - event = "VeryLazy", - config = function() - require("scrollbar.handlers.search").setup({ - override_lens = function() - return "" - end, - }) - end, - }, - "lewis6991/gitsigns.nvim", - }, - opts = { - handlers = { - handle = false, - }, - marks = { - Error = { text = { f.diagnosticIcons.ERROR, f.diagnosticIcons.ERROR } }, - Warn = { text = { f.diagnosticIcons.WARN, f.diagnosticIcons.WARN } }, - Info = { text = { f.diagnosticIcons.INFO, f.diagnosticIcons.INFO } }, - Hint = { text = { f.diagnosticIcons.HINT, f.diagnosticIcons.HINT } }, - GitDelete = { text = "" }, - }, - excluded_filetypes = { - "neo-tree", - "neo-tree-popup", - }, - }, -} diff --git a/lua/plugins/wildfire.lua b/lua/plugins/wildfire.lua deleted file mode 100644 index 4a449b5..0000000 --- a/lua/plugins/wildfire.lua +++ /dev/null @@ -1,15 +0,0 @@ -local f = require("plugins.common.utils") -return { - "sustech-data/wildfire.nvim", - event = "VeryLazy", - dependencies = { - "nvim-treesitter/nvim-treesitter", - }, - opts = { - keymaps = { - init_selection = "", - node_incremental = "", - node_decremental = f.isMac() and "" or "⊘", -- strange unicode mapped in windows because it cant understand shift+enter - }, - }, -} diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json new file mode 100644 index 0000000..005270b --- /dev/null +++ b/nvim-pack-lock.json @@ -0,0 +1,145 @@ +{ + "plugins": { + "LuaSnip": { + "rev": "642b0c595e11608b4c18219e93b88d7637af27bc", + "src": "https://github.com/L3MON4D3/LuaSnip", + "version": "'v2.5.0'" + }, + "auto-dark-mode.nvim": { + "rev": "54058b4fe414bd64bd2904a6f8a63f1f14e3d8df", + "src": "https://github.com/f-person/auto-dark-mode.nvim" + }, + "auto-session": { + "rev": "482d2bdd144e73e5060ce728ac46463684cc9d28", + "src": "https://github.com/rmagatti/auto-session" + }, + "barbar.nvim": { + "rev": "a4bef5b4fc1f064f2f673172252028eae18191c9", + "src": "https://github.com/romgrk/barbar.nvim" + }, + "blink.cmp": { + "rev": "78336bc89ee5365633bcf754d93df01678b5c08f", + "src": "https://github.com/saghen/blink.cmp" + }, + "codediff.nvim": { + "rev": "8afc229d38dc13ce71b2ffbb860084b2c726e061", + "src": "https://github.com/esmuellert/codediff.nvim" + }, + "conform.nvim": { + "rev": "dca1a190aa85f9065979ef35802fb77131911106", + "src": "https://github.com/stevearc/conform.nvim" + }, + "cutlass.nvim": { + "rev": "d01b5c1943050fcda8edf5c89d4419c41a65890e", + "src": "https://github.com/gbprod/cutlass.nvim" + }, + "definition-or-references.nvim": { + "rev": "7318f9479d2db357d2908599c3ec14bec7c589dd", + "src": "https://github.com/KostkaBrukowa/definition-or-references.nvim" + }, + "fidget.nvim": { + "rev": "889e2e96edef4e144965571d46f7a77bcc4d0ddf", + "src": "https://github.com/j-hui/fidget.nvim" + }, + "friendly-snippets": { + "rev": "6cd7280adead7f586db6fccbd15d2cac7e2188b9", + "src": "https://github.com/rafamadriz/friendly-snippets" + }, + "gitsigns.nvim": { + "rev": "dd3f588bacbeb041be6facf1742e42097f62165d", + "src": "https://github.com/lewis6991/gitsigns.nvim" + }, + "live-server.nvim": { + "rev": "084d69b63610803c18ddd7541294d83ca748d1dc", + "src": "https://github.com/selimacerbas/live-server.nvim" + }, + "lualine.nvim": { + "rev": "131a558e13f9f28b15cd235557150ccb23f89286", + "src": "https://github.com/nvim-lualine/lualine.nvim" + }, + "markdown-preview.nvim": { + "rev": "29234edae5b8b7db5ae05061ff7197f95ef0ffd5", + "src": "https://github.com/selimacerbas/markdown-preview.nvim" + }, + "mason-lspconfig.nvim": { + "rev": "0c2823e0418f3d9230ff8b201c976e84de1cb401", + "src": "https://github.com/mason-org/mason-lspconfig.nvim" + }, + "mason-tool-installer.nvim": { + "rev": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc", + "src": "https://github.com/WhoIsSethDaniel/mason-tool-installer.nvim" + }, + "mason.nvim": { + "rev": "cb8445f8ce85d957416c106b780efd51c6298f89", + "src": "https://github.com/mason-org/mason.nvim" + }, + "multicursor.nvim": { + "rev": "704b99f10a72cc05d370cfeb294ff83412a8ab55", + "src": "https://github.com/jake-stewart/multicursor.nvim" + }, + "neo-tree.nvim": { + "rev": "ff84e6e1608b24773f1b73cd4182e0bcf2b3d637", + "src": "https://github.com/nvim-neo-tree/neo-tree.nvim" + }, + "nui.nvim": { + "rev": "de740991c12411b663994b2860f1a4fd0937c130", + "src": "https://github.com/MunifTanjim/nui.nvim" + }, + "nvim-autopairs": { + "rev": "59bce2eef357189c3305e25bc6dd2d138c1683f5", + "src": "https://github.com/windwp/nvim-autopairs" + }, + "nvim-highlight-colors": { + "rev": "e2cb22089cc2358b2b995c09578224f142de6039", + "src": "https://github.com/brenoprata10/nvim-highlight-colors" + }, + "nvim-hlslens": { + "rev": "be2d7b2be01860b5445a007ff2bc72b29896db6b", + "src": "https://github.com/kevinhwang91/nvim-hlslens" + }, + "nvim-lspconfig": { + "rev": "31026a13eefb20681124706a79fc1df6bf11ab27", + "src": "https://github.com/neovim/nvim-lspconfig" + }, + "nvim-scrollbar": { + "rev": "f8e87b96cd6362ef8579be456afee3b38fd7e2a8", + "src": "https://github.com/petertriho/nvim-scrollbar" + }, + "nvim-surround": { + "rev": "2e93e154de9ff326def6480a4358bfc149d5da2c", + "src": "https://github.com/kylechui/nvim-surround" + }, + "nvim-treesitter": { + "rev": "4916d6592ede8c07973490d9322f187e07dfefac", + "src": "https://github.com/nvim-treesitter/nvim-treesitter" + }, + "nvim-web-devicons": { + "rev": "4fc505ac7bd7692824a142e96e5f529c133862f8", + "src": "https://github.com/nvim-tree/nvim-web-devicons" + }, + "onedarkpro.nvim": { + "rev": "f5fddfd5122fe00421e199151ae4fe8571a02898", + "src": "https://github.com/olimorris/onedarkpro.nvim" + }, + "plenary.nvim": { + "rev": "74b06c6c75e4eeb3108ec01852001636d85a932b", + "src": "https://github.com/nvim-lua/plenary.nvim" + }, + "scope.nvim": { + "rev": "228aabdb1b9cc74f0c0ccec88e79873857236e49", + "src": "https://github.com/tiagovla/scope.nvim" + }, + "snacks.nvim": { + "rev": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e", + "src": "https://github.com/folke/snacks.nvim" + }, + "ts-comments.nvim": { + "rev": "123a9fb12e7229342f807ec9e6de478b1102b041", + "src": "https://github.com/folke/ts-comments.nvim" + }, + "wildfire.nvim": { + "rev": "918a1873c2b8010baa034f373cf28c53ce4f038f", + "src": "https://github.com/sustech-data/wildfire.nvim" + } + } +} diff --git a/plugin/00-colorscheme.lua b/plugin/00-colorscheme.lua new file mode 100644 index 0000000..ad9724b --- /dev/null +++ b/plugin/00-colorscheme.lua @@ -0,0 +1,25 @@ +local f = require("common.utils") + +vim.pack.add({ "https://github.com/f-person/auto-dark-mode.nvim" }) +require("auto-dark-mode").setup({}) + +vim.pack.add({ "https://github.com/olimorris/onedarkpro.nvim" }) +require("onedarkpro").setup({ + styles = { + functions = "bold", + }, + highlights = { + LspReferenceText = { link = "CursorColumn", extend = true }, + NeoTreeCursorLine = { bg = "${cursorline}", bold = true }, + NeominimapCursorLine = { bg = "${gray}", bold = true }, + }, +}) +vim.cmd.colorscheme("onedark_vivid") + +vim.api.nvim_create_autocmd("OptionSet", { + pattern = "background", + callback = function(_) + vim.cmd.colorscheme(vim.o.background == "light" and "onelight" or "onedark_vivid") + f.HighlightGroups.executeAll() + end, +}) \ No newline at end of file diff --git a/plugin/01-treesitter.lua b/plugin/01-treesitter.lua new file mode 100644 index 0000000..ab5d280 --- /dev/null +++ b/plugin/01-treesitter.lua @@ -0,0 +1,38 @@ +vim.pack.add({ "https://github.com/nvim-treesitter/nvim-treesitter" }) +require("nvim-treesitter").setup() +require("nvim-treesitter").install({ + "bash", + "css", + "go", + "graphql", + "html", + "javascript", + "jsdoc", + "json", + "json5", + "lua", + "markdown", + "regex", + "scss", + "sql", + "terraform", + "toml", + "tsx", + "typescript", + "vue", + "yaml", +}) + +vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" +vim.treesitter.language.register("markdown", { "mdx" }) + +vim.api.nvim_create_autocmd("FileType", { + group = vim.api.nvim_create_augroup("EnableTreesitterHighlighting", { clear = true }), + desc = "Try to enable tree-sitter syntax highlighting", + pattern = "*", + callback = function() + pcall(function() + vim.treesitter.start() + end) + end, +}) \ No newline at end of file diff --git a/plugin/02-blink.lua b/plugin/02-blink.lua new file mode 100644 index 0000000..c94e209 --- /dev/null +++ b/plugin/02-blink.lua @@ -0,0 +1,51 @@ +local f = require("common.utils") + +vim.pack.add({ + "https://github.com/rafamadriz/friendly-snippets", + { src = "https://github.com/L3MON4D3/LuaSnip", version = "v2.5.0" }, +}) + +vim.pack.add({ { src = "https://github.com/saghen/blink.cmp", version = vim.version.range("1.*") } }) +require("blink.cmp").setup({ + fuzzy = { + implementation = "lua", + }, + sources = { + default = function() + if vim.bo.filetype == "copilot-chat" then + return {} + end + return { "lsp", "path", "buffer" } + end, + }, + keymap = { + preset = "enter", + [f.isMac() and "" or "⊘"] = { "show", "hide" }, + [""] = {}, + [""] = {}, + [""] = {}, + [""] = {}, + [""] = { "scroll_documentation_up", "fallback" }, + [""] = { "scroll_documentation_down", "fallback" }, + }, + appearance = { + nerd_font_variant = "normal", + }, + signature = { + enabled = true, + }, + completion = { + menu = { + draw = { + columns = { { "kind_icon" }, { "label", "label_description", gap = 1 }, { "kind" } }, + }, + }, + documentation = { + auto_show = true, + auto_show_delay_ms = 0, + }, + }, + snippets = { + preset = "luasnip", + }, +}) diff --git a/plugin/03-lsp.lua b/plugin/03-lsp.lua new file mode 100644 index 0000000..a51be85 --- /dev/null +++ b/plugin/03-lsp.lua @@ -0,0 +1,44 @@ +vim.pack.add({ + "https://github.com/mason-org/mason.nvim", + "https://github.com/mason-org/mason-lspconfig.nvim", + "https://github.com/WhoIsSethDaniel/mason-tool-installer.nvim", +}) + +vim.cmd.packadd("mason.nvim") +require("mason").setup({}) + +vim.cmd.packadd("mason-lspconfig.nvim") +require("mason-lspconfig").setup({}) + +vim.pack.add({ "https://github.com/j-hui/fidget.nvim" }) +require("fidget").setup({}) + +local tools = { + "tailwindcss", + "jsonls", + "emmet_language_server", + "cssls", + { "eslint", version = "4.8.0" }, + "lua_ls", + "ts_ls", + "prettier", + "stylua", +} + +if vim.fn.executable("go") == 1 then + table.insert(tools, "gopls") +end + +require("mason-tool-installer").setup({ + ensure_installed = tools, +}) + +vim.pack.add({ + "https://github.com/nvim-lua/plenary.nvim", + "https://github.com/nvim-tree/nvim-web-devicons", + "https://github.com/MunifTanjim/nui.nvim", + "https://github.com/saghen/blink.cmp", + "https://github.com/neovim/nvim-lspconfig", +}) +vim.cmd.packadd("nvim-lspconfig") +vim.lsp.enable({ "lua_ls" }) diff --git a/plugin/autopairs.lua b/plugin/autopairs.lua new file mode 100644 index 0000000..826a053 --- /dev/null +++ b/plugin/autopairs.lua @@ -0,0 +1,9 @@ +vim.pack.add({ "https://github.com/windwp/nvim-autopairs" }) +local autopairs = require("nvim-autopairs") +autopairs.setup({ + check_ts = true, + ts_config = { + lua = { "string" }, + javascript = { "template_string" }, + }, +}) \ No newline at end of file diff --git a/plugin/barbar.lua b/plugin/barbar.lua new file mode 100644 index 0000000..6d727c9 --- /dev/null +++ b/plugin/barbar.lua @@ -0,0 +1,44 @@ +local f = require("common.utils") + +vim.pack.add({ "https://github.com/romgrk/barbar.nvim" }) +vim.pack.add({ "https://github.com/lewis6991/gitsigns.nvim" }) + +vim.g.barbar_auto_setup = false + +local barbar = require("barbar") +local state = require("barbar.state") +local render = require("barbar.ui.render") + +barbar.setup({ + animation = false, + tabpages = false, + icons = { + button = false, + pinned = { filename = true, buffer_index = true }, + diagnostics = { [vim.diagnostic.severity.ERROR] = { enabled = true, icon = f.diagnosticIcons.ERROR } }, + separator = { left = " " }, + }, +}) + +f.HighlightGroups.register(function() + local default_error_hl = vim.api.nvim_get_hl(0, { name = "ErrorMsg" }) + local default_buffer_hl = vim.tbl_extend("force", vim.api.nvim_get_hl(0, { name = "Directory" }), { bold = true }) + vim.api.nvim_set_hl(0, "BufferVisibleERROR", default_error_hl) + vim.api.nvim_set_hl(0, "BufferCurrentERROR", default_error_hl) + vim.api.nvim_set_hl(0, "BufferCurrent", default_buffer_hl) + vim.api.nvim_set_hl(0, "BufferCurrentMod", default_buffer_hl) + vim.api.nvim_set_hl(0, "BufferCurrentSign", default_buffer_hl) +end) + +vim.keymap.set({ "n", "v" }, "", ":BufferPrevious", { silent = true }) +vim.keymap.set({ "n", "v" }, "", ":BufferNext", { silent = true }) +vim.keymap.set("n", "<", ":BufferMovePrevious", { silent = true }) +vim.keymap.set("n", ">", ":BufferMoveNext", { silent = true }) + +local function unpin_all() + for _, buf in ipairs(state.buffers) do + local data = state.get_buffer_data(buf) + data.pinned = false + end +end + diff --git a/plugin/codediff.lua b/plugin/codediff.lua new file mode 100644 index 0000000..dcd525e --- /dev/null +++ b/plugin/codediff.lua @@ -0,0 +1,33 @@ +vim.pack.add({ + "https://github.com/esmuellert/codediff.nvim", + "https://github.com/MunifTanjim/nui.nvim", +}) +vim.keymap.set("n", "dD", "CodeDiff", { desc = "Code diff" }) +vim.keymap.set("n", "dd", function() + local base + for _, branch in ipairs({ "main", "master" }) do + vim.fn.system("git rev-parse --verify " .. branch .. " 2>/dev/null") + if vim.v.shell_error == 0 then + base = branch + break + end + end + if not base then + vim.notify("No main or master branch found", vim.log.levels.WARN) + return + end + vim.cmd("CodeDiff " .. base .. "...") +end, { desc = "Code diff vs main/master" }) +require("codediff").setup({ + explorer = { view_mode = "tree" }, + keymaps = { + view = { + next_file = "", + prev_file = "", + next_hunk = "", + prev_hunk = "", + open_in_prev_tab = "e", + close_on_open_in_prev_tab = true, + }, + }, +}) diff --git a/plugin/colorizer.lua b/plugin/colorizer.lua new file mode 100644 index 0000000..53a1687 --- /dev/null +++ b/plugin/colorizer.lua @@ -0,0 +1,2 @@ +vim.pack.add({ "https://github.com/brenoprata10/nvim-highlight-colors" }) +require("nvim-highlight-colors").setup({ enable_tailwind = true }) \ No newline at end of file diff --git a/plugin/conform.lua b/plugin/conform.lua new file mode 100644 index 0000000..bf3bd19 --- /dev/null +++ b/plugin/conform.lua @@ -0,0 +1,45 @@ +vim.pack.add({ "https://github.com/stevearc/conform.nvim" }) +vim.cmd.packadd("conform.nvim") + +local f = require("common.utils") + +local function use_biome_if_installed_locally(bufnr) + local biome_info = require("conform").get_formatter_info("biome", bufnr) + if biome_info and biome_info.available and biome_info.command:match("node_modules/.bin/biome") then + return { "biome" } + end + return { "prettier" } +end + +local conform = require("conform") + +conform.setup({ + formatters_by_ft = { + ["javascript"] = use_biome_if_installed_locally, + ["javascriptreact"] = use_biome_if_installed_locally, + ["typescript"] = use_biome_if_installed_locally, + ["typescriptreact"] = use_biome_if_installed_locally, + ["graphql"] = use_biome_if_installed_locally, + ["css"] = { "prettier" }, + ["scss"] = { "prettier" }, + ["html"] = { "prettier" }, + ["json"] = { "prettier" }, + ["jsonc"] = { "prettier" }, + ["yaml"] = { "prettier" }, + ["markdown.mdx"] = { "prettier" }, + ["lua"] = { "stylua" }, + ["markdown"] = function() + if not f.isMac() == 1 then + return { "prettier" } + end + return {} + end, + }, + format_on_save = { lsp_format = "fallback", timeout = 500 }, +}) + +vim.api.nvim_create_user_command("SaveWithoutFormat", function() + conform.setup({ format_on_save = false }) + vim.api.nvim_command("update") + conform.setup({ format_on_save = true }) +end, { desc = "Save file without formatting" }) diff --git a/plugin/cutlass.lua b/plugin/cutlass.lua new file mode 100644 index 0000000..ebe56f7 --- /dev/null +++ b/plugin/cutlass.lua @@ -0,0 +1,2 @@ +vim.pack.add({ "https://github.com/gbprod/cutlass.nvim" }) +require("cutlass").setup({ cut_key = "x", override_del = true }) \ No newline at end of file diff --git a/plugin/definition-or-references.lua b/plugin/definition-or-references.lua new file mode 100644 index 0000000..caf8ba3 --- /dev/null +++ b/plugin/definition-or-references.lua @@ -0,0 +1,14 @@ +vim.pack.add({ "https://github.com/KostkaBrukowa/definition-or-references.nvim" }) +require("definition-or-references").setup({ + on_references_result = function() + Snacks.picker.lsp_references() + end, +}) +vim.keymap.set("n", "gd", require("definition-or-references").definition_or_references, { silent = true }) +vim.keymap.set("n", "gs", ':vs lua require("definition-or-references").definition_or_references()', { silent = true }) +vim.keymap.set( + "n", + "gt", + 'tab split | lua require("definition-or-references").definition_or_references()', + { silent = true } +) \ No newline at end of file diff --git a/plugin/gitsigns.lua b/plugin/gitsigns.lua new file mode 100644 index 0000000..6a4a233 --- /dev/null +++ b/plugin/gitsigns.lua @@ -0,0 +1,56 @@ +vim.pack.add({ "https://github.com/lewis6991/gitsigns.nvim" }) +local gitsigns = require("gitsigns") +local opts = { + current_line_blame = true, + current_line_blame_opts = { delay = 300 }, + current_line_blame_formatter = " , - ", + signs = { + delete = { text = "" }, + topdelete = { text = "" }, + }, + signs_staged = { + delete = { text = "" }, + topdelete = { text = "" }, + }, + on_attach = function(bufnr) + -- Avoid setting the keymap before codediff to avoid conflict + local ok, lifecycle = pcall(require, "codediff.ui.lifecycle") + local in_codediff = ok and lifecycle.find_tabpage_by_buffer(bufnr) + if not in_codediff then + vim.keymap.set("n", "", function() + gitsigns.nav_hunk("prev") + end, { buffer = bufnr }) + vim.keymap.set("n", "", function() + gitsigns.nav_hunk("next") + end, { buffer = bufnr }) + end + vim.keymap.set("n", "gi", gitsigns.preview_hunk) + vim.keymap.set("n", "gu", gitsigns.reset_hunk) + vim.keymap.set("n", "gs", gitsigns.stage_hunk) + end, +} +gitsigns.setup(opts) + +vim.pack.add({ "https://github.com/kevinhwang91/nvim-hlslens" }) +vim.pack.add({ "https://github.com/petertriho/nvim-scrollbar" }) + +require("scrollbar.handlers.search").setup({ + override_lens = function() + return "" + end, +}) + +local f = require("common.utils") +require("scrollbar").setup({ + handlers = { handle = false }, + marks = { + Error = { text = { f.diagnosticIcons.ERROR, f.diagnosticIcons.ERROR } }, + Warn = { text = { f.diagnosticIcons.WARN, f.diagnosticIcons.WARN } }, + Info = { text = { f.diagnosticIcons.INFO, f.diagnosticIcons.INFO } }, + Hint = { text = { f.diagnosticIcons.HINT, f.diagnosticIcons.HINT } }, + GitDelete = { text = "" }, + }, + excluded_filetypes = { "neo-tree", "neo-tree-popup", "neominimap" }, +}) + +require("scrollbar.handlers.gitsigns").setup() diff --git a/plugin/lualine.lua b/plugin/lualine.lua new file mode 100644 index 0000000..c63c980 --- /dev/null +++ b/plugin/lualine.lua @@ -0,0 +1,48 @@ +local f = require("common.utils") + +vim.pack.add({ "https://github.com/nvim-lualine/lualine.nvim" }) + +local custom_tabs = { + { "tabs", show_modified_status = false }, +} + +local custom_filename = { + { "filename", path = 1, symbols = { modified = f.diagnosticIcons.modified } }, +} + +require("lualine").setup({ + options = { + always_show_tabline = false, + disabled_filetypes = { statusline = { "neominimap" } }, + }, + sections = { + lualine_a = { + function() + local cwd = vim.fn.getcwd() + return "󰉋 " .. vim.fn.fnamemodify(cwd, ":t") + end, + }, + lualine_b = {}, + lualine_c = custom_filename, + lualine_x = { + { + "diagnostics", + symbols = { + error = f.diagnosticIcons.ERROR, + warn = f.diagnosticIcons.WARN, + info = f.diagnosticIcons.INFO, + hint = f.diagnosticIcons.HINT, + }, + }, + "filetype", + }, + lualine_y = f.isMac() and {} or { "branch" }, + lualine_z = custom_tabs, + }, + inactive_sections = { + lualine_c = custom_filename, + lualine_x = {}, + lualine_z = custom_tabs, + }, + extensions = { "neo-tree" }, +}) \ No newline at end of file diff --git a/plugin/markdown-preview.lua b/plugin/markdown-preview.lua new file mode 100644 index 0000000..9326eb5 --- /dev/null +++ b/plugin/markdown-preview.lua @@ -0,0 +1,9 @@ +vim.pack.add({ + "https://github.com/selimacerbas/markdown-preview.nvim", + "https://github.com/selimacerbas/live-server.nvim", +}) +require("markdown_preview").setup({ + port = 8421, + open_browser = true, + debounce_ms = 300, +}) \ No newline at end of file diff --git a/plugin/multicursor.lua b/plugin/multicursor.lua new file mode 100644 index 0000000..42e028a --- /dev/null +++ b/plugin/multicursor.lua @@ -0,0 +1,27 @@ +local f = require("common.utils") + +vim.pack.add({ "https://github.com/jake-stewart/multicursor.nvim" }) +local mc = require("multicursor-nvim") +mc.setup() + +vim.keymap.set({ "n", "v" }, f.isMac() and "" or "", function() + mc.addCursor("k") +end) +vim.keymap.set({ "n", "v" }, f.isMac() and "" or "", function() + mc.addCursor("j") +end) +vim.keymap.set({ "n", "v" }, f.isMac() and "" or "", function() + mc.addCursor("*") +end) +vim.keymap.set("n", "", mc.handleMouse) + +vim.keymap.set("n", "", function() + if not mc.cursorsEnabled() then + mc.enableCursors() + elseif mc.hasCursors() then + mc.clearCursors() + else + vim.cmd("nohlsearch") + vim.cmd("echo ''") + end +end) \ No newline at end of file diff --git a/plugin/neo-tree.lua b/plugin/neo-tree.lua new file mode 100644 index 0000000..672683b --- /dev/null +++ b/plugin/neo-tree.lua @@ -0,0 +1,72 @@ +local f = require("common.utils") +local function on_move(data) + Snacks.rename.on_rename_file(data.source, data.destination) +end + +vim.pack.add({ + "https://github.com/nvim-neo-tree/neo-tree.nvim", +}) +local events = require("neo-tree.events") +require("neo-tree").setup({ + commands = { + copy_path = function(state) + local node = state.tree:get_node() + local filepath = node:get_id() + local filename = node.name + local modify = vim.fn.fnamemodify + local results = { modify(filepath, ":."), filename, filepath } + vim.ui.select({ + "1. Relative path: " .. results[1], + "2. Filename: " .. results[2], + "3. Absolute path: " .. results[3], + }, { prompt = "Choose to copy to clipboard:" }, function(choice) + if choice then + local i = tonumber(choice:sub(1, 1)) + if i then + local result = results[i] + vim.fn.setreg('"', result) + vim.fn.setreg("+", result) + vim.notify("Copied: " .. result) + else + vim.notify("Invalid selection") + end + else + vim.notify("Selection cancelled") + end + end) + end, + find_in_folder = function(state) + local node = state.tree:get_node() + local filepath = node:get_id() + Snacks.picker.grep({ dirs = { filepath } }) + end, + }, + window = { + width = 40, + position = "right", + mappings = { + [""] = false, + ["y"] = "copy_path", + ["ff"] = "find_in_folder", + [""] = { "scroll_preview", config = { direction = 10 } }, + [""] = { "scroll_preview", config = { direction = -10 } }, + [""] = "close_window", + }, + }, + filesystem = { + filtered_items = { hide_dotfiles = false, always_show = {} }, + use_libuv_file_watcher = false, + follow_current_file = { enabled = true, leave_dirs_open = true }, + }, + event_handlers = { + { event = events.FILE_MOVED, handler = on_move }, + { event = events.FILE_RENAMED, handler = on_move }, + }, +}) + +vim.keymap.set( + "n", + f.isMac() and "" or "", + "Neotree toggle", + { desc = "Toggle file explorer on current file" } +) \ No newline at end of file diff --git a/plugin/nvim-surround.lua b/plugin/nvim-surround.lua new file mode 100644 index 0000000..58c2912 --- /dev/null +++ b/plugin/nvim-surround.lua @@ -0,0 +1,16 @@ +vim.pack.add({ "https://github.com/kylechui/nvim-surround" }) +vim.keymap.set("v", "(", "(nvim-surround-visual)(lvi(", { desc = "Surround with brackets ()" }) +vim.keymap.set("v", "[", "(nvim-surround-visual)[lvi[", { desc = "Surround with square brackets []" }) +vim.keymap.set("v", "{", "(nvim-surround-visual){lvi{", { desc = "Surround with curly brackets {}" }) +vim.keymap.set("v", '"', '(nvim-surround-visual)"lvi"', { desc = 'Surround with curly brackets ""' }) +vim.keymap.set("v", "`", "(nvim-surround-visual)`lvi`", { desc = "Surround with curly brackets ``" }) +vim.keymap.set("v", "<", "(nvim-surround-visual)", { desc = "Surround with less/greater than <>" }) +vim.keymap.set("v", "t", "(nvim-surround-visual)t", { desc = "Surround with anything from input, html tags" }) +require("nvim-surround").setup({ + surrounds = { + ["("] = { add = { "(", ")" } }, + ["{"] = { add = { "{", "}" } }, + ["<"] = { add = { "<", ">" } }, + ["["] = { add = { "[", "]" } }, + }, +}) \ No newline at end of file diff --git a/plugin/pack.lua b/plugin/pack.lua new file mode 100644 index 0000000..74e6ed1 --- /dev/null +++ b/plugin/pack.lua @@ -0,0 +1,521 @@ +-- +-- Minimalistic vim.pack UI +-- +-- Provides :Pack command that opens a floating window dashboard +-- for managing plugins (update, clean, log, inspect). +-- + +local api = vim.api +local ns = api.nvim_create_namespace("pack_ui") + +-- Highlight groups +local function setup_highlights() + local links = { + PackUiHeader = "Title", + PackUiButton = "Function", + PackUiPluginLoaded = "String", + PackUiPluginNotLoaded = "Comment", + PackUiPluginMissing = "ErrorMsg", + PackUiVersion = "Number", + PackUiSectionHeader = "Label", + PackUiSeparator = "FloatBorder", + PackUiDetail = "Comment", + PackUiHelp = "SpecialComment", + } + for group, target in pairs(links) do + api.nvim_set_hl(0, group, { link = target, default = true }) + end +end + +-- State +local state = { + bufnr = nil, + winid = nil, + win_autocmd_id = nil, -- WinClosed autocmd ID + line_to_plugin = {}, -- line number (1-based) => plugin name + plugin_lines = {}, -- plugin name => line number (1-based) + expanded = {}, -- plugin name => bool + show_help = false, +} + +-- Cache of path => installed git tag (false = no tag found) +local tag_cache = {} + +-- For versioned plugins, return the actual installed tag from git. +-- Results are cached for the session so git is only called once per plugin. +local function get_installed_tag(path) + if not path then + return nil + end + if tag_cache[path] ~= nil then + return tag_cache[path] or nil + end + local result = + vim.fn.system("git -C " .. vim.fn.shellescape(path) .. " describe --tags --exact-match HEAD 2>/dev/null") + if vim.v.shell_error == 0 then + local tag = vim.trim(result) + tag_cache[path] = tag + return tag + end + tag_cache[path] = false + return nil +end + +-- Get version string from plugin spec +local function get_version_str(p) + local v = p.spec.version + if v == nil then + return "" + end + if type(v) == "string" then + return v + end + return tostring(v) +end + +-- Build lines and highlights for the buffer +local function build_content() + local plugins = vim.pack.get(nil, { info = false }) + + local loaded = {} + local not_loaded = {} + for _, p in ipairs(plugins) do + if p.active then + table.insert(loaded, p) + else + table.insert(not_loaded, p) + end + end + + table.sort(loaded, function(a, b) + return a.spec.name < b.spec.name + end) + table.sort(not_loaded, function(a, b) + return a.spec.name < b.spec.name + end) + + local lines = {} + local hls = {} -- { line, col_start, col_end, hl_group } + local line_to_plugin = {} + local plugin_lines = {} + + local function add(text, hl) + local lnum = #lines + lines[#lines + 1] = text + if hl then + table.insert(hls, { lnum, 0, #text, hl }) + end + end + + local function add_hl(lnum, col_start, col_end, hl) + table.insert(hls, { lnum, col_start, col_end, hl }) + end + + -- Header + local header = string.format(" vim.pack -- %d plugins | %d loaded", #plugins, #loaded) + add(header, "PackUiHeader") + + -- Separator (fill the window width minus the leading space) + local win_width = state.winid and vim.api.nvim_win_get_width(state.winid) or 80 + local sep = " " .. string.rep("─", win_width - 1) + add(sep, "PackUiSeparator") + + -- Action bar + local bar = " [U]pdate All [u] Update [R]estore [X] Clean [D]elete [L] Log [?] Help" + add(bar) + -- Highlight the bracket keys (gmatch () captures are 1-based; + -- the end capture points one past the match, which is exactly + -- the exclusive end_col that extmarks expect) + local lnum = #lines - 1 + for s, e in bar:gmatch("()%[.-%]()") do + add_hl(lnum, s - 1, e - 1, "PackUiButton") + end + + -- Help section (toggled) + if state.show_help then + add("") + add(" Keymaps:", "PackUiHelp") + add(" U Update all plugins", "PackUiHelp") + add(" u Update plugin under cursor", "PackUiHelp") + add(" R Restore plugins to lockfile versions", "PackUiHelp") + add(" X Clean non-active plugins", "PackUiHelp") + add(" D Delete plugin under cursor (non-active only)", "PackUiHelp") + add(" L Open update log file", "PackUiHelp") + add(" Toggle plugin details", "PackUiHelp") + add(" ]] Jump to next plugin", "PackUiHelp") + add(" [[ Jump to previous plugin", "PackUiHelp") + add(" q/Esc Close window", "PackUiHelp") + end + + -- Compute max name width for alignment + local max_name = 0 + for _, p in ipairs(plugins) do + max_name = math.max(max_name, #p.spec.name) + end + + -- Render a plugin line + -- Format: ' %s %s%s%s' => 3 spaces, icon, 1 space, name, pad, version + -- Byte offsets: icon starts at 3, name starts at 3 + #icon_bytes + 1 + local function render_plugin(p, icon, hl_group) + local name = p.spec.name + local pad = string.rep(" ", max_name - #name + 2) + local version = get_version_str(p) + local tag = p.spec.version and get_installed_tag(p.path) or nil + local rev_short = p.rev and p.rev:sub(1, 7) or "" + + local ver_display = tag or (rev_short ~= "" and rev_short or version) + local line = string.format(" %s %s%s%s", icon, name, pad, ver_display) + local lnum_cur = #lines + add(line) + + -- Byte offsets for highlights + local icon_bytes = #icon + local icon_start = 3 + local name_start = icon_start + icon_bytes + 1 + + add_hl(lnum_cur, icon_start, icon_start + icon_bytes, hl_group) + add_hl(lnum_cur, name_start, name_start + #name, hl_group) + if #ver_display > 0 then + local ver_start = name_start + #name + #pad + add_hl(lnum_cur, ver_start, ver_start + #ver_display, "PackUiVersion") + end + + -- Track plugin position (1-based line number for cursor operations) + line_to_plugin[lnum_cur + 1] = name + plugin_lines[name] = lnum_cur + 1 + + -- Expanded details + if state.expanded[name] then + local details = { + string.format(" Path: %s", p.path), + string.format(" Source: %s", p.spec.src), + } + if p.rev then + table.insert(details, string.format(" Rev: %s", p.rev)) + end + for _, d in ipairs(details) do + add(d, "PackUiDetail") + end + end + end + + -- Loaded section + add("") + add(string.format(" Loaded (%d)", #loaded), "PackUiSectionHeader") + for _, p in ipairs(loaded) do + render_plugin(p, "●", "PackUiPluginLoaded") + end + + -- Not Loaded section + if #not_loaded > 0 then + add("") + add(string.format(" Not Loaded (%d)", #not_loaded), "PackUiSectionHeader") + for _, p in ipairs(not_loaded) do + render_plugin(p, "○", "PackUiPluginNotLoaded") + end + end + + state.line_to_plugin = line_to_plugin + state.plugin_lines = plugin_lines + + return lines, hls +end + +-- Render content into the buffer +local function render() + if not state.bufnr or not api.nvim_buf_is_valid(state.bufnr) then + return + end + + local lines, hls = build_content() + + vim.bo[state.bufnr].modifiable = true + api.nvim_buf_set_lines(state.bufnr, 0, -1, false, lines) + vim.bo[state.bufnr].modifiable = false + vim.bo[state.bufnr].modified = false + + -- Apply highlights + api.nvim_buf_clear_namespace(state.bufnr, ns, 0, -1) + for _, hl in ipairs(hls) do + api.nvim_buf_set_extmark(state.bufnr, ns, hl[1], hl[2], { + end_col = hl[3], + hl_group = hl[4], + }) + end +end + +-- Get plugin name at cursor +local function plugin_at_cursor() + if not state.winid or not api.nvim_win_is_valid(state.winid) then + return nil + end + local row = api.nvim_win_get_cursor(state.winid)[1] + return state.line_to_plugin[row] +end + +-- Close the floating window +local function close() + -- Remove autocmd first to prevent it from corrupting state on re-open + if state.win_autocmd_id then + pcall(api.nvim_del_autocmd, state.win_autocmd_id) + state.win_autocmd_id = nil + end + if state.winid and api.nvim_win_is_valid(state.winid) then + api.nvim_win_close(state.winid, true) + end + -- Buffer has bufhidden=wipe, so it is wiped when the window closes. + -- No need to explicitly delete it. + state.winid = nil + state.bufnr = nil + state.expanded = {} + state.show_help = false +end + +-- Jump to next/prev plugin line +local function jump_plugin(direction) + if not state.winid or not api.nvim_win_is_valid(state.winid) then + return + end + local row = api.nvim_win_get_cursor(state.winid)[1] + + -- Collect sorted plugin line numbers + local plines = {} + for lnum, _ in pairs(state.line_to_plugin) do + table.insert(plines, lnum) + end + table.sort(plines) + + if direction > 0 then + for _, lnum in ipairs(plines) do + if lnum > row then + api.nvim_win_set_cursor(state.winid, { lnum, 0 }) + return + end + end + -- Wrap around + if #plines > 0 then + api.nvim_win_set_cursor(state.winid, { plines[1], 0 }) + end + else + for i = #plines, 1, -1 do + if plines[i] < row then + api.nvim_win_set_cursor(state.winid, { plines[i], 0 }) + return + end + end + -- Wrap around + if #plines > 0 then + api.nvim_win_set_cursor(state.winid, { plines[#plines], 0 }) + end + end +end + +-- Forward declaration so keymap closures can reference open() before it is +-- defined (Lua closures capture locals by reference, but the local must be +-- declared in an enclosing scope at the point where the closure is created). +local open + +-- Setup buffer keymaps (buffer-local, survive re-focus since buffer persists) +local function setup_keymaps() + local buf = state.bufnr + local opts = { buffer = buf, silent = true, nowait = true } + + -- Close + vim.keymap.set("n", "q", close, opts) + vim.keymap.set("n", "", close, opts) + + -- Update all + vim.keymap.set("n", "U", function() + close() + vim.pack.update() + end, opts) + + -- Update plugin under cursor + vim.keymap.set("n", "u", function() + local name = plugin_at_cursor() + if name then + close() + vim.pack.update({ name }) + end + end, opts) + + -- Restore plugins from lockfile + vim.keymap.set("n", "R", function() + close() + vim.pack.update(nil, { target = "lockfile" }) + end, opts) + + -- Clean non-active plugins + vim.keymap.set("n", "X", function() + local to_clean = vim.iter(vim.pack.get(nil, { info = false })) + :filter(function(x) + return not x.active + end) + :map(function(x) + return x.spec.name + end) + :totable() + + if #to_clean == 0 then + vim.notify("vim.pack: nothing to clean", vim.log.levels.INFO) + return + end + + local msg = string.format("Remove %d non-active plugin(s)?\n\n%s", #to_clean, table.concat(to_clean, "\n")) + local choice = vim.fn.confirm(msg, "&Yes\n&No", 2, "Question") + if choice == 1 then + close() + local ok, err = pcall(vim.pack.del, to_clean) + if ok then + vim.notify(string.format("vim.pack: removed %d plugin(s)", #to_clean), vim.log.levels.INFO) + else + vim.notify("vim.pack: " .. tostring(err), vim.log.levels.ERROR) + end + end + end, opts) + + -- Delete plugin under cursor + vim.keymap.set("n", "D", function() + local name = plugin_at_cursor() + if not name then + return + end + + -- Check if active + local ok, pdata = pcall(vim.pack.get, { name }, { info = false }) + if not ok then + vim.notify(string.format("vim.pack: %s is not installed", name), vim.log.levels.WARN) + return + end + if #pdata > 0 and pdata[1].active then + vim.notify(string.format("vim.pack: %s is active, remove from config first", name), vim.log.levels.WARN) + return + end + + local choice = vim.fn.confirm(string.format("Delete plugin %s?", name), "&Yes\n&No", 2, "Question") + if choice == 1 then + close() + local del_ok, err = pcall(vim.pack.del, { name }) + if del_ok then + vim.notify(string.format("vim.pack: removed %s", name), vim.log.levels.INFO) + else + vim.notify("vim.pack: " .. tostring(err), vim.log.levels.ERROR) + end + end + end, opts) + + -- Open log + vim.keymap.set("n", "L", function() + close() + local log_path = vim.fs.joinpath(vim.fn.stdpath("log"), "nvim-pack.log") + if vim.uv.fs_stat(log_path) then + vim.cmd.edit(log_path) + else + vim.notify("vim.pack: no log file yet", vim.log.levels.INFO) + end + end, opts) + + -- Toggle details + vim.keymap.set("n", "", function() + local name = plugin_at_cursor() + if name then + state.expanded[name] = not state.expanded[name] + render() + -- Restore cursor to the plugin line + if state.plugin_lines[name] then + api.nvim_win_set_cursor(state.winid, { state.plugin_lines[name], 0 }) + end + end + end, opts) + + -- Navigation + vim.keymap.set("n", "]]", function() + jump_plugin(1) + end, opts) + vim.keymap.set("n", "[[", function() + jump_plugin(-1) + end, opts) + + -- Help toggle + vim.keymap.set("n", "?", function() + state.show_help = not state.show_help + render() + end, opts) +end + +-- Open the Pack UI +open = function() + -- If already open, focus it + if state.winid and api.nvim_win_is_valid(state.winid) then + api.nvim_set_current_win(state.winid) + return + end + + setup_highlights() + + -- Create buffer + state.bufnr = api.nvim_create_buf(false, true) + vim.bo[state.bufnr].buftype = "nofile" + vim.bo[state.bufnr].bufhidden = "wipe" + vim.bo[state.bufnr].swapfile = false + vim.bo[state.bufnr].filetype = "pack-ui" + + -- Calculate window size + local cols = vim.o.columns + local lines = vim.o.lines + local width = math.min(cols - 4, math.max(math.floor(cols * 0.8), 60)) + local height = math.min(lines - 4, math.max(math.floor(lines * 0.7), 20)) + local row = math.floor((lines - height) / 2) + local col = math.floor((cols - width) / 2) + + -- Create floating window + state.winid = api.nvim_open_win(state.bufnr, true, { + relative = "editor", + width = width, + height = height, + row = row, + col = col, + style = "minimal", + border = "rounded", + title = " vim.pack ", + title_pos = "center", + }) + + vim.wo[state.winid].cursorline = true + vim.wo[state.winid].wrap = false + + -- Render content + render() + + -- Setup keymaps + setup_keymaps() + + -- Track WinClosed to clean up state if the window is closed externally + -- (e.g., :quit, c). Store the autocmd ID so close() can remove it + -- to prevent races when re-opening immediately after an explicit close. + local captured_winid = state.winid + state.win_autocmd_id = api.nvim_create_autocmd("WinClosed", { + buffer = state.bufnr, + once = true, + callback = function(ev) + -- Only clean up if the closed window matches the one we opened + if vim._tointeger(ev.match) ~= captured_winid then + return + end + state.winid = nil + state.bufnr = nil + state.win_autocmd_id = nil + state.expanded = {} + state.show_help = false + end, + }) +end + +-- Register :Pack command +vim.api.nvim_create_user_command("Pack", function() + open() +end, { desc = "Open vim.pack plugin manager UI" }) + +vim.api.nvim_create_user_command("PackRestore", function() + vim.pack.update(nil, { target = "lockfile" }) +end, { desc = "Restore plugins to versions in lockfile" }) diff --git a/plugin/sessions.lua b/plugin/sessions.lua new file mode 100644 index 0000000..349b190 --- /dev/null +++ b/plugin/sessions.lua @@ -0,0 +1,8 @@ +vim.pack.add({ "https://github.com/rmagatti/auto-session" }) +vim.pack.add({ "https://github.com/tiagovla/scope.nvim" }) +require("scope").setup({}) +require("auto-session").setup({ + suppressed_dirs = { "~/", "/" }, + pre_save_cmds = { "ScopeSaveState" }, + post_restore_cmds = { "ScopeLoadState" }, +}) \ No newline at end of file diff --git a/plugin/snacks.lua b/plugin/snacks.lua new file mode 100644 index 0000000..e65e473 --- /dev/null +++ b/plugin/snacks.lua @@ -0,0 +1,209 @@ +vim.pack.add({ "https://github.com/folke/snacks.nvim" }) +local f = require("common.utils") +local TERMINAL_SHELL = "fish" +local LAZYGIT_KEYMAP = f.isMac() and "" or "" + +local global_keys = { + [""] = { f.isMac() and "" or "" }, + [""] = { f.isMac() and "" or "" }, + [""] = { "list_scroll_down" }, + [""] = { "list_scroll_up" }, + ["s"] = "edit_vsplit", + ["t"] = "tab", + [""] = { "history_forward", mode = "i" }, + [""] = { "history_back", mode = "i" }, + [f.isMac() and "" or ""] = { "qflist", mode = { "n", "i" } }, + [""] = { "preview_scroll_down", mode = { "n", "i" } }, + [""] = { "preview_scroll_up", mode = { "n", "i" } }, +} + +local buffer_keys = { + ["w"] = "bufdelete", + ["v"] = "list_down", + ["c"] = "list_up", +} + +require("snacks").setup({ + image = {}, + indent = {}, + statuscolumn = { + left = { "sign", "git" }, + right = { "mark", "fold" }, + folds = { open = true }, + git = { patterns = { "GitSign" } }, + refresh = 100, + }, + words = { + debounce = 50, + enabled = true, + notify_jump = true, + }, + lazygit = { + config = { + editPreset = "nvim-remote", + os = { + edit = TERMINAL_SHELL + .. ' -c \'if test -z "$NVIM"; nvim -- {{filename}}; else; nvim --server "$NVIM" --remote-send "' + .. LAZYGIT_KEYMAP + .. '"; nvim --server "$NVIM" --remote {{filename}}; end\'', + editAtLine = TERMINAL_SHELL + .. ' -c \'if test -z "$NVIM"; nvim +{{line}} -- {{filename}}; else; nvim --server "$NVIM" --remote-send "' + .. LAZYGIT_KEYMAP + .. '"; nvim --server "$NVIM" --remote {{filename}}; nvim --server "$NVIM" --remote-send ":{{line}}"; end\'', + }, + }, + win = { + height = 0.95, + width = 0.95, + keys = { + { + LAZYGIT_KEYMAP, + function() + Snacks.lazygit() + end, + mode = "t", + }, + }, + }, + }, + terminal = { + win = { height = 0.95, width = 0.95 }, + }, + picker = { + previewers = { git = { builtin = false } }, + formatters = { + filename = { filename_first = true, truncate = 80 }, + file = { filename_first = true, truncate = 80 }, + }, + win = { + input = { keys = global_keys }, + list = { keys = global_keys }, + }, + sources = { + git_log_line = { focus = "list", layout = { preset = "vertical" } }, + git_log_file = { focus = "list", layout = { preset = "vertical" } }, + buffers = { + focus = "list", + layout = { preset = "vertical" }, + win = { + input = { keys = buffer_keys }, + list = { keys = buffer_keys }, + }, + preview = function(ctx) + local previewers = require("snacks.picker.preview") + previewers.file(ctx) + local path = require("snacks.picker.util").path(ctx.item) + if path then + local relative_path = require("snacks.picker.util").truncpath(path, 999) + ctx.preview:set_title(relative_path) + end + end, + }, + grep = { + args = { "--hidden", "-i" }, + format = "filename", + }, + grep_word = { format = "filename" }, + files = { + cmd = "rg", + args = { "--files", "--hidden", "--iglob", "!.git" }, + }, + select = { focus = "list" }, + lsp_references = { focus = "list", format = "filename" }, + lsp_implementations = { focus = "list", format = "filename" }, + }, + }, +}) + +vim.keymap.set("n", LAZYGIT_KEYMAP, function() + Snacks.lazygit() +end, { desc = "Open Lazygit" }) + +vim.keymap.set("n", f.isMac() and "" or "", function() + Snacks.terminal(TERMINAL_SHELL) +end, { desc = "Open Terminal" }) + +vim.keymap.set("t", f.isMac() and "" or "", function() + Snacks.terminal.toggle(TERMINAL_SHELL) +end, { desc = "Toggle Terminal when opened" }) + +vim.keymap.set("n", "", function() + Snacks.words.jump(1, true) +end, { desc = "Next occurence" }) + +vim.keymap.set("n", "", function() + Snacks.words.jump(-1, true) +end, { desc = "Prev occurence" }) + +vim.keymap.set("n", "v", function() + Snacks.picker.buffers({ + on_show = function(picker) + picker:action("list_down") + end, + }) +end) + +vim.keymap.set("n", "p", function() + Snacks.picker.files() +end) + +vim.keymap.set("n", "ff", function() + Snacks.picker.grep() +end) + +vim.keymap.set("v", "ff", function() + Snacks.picker.grep_word({ focus = "list", live = true }) +end) + +vim.keymap.set("n", "fr", function() + Snacks.picker.resume() +end) + +vim.keymap.set("n", "fg", function() + Snacks.picker.git_log_line() +end) + +vim.keymap.set("n", "fG", function() + Snacks.picker.git_log_file() +end) + +vim.keymap.set("n", "fl", function() + Snacks.picker.git_status({ focus = "list" }) +end) + +vim.keymap.set("n", "gr", function() + Snacks.picker.lsp_references() +end, { nowait = true }) + +vim.keymap.set("n", "gi", function() + Snacks.picker.lsp_implementations() +end, { nowait = true }) + +local custom_default = require("snacks.picker.config.layouts").default +custom_default.layout.width = 0.95 +custom_default.layout.height = 0.9 +custom_default.layout[2].min_width = 85 +custom_default.layout[2].width = 85 + +local custom_vertical = require("snacks.picker.config.layouts").vertical +custom_vertical.layout.height = 0.95 +custom_vertical.layout.backdrop = true +custom_vertical.layout.width = 0.8 +custom_vertical.layout[3].height = 0.8 + +f.HighlightGroups.register(function() + vim.api.nvim_set_hl(0, "SnacksPickerDir", vim.api.nvim_get_hl(0, { name = "Comment", link = false })) +end) + +vim.api.nvim_create_user_command("CloseOtherBuffers", function() + Snacks.bufdelete.other() +end, { desc = "Close all other buffers" }) + +vim.api.nvim_create_user_command("SnacksPickers", function() + Snacks.picker() +end, { desc = "Show all Snacks pickers" }) + +vim.api.nvim_create_user_command("SymbolsPicker", function() + Snacks.picker.lsp_symbols({ focus = "list" }) +end, { desc = "Show Symbols for this file (Snack picker)" }) + diff --git a/plugin/ts-comments.lua b/plugin/ts-comments.lua new file mode 100644 index 0000000..9de529e --- /dev/null +++ b/plugin/ts-comments.lua @@ -0,0 +1,3 @@ +vim.pack.add({ "https://github.com/folke/ts-comments.nvim" }) +require("ts-comments").setup({}) + diff --git a/plugin/wildfire.lua b/plugin/wildfire.lua new file mode 100644 index 0000000..5584530 --- /dev/null +++ b/plugin/wildfire.lua @@ -0,0 +1,13 @@ +local f = require("common.utils") + +vim.pack.add({ + "https://github.com/sustech-data/wildfire.nvim", + "https://github.com/nvim-treesitter/nvim-treesitter", +}) +require("wildfire").setup({ + keymaps = { + init_selection = "", + node_incremental = "", + node_decremental = f.isMac() and "" or "⊘", + }, +}) \ No newline at end of file