local overrides = require "custom.configs.overrides" ---@type NvPluginSpec[] local plugins = { -- Override plugin definition options { "neovim/nvim-lspconfig", config = function() require "plugins.configs.lspconfig" require "custom.configs.lspconfig" end, -- Override to setup mason-lspconfig }, -- override plugin configs { "williamboman/mason.nvim", opts = overrides.mason, }, { "nvim-treesitter/nvim-treesitter", opts = overrides.treesitter, }, { "nvim-tree/nvim-tree.lua", opts = overrides.nvimtree, }, -- Install a plugin { -- exit insert mode with 'jk' "max397574/better-escape.nvim", enabled = true, event = "InsertEnter", config = function() require("better_escape").setup() end, }, { "stevearc/conform.nvim", -- for users those who want auto-save conform + lazyloading! -- event = "BufWritePre" config = function() require "custom.configs.conform" end, }, { "ggandor/leap.nvim", lazy = false, config = function() require("core.utils").load_mappings "leap" end, }, { "ggandor/flit.nvim", lazy = false, config = function() require("flit").setup { keys = { f = "f", F = "F", t = "t", T = "T" }, -- A string like "nv", "nvo", "o", etc. labeled_modes = "v", multiline = true, -- Like `leap`s similar argument (call-specific overrides). -- E.g.: opts = { equivalence_classes = {} } opts = {}, } end, }, { "kdheepak/lazygit.nvim", lazy = false, keys = { "gg" }, cmd = "LazyGit", -- optional for floating window border decoration dependencies = { "nvim-lua/plenary.nvim", }, init = function() require("core.utils").load_mappings "lazygit" end, }, { "folke/which-key.nvim", keys = { "", "", "", "", '"', "'", "`", "c", "v", "g" }, defaults = { mode = { "n", "v" }, [";"] = { name = "+telescope" }, [";f"] = { name = "+find" }, [";d"] = { name = "+lsp/todo" }, ["g"] = { name = "+goto" }, ["]"] = { name = "+next" }, ["["] = { name = "+prev" }, ["x"] = { name = "+diagnostics/quickfix" }, ["d"] = { name = "+debug" }, ["c"] = { name = "+code" }, ["g"] = { name = "+git" }, ["t"] = { name = "+toggle/tools" }, ["w"] = { name = "+window/which" }, ["f"] = { name = "+formatting" }, }, }, { "echasnovski/mini.trailspace", lazy = false, event = { "BufReadPost", "BufNewFile" }, opts = {}, }, { "itchyny/vim-cursorword", event = "FileType", init = function() vim.g.cursorword = 0 end, config = function() local augroup = vim.api.nvim_create_augroup("plex_cursorword", {}) vim.api.nvim_create_autocmd("FileType", { group = augroup, pattern = { "conf", "dosini", "json", "markdown", "nginx", "text", "yaml", }, callback = function() if vim.wo.diff or vim.wo.previewwindow then vim.b.cursorword = 0 else vim.b.cursorword = 1 end end, }) vim.api.nvim_create_autocmd("InsertEnter", { group = augroup, callback = function() if vim.b["cursorword"] == 1 then vim.b["cursorword"] = 0 end end, }) vim.api.nvim_create_autocmd("InsertLeave", { group = augroup, callback = function() if vim.b["cursorword"] == 0 then vim.b["cursorword"] = 1 end end, }) end, }, { "RRethy/vim-illuminate", lazy = false, event = { "BufReadPost", "BufNewFile" }, opts = { delay = 200, under_cursor = false, modes_allowlist = { "n", "no", "nt" }, filetypes_denylist = { "DiffviewFileHistory", "DiffviewFiles", "SidebarNvim", "fugitive", "git", "minifiles", "neo-tree", }, }, keys = { { "]]", desc = "Next Reference" }, { "[[", desc = "Prev Reference" }, }, config = function(_, opts) require("illuminate").configure(opts) local function map(key, dir, buffer) vim.keymap.set("n", key, function() require("illuminate")["goto_" .. dir .. "_reference"](false) end, { desc = dir:sub(1, 1):upper() .. dir:sub(2) .. " Reference", buffer = buffer, }) end map("]]", "next") map("[[", "prev") -- also set it after loading ftplugins, since a lot overwrite [[ and ]] vim.api.nvim_create_autocmd("FileType", { group = vim.api.nvim_create_augroup("plex_illuminate", {}), callback = function() local buffer = vim.api.nvim_get_current_buf() map("]]", "next", buffer) map("[[", "prev", buffer) end, }) end, }, { "folke/todo-comments.nvim", lazy = false, dependencies = "nvim-telescope/telescope.nvim", -- stylua: ignore keys = { { ']t', function() require('todo-comments').jump_next() end, desc = 'Next todo comment' }, { '[t', function() require('todo-comments').jump_prev() end, desc = 'Previous todo comment' }, { 'dt', 'TodoTelescope', desc = 'todo' }, { 'xt', 'TodoTrouble', desc = 'Todo (Trouble)' }, { 'xT', 'TodoTrouble keywords=TODO,FIX,FIXME', desc = 'Todo/Fix/Fixme (Trouble)' }, }, opts = { signs = true, keywords = { FIX = { icon = " ", -- icon used for the sign, and in search results color = "error", -- can be a hex color, or a named color (see below) alt = { "FIXME", "BUG", "FIXIT", "ISSUE" }, -- a set of other keywords that all map to this FIX keywords }, TODO = { icon = " ", color = "todo" }, HACK = { icon = " ", color = "hack" }, SECURITY = { icon = "󰒃 ", color = "security" }, WARN = { icon = " ", color = "warning", alt = { "WARNING", "XXX" } }, PERF = { icon = " ", color = "perf", alt = { "OPTIM", "PERFORMANCE", "OPTIMIZE" } }, NOTE = { icon = " ", color = "hint", alt = { "INFO" } }, TEST = { icon = "⏲ ", color = "test", alt = { "TESTING", "PASSED", "FAILED" } }, }, colors = { error = { "DiagnosticError", "ErrorMsg", "#DC2626" }, warning = { "DiagnosticWarn", "WarningMsg", "#FBBF24" }, todo = { "DiagnosticTodo", "#80e64d" }, hint = { "DiagnosticHint", "#10B981" }, hack = { "DiagnosticHack", "#FF33FF" }, security = { "DiagnosticSecurity", "#FF6600" }, default = { "Identifier", "#7C3AED" }, test = { "DiagnosticTest", "#E6E600" }, perf = { "DiagnosticPerf", "#9999ff" }, }, }, }, { "folke/trouble.nvim", cmd = { "Trouble", "TroubleToggle" }, opts = { use_diagnostic_signs = true }, -- stylua: ignore keys = { { 'e', 'TroubleToggle document_diagnostics', noremap = true, desc = 'Document Diagnostics' }, { 'r', 'TroubleToggle workspace_diagnostics', noremap = true, desc = 'Workspace Diagnostics' }, { 'xx', 'TroubleToggle document_diagnostics', desc = 'Document Diagnostics (Trouble)' }, { 'xX', 'TroubleToggle workspace_diagnostics', desc = 'Workspace Diagnostics (Trouble)' }, { 'xQ', 'TroubleToggle quickfix', desc = 'Quickfix List (Trouble)' }, { 'xL', 'TroubleToggle loclist', desc = 'Location List (Trouble)' }, { '[q', function() if require('trouble').is_open() then require('trouble').previous({ skip_groups = true, jump = true }) else vim.cmd.cprev() end end, desc = 'Previous trouble/quickfix item', }, { ']q', function() if require('trouble').is_open() then require('trouble').next({ skip_groups = true, jump = true }) else vim.cmd.cnext() end end, desc = 'Next trouble/quickfix item', }, }, }, { "NvChad/nvterm", enabled = false, }, { "akinsho/toggleterm.nvim", init = function() require("core.utils").load_mappings "toggleterm" end, cmd = "ToggleTerm", opts = { size = function(term) if term.direction == "horizontal" then return vim.o.lines * 0.35 elseif term.direction == "vertical" then return vim.o.columns * 0.35 else return 20 end end, open_mapping = false, float_opts = { border = "curved", }, }, }, -- lazy.nvim { "folke/noice.nvim", enabled = not vim.g.started_by_firenvim, event = "VeryLazy", -- config.lsp.signature.enabled = false dependencies = { -- if you lazy-load any plugin below, make sure to add proper `module="..."` entries "MunifTanjim/nui.nvim", -- OPTIONAL: -- `nvim-notify` is only needed, if you want to use the notification view. -- If not available, we use `mini` as the fallback "rcarriga/nvim-notify", }, config = function() require("noice").setup { lsp = { override = { ["vim.lsp.util.convert_input_to_markdown_lines"] = true, ["vim.lsp.util.stylize_markdown"] = true, ["cmp.entry.get_documentation"] = true, }, -- IDK how to disable the nvchad builtins for this, which would -- produce a conflict signature = { enabled = false }, hover = { enabled = false }, }, -- you can enable a preset for easier configuration presets = { bottom_search = true, -- use a classic bottom cmdline for search command_palette = true, -- position the cmdline and popupmenu together long_message_to_split = true, -- long messages will be sent to a split inc_rename = true, -- enables an input dialog for inc-rename.nvim lsp_doc_border = true, -- add a border to hover docs and signature help }, messages = { enabled = true, -- NOTE: we keep it with notify, -- change this to something else if you want view_error = "notify", }, popupmenu = { enabled = true, }, notify = { enabled = true, }, } end, }, { "goolord/alpha-nvim", enabled = false, lazy = false, dependencies = { "nvim-tree/nvim-web-devicons" }, config = function() local dash = require "alpha.themes.dashboard" require("alpha").setup(dash.config) end, }, { "stevearc/dressing.nvim", init = function() ---@diagnostic disable-next-line: duplicate-set-field vim.ui.select = function(...) require("lazy").load { plugins = { "dressing.nvim" } } return vim.ui.select(...) end ---@diagnostic disable-next-line: duplicate-set-field vim.ui.input = function(...) require("lazy").load { plugins = { "dressing.nvim" } } return vim.ui.input(...) end end, }, { "chentoast/marks.nvim", lazy = false, dependencies = "lewis6991/gitsigns.nvim", event = "FileType", opts = { sign_priority = { lower = 10, upper = 15, builtin = 8, bookmark = 20 }, bookmark_1 = { sign = "󰉀" }, -- ⚐ ⚑ 󰈻 󰈼 󰈽 󰈾 󰈿 󰉀 }, }, { "kevinhwang91/nvim-bqf", ft = "qf", cmd = "BqfAutoToggle", event = "QuickFixCmdPost", opts = { auto_resize_height = false, func_map = { tab = "st", split = "sv", vsplit = "sg", stoggleup = "K", stoggledown = "J", stogglevm = "", ptoggleitem = "p", ptoggleauto = "P", ptogglemode = "zp", pscrollup = "", pscrolldown = "", prevfile = "gk", nextfile = "gj", prevhist = "", nexthist = "", }, preview = { auto_preview = true, should_preview_cb = function(bufnr) -- file size greater than 100kb can't be previewed automatically local filename = vim.api.nvim_buf_get_name(bufnr) local fsize = vim.fn.getfsize(filename) if fsize > 100 * 1024 then return false end return true end, }, }, }, { "uga-rosa/ccc.nvim", lazy = false, event = "FileType", keys = { { "cp", "CccPick", desc = "Color-picker" }, }, opts = { highlighter = { auto_enable = true, lsp = true, excludes = { "lazy", "mason", "help", "neo-tree" }, }, }, }, { "Bekaboo/deadcolumn.nvim", event = { "BufReadPre", "BufNewFile" }, }, { "rmagatti/goto-preview", event = "FileType", config = function() require("core.utils").load_mappings "goto_preview" require("goto-preview").setup {} end, dependencies = "nvim-telescope/telescope.nvim", opts = { width = 78, height = 15, default_mappings = false, opacity = 10, }, }, { "glacambre/firenvim", enabled = vim.g.started_by_firenvim, lazy = false, build = function() vim.fn["firenvim#install"](0) end, config = function() vim.g.firenvim_config = { localSettings = { [".*"] = { filename = "/tmp/{hostname}_{pathname%10}.{extension%5}", cmdline = "firenvim", takeover = "never", -- can't open it with never at all? }, }, } end, }, { "sidebar-nvim/sidebar.nvim", cmd = { "SidebarNvimToggle", "SidebarNvimOpen" }, config = function() require("sidebar-nvim").setup { bindings = { ["q"] = function() require("sidebar-nvim").close() end, }, } end, }, { "dhruvasagar/vim-table-mode", lazy = false, -- tm is automatically set for toggle -- see t menu }, { "kevinhwang91/nvim-ufo", event = { "BufReadPost", "BufNewFile" }, -- stylua: ignore keys = { { 'zR', function() require('ufo').openAllFolds() end }, { 'zM', function() require('ufo').closeAllFolds() end }, }, dependencies = { "kevinhwang91/promise-async", "nvim-treesitter/nvim-treesitter", "neovim/nvim-lspconfig", }, opts = function() -- fancy display function for folds (stolen from nvim-ufo readme) local handler = function(virtText, lnum, endLnum, width, truncate) local newVirtText = {} local suffix = (" 󰁂 %d "):format(endLnum - lnum) local sufWidth = vim.fn.strdisplaywidth(suffix) local targetWidth = width - sufWidth local curWidth = 0 for _, chunk in ipairs(virtText) do local chunkText = chunk[1] local chunkWidth = vim.fn.strdisplaywidth(chunkText) if targetWidth > curWidth + chunkWidth then table.insert(newVirtText, chunk) else chunkText = truncate(chunkText, targetWidth - curWidth) local hlGroup = chunk[2] table.insert(newVirtText, { chunkText, hlGroup }) chunkWidth = vim.fn.strdisplaywidth(chunkText) -- str width returned from truncate() may less than 2nd argument, need padding if curWidth + chunkWidth < targetWidth then suffix = suffix .. (" "):rep(targetWidth - curWidth - chunkWidth) end break end curWidth = curWidth + chunkWidth end table.insert(newVirtText, { suffix, "MoreMsg" }) return newVirtText end require("ufo").setup { -- use treesitter to get the folds provider_selector = function(bufnr, filetype, buftype) return { "treesitter", "indent" } end, -- apply out fancy fold display fold_virt_text_handler = handler, } end, }, { -- enables UNIX specific stuff in vim, -- specifically: -- :SudoWrite -- :SudoRead -- :Chmod -- and also some more, but those are easy done with shell "tpope/vim-eunuch", lazy = false, }, { "nvimtools/none-ls.nvim", event = { "BufReadPre", "BufNewFile" }, opts = function(_, opts) opts.sources = {} local nls = require "null-ls" local builtins = nls.builtins local sources = { builtins.formatting.djlint.with { filetypes = { "django", "jinja.html", "htmldjango", "tera", "html" }, }, builtins.diagnostics.djlint.with { filetypes = { "django", "jinja.html", "htmldjango", "tera", "html" }, }, builtins.formatting.shfmt, -- builtins.diagnostics.write_good.with { -- diagnostics_postprocess = function(diagnostic) -- diagnostic.severity = vim.diagnostic.severity.HINT -- end, -- }, } for _, source in ipairs(sources) do table.insert(opts.sources, source) end end, }, { "lvimuser/lsp-inlayhints.nvim", event = "LspAttach", opts = { inlay_hints = { parameter_hints = { show = true }, type_hints = { show = true }, only_current_line = false, -- highlight group highlight = "LspInlayHint", -- virt_text priority priority = 0, }, }, config = function(_, opts) require("lsp-inlayhints").setup(opts) vim.api.nvim_create_augroup("LspAttach_inlayhints", {}) vim.api.nvim_create_autocmd("LspAttach", { group = vim.api.nvim_create_augroup("LspAttach_inlayhints", {}), callback = function(args) if not (args.data and args.data.client_id) then return end local client = vim.lsp.get_client_by_id(args.data.client_id) require("lsp-inlayhints").on_attach(client, args.buf) end, }) -- change how the highlighting looks vim.cmd "hi LspInlayHint guibg=(bg*0.8) guifg=#6699b3" end, }, { "kosayoda/nvim-lightbulb", event = { "BufReadPre", "BufNewFile" } }, { "Wansmer/treesj", cmd = { "TSJJoin", "TSJSplit", "TSJSplit" }, keys = { { "", "TSJJoin" }, { "", "TSJSplit" }, }, opts = { use_default_keymaps = false, }, }, { "b0o/incline.nvim", event = "FileType", config = function() local function get_diagnostic_label(props) local icons = { error = "", warn = "", info = "", hint = "" } local label = {} for severity, icon in pairs(icons) do local n = #vim.diagnostic.get(props.buf, { severity = vim.diagnostic.severity[string.upper(severity)] }) if n > 0 then table.insert(label, { icon .. " " .. n .. " ", group = "DiagnosticSign" .. severity }) end end if #label > 0 then table.insert(label, { "| " }) end return label end local function get_git_diff(props) local icons = { removed = "", changed = "", added = "" } local labels = {} -- local signs = vim.api.nvim_buf_get_var(props.buf, "gitsigns_status_dict") -- local signs = vim.b.gitsigns_status_dict -- for name, icon in pairs(icons) do -- if tonumber(signs[name]) and signs[name] > 0 then -- table.insert(labels, { icon .. " " .. signs[name] .. " ", group = "Diff" .. name }) -- end -- end if #labels > 0 then table.insert(labels, { "| " }) end return labels end require("incline").setup { render = function(props) local filename = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(props.buf), ":t") local ft_icon, ft_color = require("nvim-web-devicons").get_icon_color(filename) local modified = vim.api.nvim_buf_get_option(props.buf, "modified") and "bold,italic" or "bold" local buffer = { { get_diagnostic_label(props) }, { get_git_diff(props) }, { ft_icon, guifg = ft_color }, { " " }, { filename, gui = modified }, } return buffer end, } end, }, { "mikesmithgh/kitty-scrollback.nvim", enabled = true, lazy = true, cmd = { "KittyScrollbackGenerateKittens", "KittyScrollbackCheckHealth" }, event = { "User KittyScrollbackLaunch" }, -- version = '*', -- latest stable version, may have breaking changes if major version changed -- version = '^3.0.0', -- pin major version, include fixes and features that do not have breaking changes config = function() require("kitty-scrollback").setup { myconfig = function() return { keymaps_enabled = false } end, } end, }, { "hrsh7th/nvim-cmp", enabled = not vim.g.started_by_firenvim, }, { "ziontee113/icon-picker.nvim", keys = { { "", "IconPickerNormal", desc = "pick icon" }, { "y", "IconPickerYank", desc = "yank icon" }, }, cmd = { "IconPickerInsert", "IconPickerYank", "IconPickerNormal" }, config = function() require("icon-picker").setup { disable_legacy_commands = true } end, }, { "mfussenegger/nvim-dap", lazy = false, init = function() require("core.utils").load_mappings "debug" end, config = function() local dap = require "dap" local mason_registry = require "mason-registry" local codelldb_root = mason_registry.get_package("codelldb"):get_install_path() .. "/extension/" local codelldb_path = codelldb_root .. "adapter/codelldb" local liblldb_path = codelldb_root .. "lldb/lib/liblldb.so" dap.defaults.fallback.external_terminal = { command = "/home/plex/.local/bin/kitty", args = {}, } dap.adapters.gdb = { type = "executable", command = "gdb", args = { "-i", "dap" }, } dap.adapters.codelldb = { type = "server", port = "30333", executable = { command = codelldb_path, args = { "--port", "30333" }, detached = false, }, } dap.configurations.cpp = { { name = "Launch file", type = "codelldb", request = "launch", program = function() return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file") end, args = function() return require("custom.utils").tokenize_args(vim.fn.input "args: ") end, cwd = "${workspaceFolder}", -- FIXME: perhaps we can put the stdio somewhere more practical stopOnEntry = false, }, } dap.configurations.c = dap.configurations.cpp dap.configurations.rust = dap.configurations.cpp end, }, { "rcarriga/nvim-dap-ui", init = function() require("core.utils").load_mappings "debug" end, dependencies = { "mfussenegger/nvim-dap", }, config = function(_, opts) local dap = require "dap" local dapui = require "dapui" dapui.setup(opts) dap.listeners.after.event_initialized["dapui_config"] = function() dapui.open {} end dap.listeners.before.event_terminated["dapui_config"] = function() -- dapui.close {} end dap.listeners.before.event_exited["dapui_config"] = function() -- dapui.close {} end end, }, { "folke/neodev.nvim", opts = {} }, { "mrcjkb/rustaceanvim", enabled = true, version = "^4", -- Recommended ft = { "rust" }, config = function() local dap = require "dap" vim.g.rustaceanvim = { enable_clippy = true, -- Plugin configuration tools = { enable_clippy = true, }, -- LSP configuration server = { on_attach = function(client, bufnr) -- you can also put keymaps in here end, settings = { -- rust-analyzer language server configuration ["rust-analyzer"] = { cargo = { features = "all", }, }, }, }, -- DAP configuration dap = { -- FIXME: the rustaceanvim debug config does not map the stdout/stderr to the -- opened terminal, effectively rendering debugging with it useless. Luckily, -- we can use the regular nvim-dap and nvim-dap-ui. adapter = dap.adapters.codelldb, }, } end, }, { "theHamsta/nvim-dap-virtual-text", lazy = false, -- PERF: this can be done more elegant config = function() require("nvim-dap-virtual-text").setup() end, }, { "jvgrootveld/telescope-zoxide", dependencies = "nvim-telescope/telescope.nvim", config = function() -- Useful for easily creating commands local z_utils = require "telescope._extensions.zoxide.utils" require("telescope").setup { -- (other Telescope configuration...) extensions = { zoxide = { prompt_title = "[ Walking on the shoulders of TJ ]", mappings = { default = { after_action = function(selection) print("Update to (" .. selection.z_score .. ") " .. selection.path) end, }, [""] = { before_action = function(selection) print "before C-s" end, action = function(selection) vim.cmd.edit(selection.path) end, }, -- Opens the selected entry in a new split [""] = { action = z_utils.create_basic_command "split" }, }, }, }, } require("telescope").load_extension "zoxide" end, }, { "nanotee/zoxide.vim", lazy = false, enabled = false }, { "iamcco/markdown-preview.nvim", cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" }, ft = { "markdown" }, build = function() vim.fn["mkdp#util#install"]() end, config = function() -- Ugly fix for wsl not finding my browser -- I HATE windows vim.g.mkdp_echo_preview_url = 1 end, }, } return plugins