return { "folke/snacks.nvim", priority = 1000, lazy = false, opts = { -- Dashboard/Starter dashboard = { enabled = false }, -- Notification system (replaces nvim-notify) notifier = { enabled = true, timeout = 5000, width = { min = 50, max = 0.4 }, height = { min = 1, max = 0.6 }, margin = { top = 0, right = 1, bottom = 0 }, padding = true, sort = { "level", "added" }, level = vim.log.levels.INFO, icons = { error = " ", warn = " ", info = " ", debug = " ", trace = "✎ ", }, style = "compact", }, -- File picker (replaces telescope) picker = { enabled = true, -- Performance optimizations show_delay = 0, -- Show picker immediately (default is 5000ms) limit_live = 5000, -- Reduce live search limit for better performance matcher = { frecency = false, -- Disable frecency for faster startup (enable if you want recency scoring) cwd_bonus = false, -- Disable for better performance history_bonus = false, -- Disable for better performance }, formatters = { file = { filename_first = true, }, }, win = { input = { keys = { [""] = { "list_down", mode = { "i", "n" } }, [""] = { "list_up", mode = { "i", "n" } }, [""] = { "history_next", mode = { "i", "n" } }, [""] = { "history_prev", mode = { "i", "n" } }, [""] = { "qflist", mode = { "i", "n" } }, [""] = { "close", mode = { "i", "n" } }, }, }, }, sources = { files = { hidden = true, follow = true, -- Let snacks auto-detect fd (fastest) or fallback to rg/find }, grep = { hidden = true, follow = true, }, }, }, -- Quickfile (fast file operations) quickfile = { enabled = true }, -- Statuscolumn enhancements statuscolumn = { enabled = true, left = { "mark", "sign" }, -- priority of signs on the left (high to low) right = { "fold", "git" }, -- priority of signs on the right (high to low) folds = { open = false, -- show open fold icons git_hl = false, -- use Git Signs hl for fold icons }, git = { -- patterns to match Git signs patterns = { "GitSign", "MiniDiffSign" }, }, refresh = 50, -- refresh at most every 50ms }, -- Word highlighting words = { enabled = true }, -- Styling for inputs input = { enabled = true }, -- Scrolling scroll = { enabled = false }, -- Indent guides indent = { enabled = false }, -- Scope highlighting scope = { enabled = true }, -- Git integration with blame git = { enabled = true, }, gitbrowse = { enabled = true, }, -- Rename with LSP rename = { enabled = true }, -- Terminal terminal = { enabled = true }, -- Zen mode zen = { enabled = false }, -- Dim inactive windows dim = { enabled = false }, -- Better quickfix quickfix = { enabled = true }, -- Scratch buffer scratch = { enabled = true }, -- Toggle options toggle = { enabled = true }, -- Profiler profiler = { enabled = false }, -- Debugging helpers debug = { enabled = false }, -- Treesitter scope treesitter = { enabled = true }, }, keys = { -- File navigation (replacing telescope keybindings) { "p", function() Snacks.picker.smart() end, desc = "Find project files" }, { "ff", function() Snacks.picker.grep() end, desc = "Live grep" }, { "fg", function() Snacks.picker.grep() end, desc = "Live grep" }, { "fr", function() Snacks.picker.resume() end, desc = "Resume last picker" }, { "fb", function() Snacks.picker.buffers() end, desc = "Find buffers" }, { "fo", function() Snacks.picker.recent() end, desc = "Find recent files" }, { "fc", function() Snacks.picker.commands() end, desc = "Find commands" }, -- Search { "fw", function() Snacks.picker.grep_word() end, desc = "Grep word under cursor" }, { "fW", function() local word = vim.fn.expand("") Snacks.picker.grep({ search = word }) end, desc = "Grep WORD under cursor" }, { "fw", function() local mode = vim.fn.mode() if mode == 'v' or mode == 'V' then vim.cmd('noau normal! "vy"') local text = vim.fn.getreg('v') vim.fn.setreg('v', {}) text = string.gsub(text, "\n", "") if #text > 0 then Snacks.picker.grep({ search = text }) else Snacks.picker.grep() end end end, mode = "v", desc = "Grep selection" }, { "fF", function() local word = vim.fn.expand("") Snacks.picker.files({ search = word }) end, desc = "Find file with name under cursor" }, -- Git { "gb", function() Snacks.picker.git_branches() end, desc = "Git branches" }, { "gc", function() Snacks.picker.git_log() end, desc = "Git commits" }, { "gs", function() Snacks.picker.git_status() end, desc = "Git status" }, { "gbl", function() Snacks.git.blame_line() end, desc = "Git blame line" }, -- LSP { "ds", function() Snacks.picker.lsp_symbols() end, desc = "Document symbols" }, { "ws", function() Snacks.picker.lsp_symbols({ symbols = "workspace" }) end, desc = "Workspace symbols" }, { "dws", function() Snacks.picker.lsp_symbols({ symbols = "workspace" }) end, desc = "Dynamic workspace symbols" }, { "gd", function() Snacks.picker.lsp_definitions() end, desc = "Go to definition" }, { "gr", function() Snacks.picker.lsp_references() end, desc = "Go to references" }, { "gI", function() Snacks.picker.lsp_implementations() end, desc = "Go to implementation" }, -- Utilities { "fs", function() Snacks.picker.spelling() end, desc = "Spell suggestions" }, { "fm", function() Snacks.picker.marks() end, desc = "Marks" }, { "fh", function() Snacks.picker.command_history() end, desc = "Command history" }, { "fH", function() Snacks.picker.help() end, desc = "Help tags" }, { "fk", function() Snacks.picker.keymaps() end, desc = "Keymaps" }, { ":", function() Snacks.picker.commands() end, desc = "Commands" }, -- Quickfix { "fq", function() Snacks.picker.qflist() end, desc = "Quickfix list" }, { "fl", function() Snacks.picker.loclist() end, desc = "Location list" }, -- Diagnostics { "fd", function() Snacks.picker.diagnostics() end, desc = "Diagnostics" }, -- Additional snacks features { "gg", function() Snacks.lazygit() end, desc = "Lazygit" }, { "gf", function() Snacks.lazygit.log_file() end, desc = "Lazygit log (current file)" }, { "gl", function() Snacks.lazygit.log() end, desc = "Lazygit log" }, { "un", function() Snacks.notifier.hide() end, desc = "Dismiss notifications" }, { "nh", function() Snacks.notifier.show_history() end, desc = "Notification history" }, { "", function() Snacks.terminal() end, desc = "Toggle terminal", mode = { "n", "t" } }, { "", function() Snacks.terminal() end, desc = "Toggle terminal (which_key)", mode = { "n", "t" } }, { "]]", function() Snacks.words.jump(vim.v.count1) end, desc = "Next reference", mode = { "n", "t" } }, { "[[", function() Snacks.words.jump(-vim.v.count1) end, desc = "Prev reference", mode = { "n", "t" } }, { "N", function() Snacks.notifier.show_history() end, desc = "Notification history" }, { "bd", function() Snacks.bufdelete() end, desc = "Delete buffer" }, { "cR", function() Snacks.rename.rename_file() end, desc = "Rename file" }, { "gB", function() Snacks.gitbrowse() end, desc = "Git browse" }, { "S", function() Snacks.profiler.scratch() end, desc = "Profiler scratch buffer" }, }, init = function() -- Setup notification handler immediately vim.notify = function(msg, level, opts) return Snacks.notifier.notify(msg, level, opts) end vim.api.nvim_create_autocmd("User", { pattern = "VeryLazy", callback = function() -- Create some toggle keymaps Snacks.toggle.option("spell", { name = "Spelling" }):map("us") Snacks.toggle.option("wrap", { name = "Wrap" }):map("uw") Snacks.toggle.option("relativenumber", { name = "Relative Number" }):map("uL") Snacks.toggle.diagnostics():map("ud") Snacks.toggle.line_number():map("ul") Snacks.toggle.option("conceallevel", { off = 0, on = vim.o.conceallevel > 0 and vim.o.conceallevel or 2 }) :map("uc") Snacks.toggle.treesitter():map("uT") Snacks.toggle.option("background", { off = "light", on = "dark", name = "Dark Background" }):map( "ub") Snacks.toggle.inlay_hints():map("uh") Snacks.toggle.indent():map("ug") Snacks.toggle.dim():map("uD") end, }) end, }