local have_make = vim.fn.executable("make") == 1 local have_cmake = vim.fn.executable("cmake") == 1 return { -- file explorer { "nvim-neo-tree/neo-tree.nvim", branch = "v3.x", cmd = "Neotree", keys = { { "fe", function() require("neo-tree.command").execute({ toggle = true, dir = LazyVim.root() }) end, desc = "Explorer NeoTree (Root Dir)", }, { "fE", function() require("neo-tree.command").execute({ toggle = true, dir = vim.uv.cwd() }) end, desc = "Explorer NeoTree (cwd)", }, { "e", "fe", desc = "Explorer NeoTree (Root Dir)", remap = true }, { "E", "fE", desc = "Explorer NeoTree (cwd)", remap = true }, { "ge", function() require("neo-tree.command").execute({ source = "git_status", toggle = true }) end, desc = "Git Explorer", }, { "be", function() require("neo-tree.command").execute({ source = "buffers", toggle = true }) end, desc = "Buffer Explorer", }, }, deactivate = function() vim.cmd([[Neotree close]]) end, init = function() -- FIX: use `autocmd` for lazy-loading neo-tree instead of directly requiring it, -- because `cwd` is not set up properly. vim.api.nvim_create_autocmd("BufEnter", { group = vim.api.nvim_create_augroup("Neotree_start_directory", { clear = true }), desc = "Start Neo-tree with directory", once = true, callback = function() if package.loaded["neo-tree"] then return else local stats = vim.uv.fs_stat(vim.fn.argv(0)) if stats and stats.type == "directory" then require("neo-tree") end end end, }) end, opts = { sources = { "filesystem", "buffers", "git_status", "document_symbols" }, open_files_do_not_replace_types = { "terminal", "Trouble", "trouble", "qf", "Outline" }, filesystem = { bind_to_cwd = false, follow_current_file = { enabled = true }, use_libuv_file_watcher = true, }, window = { mappings = { ["l"] = "open", ["h"] = "close_node", [""] = "none", ["Y"] = { function(state) local node = state.tree:get_node() local path = node:get_id() vim.fn.setreg("+", path, "c") end, desc = "Copy Path to Clipboard", }, ["O"] = { function(state) require("lazy.util").open(state.tree:get_node().path, { system = true }) end, desc = "Open with System Application", }, ["P"] = { "toggle_preview", config = { use_float = false } }, }, }, default_component_configs = { indent = { with_expanders = true, -- if nil and file nesting is enabled, will enable expanders expander_collapsed = "", expander_expanded = "", expander_highlight = "NeoTreeExpander", }, git_status = { symbols = { unstaged = "󰄱", staged = "󰱒", }, }, }, }, config = function(_, opts) local function on_move(data) LazyVim.lsp.on_rename(data.source, data.destination) end local events = require("neo-tree.events") opts.event_handlers = opts.event_handlers or {} vim.list_extend(opts.event_handlers, { { event = events.FILE_MOVED, handler = on_move }, { event = events.FILE_RENAMED, handler = on_move }, }) require("neo-tree").setup(opts) vim.api.nvim_create_autocmd("TermClose", { pattern = "*lazygit", callback = function() if package.loaded["neo-tree.sources.git_status"] then require("neo-tree.sources.git_status").refresh() end end, }) end, }, -- search/replace in multiple files { "nvim-pack/nvim-spectre", build = false, cmd = "Spectre", opts = { open_cmd = "noswapfile vnew" }, -- stylua: ignore keys = { { "sr", function() require("spectre").open() end, desc = "Replace in Files (Spectre)" }, }, }, -- Flash enhances the built-in search functionality by showing labels -- at the end of each match, letting you quickly jump to a specific -- location. { "folke/flash.nvim", event = "VeryLazy", vscode = true, ---@type Flash.Config opts = {}, -- stylua: ignore keys = { { "s", mode = { "n", "x", "o" }, function() require("flash").jump() end, desc = "Flash" }, { "S", mode = { "n", "o", "x" }, function() require("flash").treesitter() end, desc = "Flash Treesitter" }, { "r", mode = "o", function() require("flash").remote() end, desc = "Remote Flash" }, { "R", mode = { "o", "x" }, function() require("flash").treesitter_search() end, desc = "Treesitter Search" }, { "", mode = { "c" }, function() require("flash").toggle() end, desc = "Toggle Flash Search" }, }, }, -- which-key helps you remember key bindings by showing a popup -- with the active keybindings of the command you started typing. { "folke/which-key.nvim", event = "VeryLazy", opts = { plugins = { spelling = true }, defaults = { mode = { "n", "v" }, ["g"] = { name = "+goto" }, ["gs"] = { name = "+surround" }, ["z"] = { name = "+fold" }, ["]"] = { name = "+next" }, ["["] = { name = "+prev" }, [""] = { name = "+tabs" }, ["b"] = { name = "+buffer" }, ["c"] = { name = "+code" }, ["f"] = { name = "+file/find" }, ["g"] = { name = "+git" }, ["gh"] = { name = "+hunks" }, ["q"] = { name = "+quit/session" }, ["s"] = { name = "+search" }, ["u"] = { name = "+ui" }, ["w"] = { name = "+windows" }, ["x"] = { name = "+diagnostics/quickfix" }, }, }, config = function(_, opts) local wk = require("which-key") wk.setup(opts) wk.register(opts.defaults) end, }, -- git signs highlights text that has changed since the list -- git commit, and also lets you interactively stage & unstage -- hunks in a commit. { "lewis6991/gitsigns.nvim", event = "LazyFile", opts = { signs = { add = { text = "▎" }, change = { text = "▎" }, delete = { text = "" }, topdelete = { text = "" }, changedelete = { text = "▎" }, untracked = { text = "▎" }, }, on_attach = function(buffer) local gs = package.loaded.gitsigns local function map(mode, l, r, desc) vim.keymap.set(mode, l, r, { buffer = buffer, desc = desc }) end -- stylua: ignore start map("n", "]h", function() gs.nav_hunk("next") end, "Next Hunk") map("n", "[h", function() gs.nav_hunk("prev") end, "Prev Hunk") map("n", "]H", function() gs.nav_hunk("last") end, "Last Hunk") map("n", "[H", function() gs.nav_hunk("first") end, "First Hunk") map({ "n", "v" }, "ghs", ":Gitsigns stage_hunk", "Stage Hunk") map({ "n", "v" }, "ghr", ":Gitsigns reset_hunk", "Reset Hunk") map("n", "ghS", gs.stage_buffer, "Stage Buffer") map("n", "ghu", gs.undo_stage_hunk, "Undo Stage Hunk") map("n", "ghR", gs.reset_buffer, "Reset Buffer") map("n", "ghp", gs.preview_hunk_inline, "Preview Hunk Inline") map("n", "ghb", function() gs.blame_line({ full = true }) end, "Blame Line") map("n", "ghd", gs.diffthis, "Diff This") map("n", "ghD", function() gs.diffthis("~") end, "Diff This ~") map({ "o", "x" }, "ih", ":Gitsigns select_hunk", "GitSigns Select Hunk") end, }, }, -- better diagnostics list and others { "folke/trouble.nvim", cmd = { "TroubleToggle", "Trouble" }, opts = { use_diagnostic_signs = true }, keys = { { "xx", "Trouble diagnostics toggle", desc = "Diagnostics (Trouble)" }, { "xX", "Trouble diagnostics toggle filter.buf=0", desc = "Buffer Diagnostics (Trouble)" }, { "cs", "Trouble symbols toggle focus=false", desc = "Symbols (Trouble)" }, { "cS", "Trouble lsp toggle focus=false win.position=right", desc = "LSP references/definitions/... (Trouble)", }, { "xL", "Trouble loclist toggle", desc = "Location List (Trouble)" }, { "xQ", "Trouble qflist toggle", desc = "Quickfix List (Trouble)" }, { "[q", function() if require("trouble").is_open() then require("trouble").prev({ skip_groups = true, jump = true }) else local ok, err = pcall(vim.cmd.cprev) if not ok then vim.notify(err, vim.log.levels.ERROR) end end end, desc = "Previous Trouble/Quickfix Item", }, { "]q", function() if require("trouble").is_open() then require("trouble").next({ skip_groups = true, jump = true }) else local ok, err = pcall(vim.cmd.cnext) if not ok then vim.notify(err, vim.log.levels.ERROR) end end end, desc = "Next Trouble/Quickfix Item", }, }, }, -- Finds and lists all of the TODO, HACK, BUG, etc comment -- in your project and loads them into a browsable list. { "folke/todo-comments.nvim", cmd = { "TodoTrouble", "TodoTelescope" }, event = "LazyFile", opts = {}, -- 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" }, { "xt", "Trouble todo toggle", desc = "Todo (Trouble)" }, { "xT", "Trouble todo toggle filter = {tag = {TODO,FIX,FIXME}}", desc = "Todo/Fix/Fixme (Trouble)" }, { "st", "TodoTelescope", desc = "Todo" }, { "sT", "TodoTelescope keywords=TODO,FIX,FIXME", desc = "Todo/Fix/Fixme" }, }, }, { import = "lazyvim.plugins.extras.editor.fzf", enabled = function() return LazyVim.has_extra("editor.fzf") end, }, { import = "lazyvim.plugins.extras.editor.telescope", enabled = function() return not LazyVim.has_extra("editor.fzf") end, }, }