Files
dotfiles/config/nvim/plugin/snacks.lua
T

282 lines
14 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
require('snacks').setup({
animate = {
enabled = false,
duration = { step = 1, total = 1 },
easing = "linear",
},
bigfile = { enabled = true },
dashboard = { enabled = false },
explorer = { enabled = false },
image = {
enabled = true,
inline = false,
scale = 3, -- nil | 1 (default) | 2 | 3 | ...
doc = {
inline = true,
enabled = true,
max_width = nil,
max_height = nil,
conceal = true,
},
math = {
enabled = true,
}
},
terminal = {
bo = {
filetype = "snacks_terminal",
},
win = { style = "terminal" },
wo = {},
keys = {
q = "hide",
gf = function(self)
local f = vim.fn.findfile(vim.fn.expand("<cfile>"), "**")
if f == "" then
Snacks.notify.warn("No file under cursor")
else
self:hide()
vim.schedule(function()
vim.cmd("e " .. f)
end)
end
end,
-- term_normal = {
-- "<esc><esc>",
-- function(self)
-- self.esc_timer = self.esc_timer or (vim.uv or vim.loop).new_timer()
-- if self.esc_timer:is_active() then
-- self.esc_timer:stop()
-- vim.cmd("stopinsert")
-- else
-- self.esc_timer:start(250, 0, function() end)
-- return "<esc>"
-- end
-- end,
-- mode = "t",
-- expr = true,
-- desc = "Double escape to normal mode",
-- },
},
},
indent = { enabled = false },
notifier = {
enabled = true,
timeout = 1000,
},
picker = {
enabled = true,
layout = { preset = "ivy", layout = { position = "bottom" } },
frecency = true,
history_bonus = true,
projects = {
dev = { "~/Projects", },
},
actions = {
flash = function(picker)
require("flash").jump({
pattern = "^",
label = { after = { 0, 0 } },
search = {
mode = "search",
exclude = {
function(win)
return vim.bo[vim.api.nvim_win_get_buf(win)].filetype ~= "snacks_picker_list"
end,
},
},
action = function(match)
local idx = picker.list:row2idx(match.pos[1])
picker.list:_move(idx, true, true)
end,
})
end,
},
win = {
input = {
keys = {
['<c-e>'] = { 'layout_right', mode = { 'i', 'n' } },
["<a-s>"] = { "flash", mode = { "n", "i" } },
["s"] = { "flash" },
},
},
},
sources = {
files = {
-- add a custom action
actions = {
create_if_missing = function(picker, item)
-- When typing in the input, item may be nil.
-- We'll use the input text as the intended file path.
local input = picker.input and picker.input:get() or ""
if input == "" then return end
-- Make it relative to picker cwd if it’s not absolute
local cwd = picker.opts.cwd or vim.loop.cwd()
local path = input
if not path:match("^/") and not path:match("^%a:[/\\]") then
path = cwd .. "/" .. path
end
-- Normalize path (optional)
path = vim.fn.fnamemodify(path, ":p")
-- If file exists, just open it
if vim.loop.fs_stat(path) then
picker:close()
vim.cmd.edit(path)
return
end
-- Ensure parent dirs exist (optional but nice)
vim.fn.mkdir(vim.fn.fnamemodify(path, ":h"), "p")
-- Open a new buffer at that path (creates buffer even if file missing)
picker:close()
vim.cmd.edit(path)
-- At this point buffer is new + unnamed-on-disk until you :w
end,
},
-- bind the action to a key in the picker UI
win = {
input = {
keys = {
["<M-n>"] = { "create_if_missing", mode = { "i", "n" }, desc = "Create file from input" },
},
},
list = {
keys = {
["<M-n>"] = { "create_if_missing", mode = { "n" }, desc = "Create file from input" },
},
},
},
},
},
},
scope = { enabled = false },
scratch = {
ft = "markdown",
},
statuscolumn = { enabled = true },
styles = {
notification = {
-- wo = { wrap = true } -- Wrap notifications
}
}
})
vim.keymap.set('n', "<leader>o/", function() Snacks.picker.grep({dirs = { os.getenv("HOME") .. "/Documents/notes" }}) end, { desc = "Search Org Files" })
vim.keymap.set('n', "<leader><Space>", function() Snacks.picker.smart() end, { desc = "Smart Find Files" })
vim.keymap.set('n', "<leader>j", function() Snacks.picker.files({args = { "--no-require-git" }}) end, { desc = "Find Files" })
vim.keymap.set('n', "<leader>,", function() Snacks.picker.buffers() end, { desc = "Buffers" })
vim.keymap.set('n', "<leader>/", function() Snacks.picker.grep() end, { desc = "Grep" })
vim.keymap.set('n', "<leader>:", function() Snacks.picker.command_history() end, { desc = "Command History" })
vim.keymap.set('n', "<leader>n", function() Snacks.picker.notifications() end, { desc = "Notification History" })
vim.keymap.set('n', "<leader>i", function() Snacks.picker.lsp_symbols() end, { desc = "Symbols" })
vim.keymap.set('n', "<leader>I", function() Snacks.picker.lsp_workspace_symbols() end, { desc = "LSP Workspace Symbols" })
vim.keymap.set('n', "<leader>fb", function() Snacks.picker.buffers() end, { desc = "Buffers" })
vim.keymap.set('n', "<leader>fc", function() Snacks.picker.files({ cwd = vim.fn.stdpath("config") }) end, { desc = "Find Config File" })
vim.keymap.set('n', "<leader>ff", function() Snacks.picker.files() end, { desc = "Find Files" })
vim.keymap.set('n', "<leader>fg", function() Snacks.picker.git_files() end, { desc = "Find Git Files" })
vim.keymap.set('n', "<leader>fp", function() Snacks.picker.projects() end, { desc = "Projects" })
vim.keymap.set('n', "<leader>fr", function() Snacks.picker.recent() end, { desc = "Recent" })
vim.keymap.set('n', "<leader>gb", function() Snacks.picker.git_branches() end, { desc = "Git Branches" })
vim.keymap.set('n', "<leader>gl", function() Snacks.picker.git_log() end, { desc = "Git Log" })
vim.keymap.set('n', "<leader>gL", function() Snacks.picker.git_log_line() end, { desc = "Git Log Line" })
vim.keymap.set('n', "<leader>gs", function() Snacks.picker.git_status() end, { desc = "Git Status" })
vim.keymap.set('n', "<leader>gS", function() Snacks.picker.git_stash() end, { desc = "Git Stash" })
vim.keymap.set('n', "<leader>gd", function() Snacks.picker.git_diff() end, { desc = "Git Diff (Hunks)" })
vim.keymap.set('n', "<leader>gf", function() Snacks.picker.git_log_file() end, { desc = "Git Log File" })
vim.keymap.set('n', "<leader>sb", function() Snacks.picker.lines() end, { desc = "Buffer Lines" })
vim.keymap.set('n', "<leader>sB", function() Snacks.picker.grep_buffers() end, { desc = "Grep Open Buffers" })
vim.keymap.set('n', "<leader>sg", function() Snacks.picker.grep() end, { desc = "Grep" })
vim.keymap.set('n', '<leader>s"', function() Snacks.picker.registers() end, { desc = "Registers" })
vim.keymap.set('n', '<leader>s/', function() Snacks.picker.search_history() end, { desc = "Search History" })
vim.keymap.set('n', "<leader>sa", function() Snacks.picker.autocmds() end, { desc = "Autocmds" })
vim.keymap.set('n', "<leader>sb", function() Snacks.picker.lines() end, { desc = "Buffer Lines" })
vim.keymap.set('n', "<leader>sc", function() Snacks.picker.command_history() end, { desc = "Command History" })
vim.keymap.set('n', "<leader>sC", function() Snacks.picker.commands() end, { desc = "Commands" })
vim.keymap.set('n', "<leader>sd", function() Snacks.picker.diagnostics() end, { desc = "Diagnostics" })
vim.keymap.set('n', "<leader>sD", function() Snacks.picker.diagnostics_buffer() end, { desc = "Buffer Diagnostics" })
vim.keymap.set('n', "<leader>sh", function() Snacks.picker.help() end, { desc = "Help Pages" })
vim.keymap.set('n', "<leader>sH", function() Snacks.picker.highlights() end, { desc = "Highlights" })
vim.keymap.set('n', "<leader>si", function() Snacks.picker.icons() end, { desc = "Icons" })
vim.keymap.set('n', "<leader>sj", function() Snacks.picker.jumps() end, { desc = "Jumps" })
vim.keymap.set('n', "<leader>sk", function() Snacks.picker.keymaps() end, { desc = "Keymaps" })
vim.keymap.set('n', "<leader>sl", function() Snacks.picker.loclist() end, { desc = "Location List" })
vim.keymap.set('n', "<leader>sm", function() Snacks.picker.marks() end, { desc = "Marks" })
vim.keymap.set('n', "<leader>sM", function() Snacks.picker.man() end, { desc = "Man Pages" })
-- vim.keymap.set('n', "<leader>sp", function() Snacks.picker.lazy() end, { desc = "Search for Plugin Spec" })
vim.keymap.set('n', "<leader>sq", function() Snacks.picker.qflist() end, { desc = "Quickfix List" })
vim.keymap.set('n', "<leader>sR", function() Snacks.picker.resume() end, { desc = "Resume" })
vim.keymap.set('n', "<leader>su", function() Snacks.picker.undo() end, { desc = "Undo History" })
vim.keymap.set('n', "<leader>sz", function() Snacks.picker.zoxide() end, { desc = "Zoxide" })
vim.keymap.set('n', "<leader>uC", function() Snacks.picker.colorschemes() end, { desc = "Colorschemes" })
vim.keymap.set('n', "gd", function() Snacks.picker.lsp_definitions() end, { desc = "Goto Definition" })
vim.keymap.set('n', "gD", function() Snacks.picker.lsp_declarations() end, { desc = "Goto Declaration" })
vim.keymap.set('n', "gri", function() Snacks.picker.lsp_implementations() end, { desc = "Goto Implementation" })
vim.keymap.set('n', "gy", function() Snacks.picker.lsp_type_definitions() end, { desc = "Goto T[y]pe Definition" })
vim.keymap.set('n', "<leader>ss", function() Snacks.picker.lsp_symbols() end, { desc = "LSP Symbols" })
vim.keymap.set('n', "<leader>sS", function() Snacks.picker.lsp_workspace_symbols() end, { desc = "LSP Workspace Symbols" })
vim.keymap.set('n', "<leader>Z", function() Snacks.zen() end, { desc = "Toggle Zen Mode" })
vim.keymap.set('n', "<leader>z", function() Snacks.zen.zoom() end, { desc = "Toggle Zoom" })
vim.keymap.set('n', "<leader>.", function() Snacks.scratch() end, { desc = "Toggle Scratch Buffer" })
vim.keymap.set('n', "<leader>S", function() Snacks.scratch.select() end, { desc = "Select Scratch Buffer" })
vim.keymap.set('n', "<leader>bd", function() Snacks.bufdelete() end, { desc = "Delete Buffer" })
vim.keymap.set('n', "<leader>bR", function() Snacks.rename.rename_file() end, { desc = "Rename File" })
vim.keymap.set('n', "<leader>gg", function() Snacks.lazygit() end, { desc = "Lazygit" })
vim.keymap.set('n', "<leader>un", function() Snacks.notifier.hide() end, { desc = "Dismiss All Notifications" })
vim.keymap.set('n', "grr", function() Snacks.picker.lsp_references() end, { nowait = true, desc = "References" })
vim.keymap.set({ "n", "x" }, "<leader>sw", function() Snacks.picker.grep_word() end, { desc = "Visual selection or word" })
vim.keymap.set({ "n", "v" }, "<leader>gB", function() Snacks.gitbrowse() end, { desc = "Git Browse" })
vim.keymap.set({ "n", "t" }, "<c-_>", function() Snacks.terminal.toggle() end, { desc = "Toggle Terminal" })
vim.keymap.set({ "n", "t" }, "]]", function() Snacks.words.jump(vim.v.count1) end, { desc = "Next Reference" })
vim.keymap.set({ "n", "t" }, "[[", function() Snacks.words.jump(-vim.v.count1) end, { desc = "Prev Reference" })
vim.keymap.set('n', '<leader>xN',
function()
Snacks.win({
file = vim.api.nvim_get_runtime_file("doc/news.txt", false)[1],
width = 0.6,
height = 0.6,
wo = {
spell = false,
wrap = false,
signcolumn = "yes",
statuscolumn = " ",
conceallevel = 3,
},
})
end,
{ desc = "Neovim News" })
vim.api.nvim_create_autocmd("User", {
callback = function()
-- Setup some globals for debugging (lazy-loaded)
_G.dd = function(...)
Snacks.debug.inspect(...)
end
_G.bt = function()
Snacks.debug.backtrace()
end
vim.print = _G.dd -- Override print to use snacks for `:=` command
-- Create some toggle mappings
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,
})