feat(plugins): add dashboard, Octo shortcuts, and simplify title handling
This commit is contained in:
1 parent
90f8f0bd64
commit
ee5fb43c00
3 files changed
+81
-255
No files matched your search
+42
-140
@@ -18,55 +18,6 @@ local function with_trouble(source, opts)
|
||||
require("snacks").picker[source](opts)
|
||||
end
|
||||
|
||||
-- Terminal title: "<file> — <org/repo>", derived from the buffer's git remote
|
||||
-- (works for any clone location, not just ghq paths). Cached per git root.
|
||||
local repo_label_cache = {} ---@type table<string, string|false>
|
||||
local function repo_label(path)
|
||||
local root = vim.fs.root(path, ".git")
|
||||
if not root then return nil end
|
||||
local cached = repo_label_cache[root]
|
||||
if cached ~= nil then return cached or nil end
|
||||
local label = nil
|
||||
local gitdir = root .. "/.git"
|
||||
local stat = vim.uv.fs_stat(gitdir)
|
||||
if stat and stat.type == "file" then -- worktree/submodule: "gitdir: <path>"
|
||||
local f = io.open(gitdir)
|
||||
if f then
|
||||
local line = f:read "*l" or ""
|
||||
f:close()
|
||||
local target = line:match "^gitdir:%s*(.+)$"
|
||||
if target then
|
||||
if not target:match "^/" then target = root .. "/" .. target end
|
||||
-- worktrees: <common>/.git/worktrees/<name> → strip back to <common>/.git
|
||||
gitdir = target:gsub("/worktrees/[^/]+$", "")
|
||||
end
|
||||
end
|
||||
end
|
||||
local f = io.open(gitdir .. "/config")
|
||||
if f then
|
||||
for line in f:lines() do
|
||||
local url = line:match "^%s*url%s*=%s*(%S+)"
|
||||
if url then
|
||||
label = url:match "[:/]([^/:]+/[^/]+)%.git$" or url:match "[:/]([^/:]+/[^/]+)$"
|
||||
if label then break end
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
repo_label_cache[root] = label or false
|
||||
return label
|
||||
end
|
||||
|
||||
local function set_title(buf)
|
||||
if vim.bo[buf].buftype ~= "" then return end -- keep last title in pickers/terminals
|
||||
local filepath = vim.api.nvim_buf_get_name(buf)
|
||||
local filename = vim.fs.basename(filepath)
|
||||
local label = repo_label(filepath ~= "" and filepath or assert(vim.uv.cwd()))
|
||||
or vim.fs.basename(assert(vim.uv.cwd()))
|
||||
local title = (filename ~= "" and filename .. " — " or "") .. label
|
||||
vim.o.titlestring = title:gsub("%%", "%%%%") -- '%' is a statusline escape in titlestring
|
||||
end
|
||||
|
||||
return {
|
||||
"AstroNvim/astrocore",
|
||||
---@type AstroCoreOpts
|
||||
@@ -126,8 +77,30 @@ return {
|
||||
custom_title = {
|
||||
{
|
||||
event = { "BufEnter", "DirChanged" },
|
||||
desc = "Set terminal title to '<file> — <org/repo>'",
|
||||
callback = function(args) set_title(args.buf) end,
|
||||
desc = "Update terminal title with org/repo format",
|
||||
callback = function()
|
||||
local filepath = vim.fn.expand "%:p"
|
||||
local filename = vim.fn.expand "%:t"
|
||||
|
||||
if filename == "" then
|
||||
local cwd = vim.fn.getcwd()
|
||||
local github_match = cwd:match "github%.com/([^/]+/[^/]+)"
|
||||
if github_match then
|
||||
vim.opt.titlestring = github_match
|
||||
else
|
||||
vim.opt.titlestring = "Nvim"
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local github_match = filepath:match "github%.com/([^/]+/[^/]+)"
|
||||
|
||||
if github_match then
|
||||
vim.opt.titlestring = string.format("%s | %s", filename, github_match)
|
||||
else
|
||||
vim.opt.titlestring = string.format("%s | Nvim", filename)
|
||||
end
|
||||
end,
|
||||
},
|
||||
},
|
||||
restore_session = {
|
||||
@@ -156,7 +129,7 @@ return {
|
||||
clipboard = "unnamedplus",
|
||||
title = true,
|
||||
titlestring = "",
|
||||
laststatus = 3, -- global statusline (custom heirline in heirline.lua)
|
||||
laststatus = 0,
|
||||
},
|
||||
g = {},
|
||||
},
|
||||
@@ -168,13 +141,7 @@ return {
|
||||
["<C-!>"] = { "<Cmd>suspend<CR>", desc = "Suspend nvim (return with 'fg')" },
|
||||
["ZZ"] = { "<Cmd>wqa<CR>", desc = "Save all buffers and quit Neovim" },
|
||||
["<A-q>"] = { "<Cmd>wqa<CR>", desc = "Save all buffers and quit Neovim" },
|
||||
["<C-c>"] = {
|
||||
function()
|
||||
vim.cmd "wa"
|
||||
require("snacks").bufdelete()
|
||||
end,
|
||||
desc = "Save and close buffer",
|
||||
},
|
||||
["<C-c>"] = { "<Cmd>wa<CR><Cmd>bd<CR>", desc = "Save and close buffer" },
|
||||
["F"] = { "za", desc = "Toggle fold under cursor" },
|
||||
-- v6: vim.diagnostic.goto_next/goto_prev deprecated in 0.11, use jump()
|
||||
["J"] = {
|
||||
@@ -201,7 +168,12 @@ return {
|
||||
desc = "Find buffers",
|
||||
},
|
||||
["<C-b><C-c>"] = {
|
||||
function() require("snacks").bufdelete.other() end,
|
||||
function()
|
||||
local current_buffer = vim.api.nvim_get_current_buf()
|
||||
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if buf ~= current_buffer then vim.api.nvim_buf_delete(buf, { force = true }) end
|
||||
end
|
||||
end,
|
||||
desc = "Close all buffers except the current one",
|
||||
},
|
||||
["<C-b>g"] = {
|
||||
@@ -217,58 +189,14 @@ return {
|
||||
function() require("snacks").picker.lines() end,
|
||||
desc = "Find in line",
|
||||
},
|
||||
["<C-g>o"] = { function() require("snacks").gitbrowse() end, desc = "Open Repo on Web" },
|
||||
["<C-g>o"] = { "<cmd>!gh repo view --web<CR>", desc = "Open Repo on Web" },
|
||||
["<C-s>"] = { "<cmd>w<CR>", desc = "Save buffer" },
|
||||
["<C-w>"] = {
|
||||
function()
|
||||
vim.cmd "w"
|
||||
require("snacks").bufdelete()
|
||||
end,
|
||||
desc = "Save and close buffer",
|
||||
},
|
||||
["<C-w>"] = { "<cmd>w<CR><Cmd>bd<CR>", desc = "Save and close buffer" },
|
||||
["<C-Tab>"] = { "<cmd>tabnext<CR>", desc = "Next Tab" },
|
||||
["<C-g><C-i>"] = {
|
||||
function() require("snacks").picker.gh_issue() end,
|
||||
desc = "GitHub issues (open)",
|
||||
},
|
||||
["<C-g><C-p>"] = {
|
||||
function() require("snacks").picker.gh_pr() end,
|
||||
desc = "GitHub PRs (open)",
|
||||
},
|
||||
["<C-g>I"] = {
|
||||
function() require("snacks").picker.gh_issue { state = "all" } end,
|
||||
desc = "GitHub issues (all)",
|
||||
},
|
||||
["<C-g>P"] = {
|
||||
function() require("snacks").picker.gh_pr { state = "all" } end,
|
||||
desc = "GitHub PRs (all)",
|
||||
},
|
||||
-- which-key prefix group labels
|
||||
["<C-g>"] = { desc = "Git + GitHub" },
|
||||
["<C-f>"] = { desc = "Find" },
|
||||
["<C-b>"] = { desc = "Buffers" },
|
||||
["<C-a>"] = { desc = "Assist" },
|
||||
-- ghq project switcher (previously a dashboard action)
|
||||
["<C-f>P"] = {
|
||||
function()
|
||||
local repos = vim.fn.systemlist "ghq list -p"
|
||||
vim.ui.select(repos, { prompt = "Select repository" }, function(dir)
|
||||
if not dir then return end
|
||||
vim.cmd.cd(dir)
|
||||
require("snacks").picker.files()
|
||||
end)
|
||||
end,
|
||||
desc = "Find ghq projects",
|
||||
},
|
||||
["<C-g><C-g>"] = {
|
||||
function() require("snacks").lazygit() end,
|
||||
desc = "Toggle lazygit (float)",
|
||||
},
|
||||
["<C-d><C-d>"] = {
|
||||
function() require("snacks").terminal.toggle("lazydocker", { win = { style = "float" } }) end,
|
||||
desc = "Toggle lazydocker (float)",
|
||||
},
|
||||
["<C-r>"] = { "<Cmd>Scooter<CR>", desc = "Find & replace (scooter)" },
|
||||
["<C-g><C-i>"] = { "<cmd>Octo issue list<CR>", desc = "List Issues" },
|
||||
["<C-g><C-l>"] = { "<cmd>Octo label<CR>", desc = "Manage Labels" },
|
||||
["<C-g><C-p>"] = { "<cmd>Octo pr list<CR>", desc = "List PRs" },
|
||||
["<C-g>s"] = { "<cmd>Octo search<CR>", desc = "Octo Search" },
|
||||
["<C-g><C-r>"] = { "<cmd>!gh release list<CR>", desc = "List Releases" },
|
||||
["<C-g>d"] = {
|
||||
function() require("snacks").picker.git_diff() end,
|
||||
@@ -474,38 +402,12 @@ return {
|
||||
},
|
||||
i = {
|
||||
["<C-s>"] = { "<Cmd>wa<CR><Esc>", desc = "Save buffer, and return to normal mode" },
|
||||
["<C-c>"] = {
|
||||
function()
|
||||
vim.cmd "stopinsert"
|
||||
vim.cmd "wa"
|
||||
require("snacks").bufdelete()
|
||||
end,
|
||||
desc = "Save, close buffer, and return to normal mode",
|
||||
},
|
||||
["<C-x>"] = {
|
||||
function()
|
||||
vim.cmd "stopinsert"
|
||||
vim.cmd "wa"
|
||||
require("snacks").bufdelete()
|
||||
end,
|
||||
desc = "Save, close buffer, and return to normal mode",
|
||||
},
|
||||
["<C-c>"] = { "<Cmd>wa<CR><Cmd>bd<CR><Esc>", desc = "Save, close buffer, and return to normal mode" },
|
||||
["<C-x>"] = { "<Cmd>wa<CR><Cmd>bd<CR><Esc>", desc = "Save, close buffer, and return to normal mode" },
|
||||
},
|
||||
v = {
|
||||
["<C-c>"] = {
|
||||
function()
|
||||
vim.cmd "w"
|
||||
require("snacks").bufdelete()
|
||||
end,
|
||||
desc = "Save and close buffer",
|
||||
},
|
||||
["<C-x>"] = {
|
||||
function()
|
||||
vim.cmd "w"
|
||||
require("snacks").bufdelete()
|
||||
end,
|
||||
desc = "Save and close buffer",
|
||||
},
|
||||
["<C-c>"] = { "<Cmd>w<CR><Cmd>bd<CR>", desc = "Save and close buffer" },
|
||||
["<C-x>"] = { "<Cmd>w<CR><Cmd>bd<CR>", desc = "Save and close buffer" },
|
||||
["D"] = {
|
||||
function()
|
||||
vim.cmd 'normal! "vy'
|
||||
|
||||
+39
-29
@@ -1,5 +1,4 @@
|
||||
--- User plugins: cursor animation and the central snacks.nvim configuration
|
||||
--- (all snacks modules are configured here in one snacks.Config table)
|
||||
--- User plugins: cursor animation and snacks.nvim (picker + dashboard) customization
|
||||
|
||||
-- Confirm action for file-opening pickers: <CR> opens the selection as a
|
||||
-- tab via `tabdrop` (:tab drop semantics — focus the buffer if it's already
|
||||
@@ -44,42 +43,53 @@ end
|
||||
return {
|
||||
{ "sphamba/smear-cursor.nvim", opts = {} },
|
||||
|
||||
-- AstroNvim CORE ships toggleterm (astronvim/plugins/toggleterm.lua);
|
||||
-- terminals are handled by kitty + snacks.terminal/external-tui instead
|
||||
-- terminals are handled by kitty now
|
||||
{ "akinsho/toggleterm.nvim", enabled = false },
|
||||
|
||||
-- pulled in by astrocommunity.pack.typescript; only ever loaded by
|
||||
-- neo-tree/nvim-tree (both removed; yazi runs as a plain snacks terminal)
|
||||
{ "antosha417/nvim-lsp-file-operations", enabled = false },
|
||||
|
||||
{
|
||||
"folke/snacks.nvim",
|
||||
---@type snacks.Config
|
||||
opts = {
|
||||
-- dashboard discarded in favor of session management: the astrocore
|
||||
-- restore_session autocmd resumes the cwd dirsession on startup and
|
||||
-- sessions.autosave persists it on exit
|
||||
dashboard = { enabled = false },
|
||||
|
||||
-- GitHub issue/PR pickers and buffers (`<C-g>` binds in astrocore.lua)
|
||||
gh = {},
|
||||
|
||||
-- auto-highlight LSP references of the symbol under the cursor;
|
||||
-- ]] / [[ jump binds live in polish.lua (Snacks.keymap, LSP-gated)
|
||||
words = { enabled = true },
|
||||
|
||||
picker = {
|
||||
jump = { reuse_win = true },
|
||||
sources = picker_sources,
|
||||
},
|
||||
|
||||
styles = {
|
||||
-- right-hand 30% split used by :Scooter (external-tui snacks terminal)
|
||||
scooter = {
|
||||
position = "right",
|
||||
width = 0.3,
|
||||
height = 0,
|
||||
border = "none",
|
||||
dashboard = {
|
||||
enabled = true,
|
||||
preset = {
|
||||
-- "prdlk.nvim" in ansi_regular block style
|
||||
header = table.concat({
|
||||
"██████ ██████ ██████ ██ ██ ██ ███ ██ ██ ██ ██ ███ ███",
|
||||
"██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ████ ████",
|
||||
"██████ ██████ ██ ██ ██ █████ ██ ██ ██ ██ ██ ██ ██ ████ ██",
|
||||
"██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██",
|
||||
"██ ██ ██ ██████ ███████ ██ ██ ██ ██ ████ ████ ██ ██ ██",
|
||||
}, "\n"),
|
||||
},
|
||||
sections = {
|
||||
{ section = "header" },
|
||||
{ section = "keys", gap = 1, padding = 1 },
|
||||
{
|
||||
icon = " ",
|
||||
desc = "Browse Repo",
|
||||
padding = 1,
|
||||
key = "b",
|
||||
action = function() Snacks.gitbrowse() end,
|
||||
},
|
||||
{
|
||||
icon = " ",
|
||||
desc = "Projects (ghq)",
|
||||
padding = 1,
|
||||
key = "p",
|
||||
action = function()
|
||||
local repos = vim.fn.systemlist "ghq list -p"
|
||||
vim.ui.select(repos, { prompt = "Select repository" }, function(dir)
|
||||
if not dir then return end
|
||||
vim.cmd.cd(dir)
|
||||
Snacks.picker.files()
|
||||
end)
|
||||
end,
|
||||
},
|
||||
{ section = "startup" },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
--- Yazi as the default file manager (persistent session, full neo-tree
|
||||
--- replacement). yazi.nvim was removed: it spawns a NEW yazi process on
|
||||
--- every toggle (only the last-hovered path survives), so tab arrangements
|
||||
--- were lost and each <C-e> "created a new tab for the workspace". Instead,
|
||||
--- lua/config/yazi_session.lua keeps ONE yazi process alive in a snacks
|
||||
--- terminal and <C-e> just hides/shows it — same session, same tabs.
|
||||
--- File opens come back via ~/.local/bin/yazi-nvim-open -> _G.EditFromYazi
|
||||
--- (edit / <C-v> vsplit / <C-x> split, bound yazi-side in keymap.toml).
|
||||
---@type LazySpec
|
||||
return {
|
||||
{
|
||||
"folke/snacks.nvim",
|
||||
opts = {
|
||||
styles = {
|
||||
-- fullscreen borderless float for the yazi session terminal
|
||||
yazi = {
|
||||
position = "float",
|
||||
width = 0,
|
||||
height = 0,
|
||||
border = "none",
|
||||
backdrop = false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"AstroNvim/astrocore",
|
||||
opts = {
|
||||
mappings = {
|
||||
n = {
|
||||
["<C-e>"] = {
|
||||
function() require("config.yazi_session").toggle() end,
|
||||
desc = "Toggle yazi (persistent session)",
|
||||
},
|
||||
["<Leader>-"] = {
|
||||
function() require("config.yazi_session").open_current() end,
|
||||
desc = "Open yazi at the current file",
|
||||
},
|
||||
["<Leader>o"] = {
|
||||
function() require("config.yazi_session").open_current() end,
|
||||
desc = "Open Explorer (yazi at current file)",
|
||||
},
|
||||
["<Leader>cw"] = {
|
||||
function() require("config.yazi_session").open(vim.uv.cwd()) end,
|
||||
desc = "Open yazi in nvim's working directory",
|
||||
},
|
||||
},
|
||||
v = {
|
||||
["<C-e>"] = {
|
||||
function() require("config.yazi_session").toggle() end,
|
||||
desc = "Toggle yazi (persistent session)",
|
||||
},
|
||||
},
|
||||
t = {
|
||||
["<C-e>"] = {
|
||||
function() require("config.yazi_session").toggle() end,
|
||||
desc = "Toggle yazi (persistent session)",
|
||||
},
|
||||
},
|
||||
},
|
||||
autocmds = {
|
||||
-- netrw is disabled in lazy_setup.lua (performance.rtp.disabled_plugins);
|
||||
-- directory buffers (nvim . / :e dir) open in the yazi session instead
|
||||
yazi_dir_hijack = {
|
||||
{
|
||||
event = "BufEnter",
|
||||
desc = "Open directory buffers in the yazi session",
|
||||
callback = function(args)
|
||||
local path = vim.api.nvim_buf_get_name(args.buf)
|
||||
if path == "" or vim.fn.isdirectory(path) == 0 then return end
|
||||
vim.bo[args.buf].bufhidden = "wipe"
|
||||
vim.schedule(function()
|
||||
if vim.api.nvim_get_current_buf() == args.buf then vim.cmd.enew() end
|
||||
require("config.yazi_session").open(path)
|
||||
end)
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
-- neo-tree is fully replaced by the yazi session
|
||||
{ "nvim-neo-tree/neo-tree.nvim", enabled = false },
|
||||
}
|
||||
Reference in new issue
Block a user