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 = {
|
|
["<C-n>"] = { "list_down", mode = { "i", "n" } },
|
|
["<C-p>"] = { "list_up", mode = { "i", "n" } },
|
|
["<C-j>"] = { "history_next", mode = { "i", "n" } },
|
|
["<C-k>"] = { "history_prev", mode = { "i", "n" } },
|
|
["<C-q>"] = { "qflist", mode = { "i", "n" } },
|
|
["<C-c>"] = { "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)
|
|
{ "<leader>p", function() Snacks.picker.smart() end, desc = "Find project files" },
|
|
{ "<leader>ff", function() Snacks.picker.grep() end, desc = "Live grep" },
|
|
{ "<leader>fg", function() Snacks.picker.grep() end, desc = "Live grep" },
|
|
{ "<leader>fr", function() Snacks.picker.resume() end, desc = "Resume last picker" },
|
|
{ "<leader>fb", function() Snacks.picker.buffers() end, desc = "Find buffers" },
|
|
{ "<leader>fo", function() Snacks.picker.recent() end, desc = "Find recent files" },
|
|
{ "<leader>fc", function() Snacks.picker.commands() end, desc = "Find commands" },
|
|
|
|
-- Search
|
|
{
|
|
"<leader>fw",
|
|
function()
|
|
Snacks.picker.grep_word()
|
|
end,
|
|
desc = "Grep word under cursor"
|
|
},
|
|
|
|
{
|
|
"<leader>fW",
|
|
function()
|
|
local word = vim.fn.expand("<cWORD>")
|
|
Snacks.picker.grep({ search = word })
|
|
end,
|
|
desc = "Grep WORD under cursor"
|
|
},
|
|
|
|
{
|
|
"<leader>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"
|
|
},
|
|
|
|
{
|
|
"<leader>fF",
|
|
function()
|
|
local word = vim.fn.expand("<cword>")
|
|
Snacks.picker.files({ search = word })
|
|
end,
|
|
desc = "Find file with name under cursor"
|
|
},
|
|
|
|
-- Git
|
|
{ "<leader>gb", function() Snacks.picker.git_branches() end, desc = "Git branches" },
|
|
{ "<leader>gc", function() Snacks.picker.git_log() end, desc = "Git commits" },
|
|
{ "<leader>gs", function() Snacks.picker.git_status() end, desc = "Git status" },
|
|
{ "<leader>gbl", function() Snacks.git.blame_line() end, desc = "Git blame line" },
|
|
|
|
-- LSP
|
|
{ "<leader>ds", function() Snacks.picker.lsp_symbols() end, desc = "Document symbols" },
|
|
{ "<leader>ws", function() Snacks.picker.lsp_symbols({ symbols = "workspace" }) end, desc = "Workspace symbols" },
|
|
{ "<leader>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
|
|
{ "<leader>fs", function() Snacks.picker.spelling() end, desc = "Spell suggestions" },
|
|
{ "<leader>fm", function() Snacks.picker.marks() end, desc = "Marks" },
|
|
{ "<leader>fh", function() Snacks.picker.command_history() end, desc = "Command history" },
|
|
{ "<leader>fH", function() Snacks.picker.help() end, desc = "Help tags" },
|
|
{ "<leader>fk", function() Snacks.picker.keymaps() end, desc = "Keymaps" },
|
|
{ "<leader>:", function() Snacks.picker.commands() end, desc = "Commands" },
|
|
|
|
-- Quickfix
|
|
{ "<leader>fq", function() Snacks.picker.qflist() end, desc = "Quickfix list" },
|
|
{ "<leader>fl", function() Snacks.picker.loclist() end, desc = "Location list" },
|
|
|
|
-- Diagnostics
|
|
{ "<leader>fd", function() Snacks.picker.diagnostics() end, desc = "Diagnostics" },
|
|
|
|
-- Additional snacks features
|
|
{ "<leader>gg", function() Snacks.lazygit() end, desc = "Lazygit" },
|
|
{ "<leader>gf", function() Snacks.lazygit.log_file() end, desc = "Lazygit log (current file)" },
|
|
{ "<leader>gl", function() Snacks.lazygit.log() end, desc = "Lazygit log" },
|
|
{ "<leader>un", function() Snacks.notifier.hide() end, desc = "Dismiss notifications" },
|
|
{ "<leader>nh", function() Snacks.notifier.show_history() end, desc = "Notification history" },
|
|
{ "<c-/>", function() Snacks.terminal() end, desc = "Toggle terminal", mode = { "n", "t" } },
|
|
{ "<c-_>", 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" } },
|
|
{ "<leader>N", function() Snacks.notifier.show_history() end, desc = "Notification history" },
|
|
{ "<leader>bd", function() Snacks.bufdelete() end, desc = "Delete buffer" },
|
|
{ "<leader>cR", function() Snacks.rename.rename_file() end, desc = "Rename file" },
|
|
{ "<leader>gB", function() Snacks.gitbrowse() end, desc = "Git browse" },
|
|
{ "<leader>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("<leader>us")
|
|
Snacks.toggle.option("wrap", { name = "Wrap" }):map("<leader>uw")
|
|
Snacks.toggle.option("relativenumber", { name = "Relative Number" }):map("<leader>uL")
|
|
Snacks.toggle.diagnostics():map("<leader>ud")
|
|
Snacks.toggle.line_number():map("<leader>ul")
|
|
Snacks.toggle.option("conceallevel", { off = 0, on = vim.o.conceallevel > 0 and vim.o.conceallevel or 2 })
|
|
:map("<leader>uc")
|
|
Snacks.toggle.treesitter():map("<leader>uT")
|
|
Snacks.toggle.option("background", { off = "light", on = "dark", name = "Dark Background" }):map(
|
|
"<leader>ub")
|
|
Snacks.toggle.inlay_hints():map("<leader>uh")
|
|
Snacks.toggle.indent():map("<leader>ug")
|
|
Snacks.toggle.dim():map("<leader>uD")
|
|
end,
|
|
})
|
|
end,
|
|
}
|