diff --git a/lua/plugins/astrocore.lua b/lua/plugins/astrocore.lua index dbd418e..5127e59 100644 --- a/lua/plugins/astrocore.lua +++ b/lua/plugins/astrocore.lua @@ -18,55 +18,6 @@ local function with_trouble(source, opts) require("snacks").picker[source](opts) end --- Terminal title: " — ", 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 -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: " - 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: /.git/worktrees/ → strip back to /.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 ' — '", - 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 { [""] = { "suspend", desc = "Suspend nvim (return with 'fg')" }, ["ZZ"] = { "wqa", desc = "Save all buffers and quit Neovim" }, [""] = { "wqa", desc = "Save all buffers and quit Neovim" }, - [""] = { - function() - vim.cmd "wa" - require("snacks").bufdelete() - end, - desc = "Save and close buffer", - }, + [""] = { "wabd", 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", }, [""] = { - 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", }, ["g"] = { @@ -217,58 +189,14 @@ return { function() require("snacks").picker.lines() end, desc = "Find in line", }, - ["o"] = { function() require("snacks").gitbrowse() end, desc = "Open Repo on Web" }, + ["o"] = { "!gh repo view --web", desc = "Open Repo on Web" }, [""] = { "w", desc = "Save buffer" }, - [""] = { - function() - vim.cmd "w" - require("snacks").bufdelete() - end, - desc = "Save and close buffer", - }, + [""] = { "wbd", desc = "Save and close buffer" }, [""] = { "tabnext", desc = "Next Tab" }, - [""] = { - function() require("snacks").picker.gh_issue() end, - desc = "GitHub issues (open)", - }, - [""] = { - function() require("snacks").picker.gh_pr() end, - desc = "GitHub PRs (open)", - }, - ["I"] = { - function() require("snacks").picker.gh_issue { state = "all" } end, - desc = "GitHub issues (all)", - }, - ["P"] = { - function() require("snacks").picker.gh_pr { state = "all" } end, - desc = "GitHub PRs (all)", - }, - -- which-key prefix group labels - [""] = { desc = "Git + GitHub" }, - [""] = { desc = "Find" }, - [""] = { desc = "Buffers" }, - [""] = { desc = "Assist" }, - -- ghq project switcher (previously a dashboard action) - ["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", - }, - [""] = { - function() require("snacks").lazygit() end, - desc = "Toggle lazygit (float)", - }, - [""] = { - function() require("snacks").terminal.toggle("lazydocker", { win = { style = "float" } }) end, - desc = "Toggle lazydocker (float)", - }, - [""] = { "Scooter", desc = "Find & replace (scooter)" }, + [""] = { "Octo issue list", desc = "List Issues" }, + [""] = { "Octo label", desc = "Manage Labels" }, + [""] = { "Octo pr list", desc = "List PRs" }, + ["s"] = { "Octo search", desc = "Octo Search" }, [""] = { "!gh release list", desc = "List Releases" }, ["d"] = { function() require("snacks").picker.git_diff() end, @@ -474,38 +402,12 @@ return { }, i = { [""] = { "wa", desc = "Save buffer, and return to normal mode" }, - [""] = { - function() - vim.cmd "stopinsert" - vim.cmd "wa" - require("snacks").bufdelete() - end, - desc = "Save, close buffer, and return to normal mode", - }, - [""] = { - function() - vim.cmd "stopinsert" - vim.cmd "wa" - require("snacks").bufdelete() - end, - desc = "Save, close buffer, and return to normal mode", - }, + [""] = { "wabd", desc = "Save, close buffer, and return to normal mode" }, + [""] = { "wabd", desc = "Save, close buffer, and return to normal mode" }, }, v = { - [""] = { - function() - vim.cmd "w" - require("snacks").bufdelete() - end, - desc = "Save and close buffer", - }, - [""] = { - function() - vim.cmd "w" - require("snacks").bufdelete() - end, - desc = "Save and close buffer", - }, + [""] = { "wbd", desc = "Save and close buffer" }, + [""] = { "wbd", desc = "Save and close buffer" }, ["D"] = { function() vim.cmd 'normal! "vy' diff --git a/lua/plugins/user.lua b/lua/plugins/user.lua index fce41a9..71bf325 100644 --- a/lua/plugins/user.lua +++ b/lua/plugins/user.lua @@ -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: 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 (`` 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" }, }, }, }, diff --git a/lua/plugins/yazi.lua b/lua/plugins/yazi.lua deleted file mode 100644 index 749a18f..0000000 --- a/lua/plugins/yazi.lua +++ /dev/null @@ -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 "created a new tab for the workspace". Instead, ---- lua/config/yazi_session.lua keeps ONE yazi process alive in a snacks ---- terminal and just hides/shows it — same session, same tabs. ---- File opens come back via ~/.local/bin/yazi-nvim-open -> _G.EditFromYazi ---- (edit / vsplit / 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 = { - [""] = { - function() require("config.yazi_session").toggle() end, - desc = "Toggle yazi (persistent session)", - }, - ["-"] = { - function() require("config.yazi_session").open_current() end, - desc = "Open yazi at the current file", - }, - ["o"] = { - function() require("config.yazi_session").open_current() end, - desc = "Open Explorer (yazi at current file)", - }, - ["cw"] = { - function() require("config.yazi_session").open(vim.uv.cwd()) end, - desc = "Open yazi in nvim's working directory", - }, - }, - v = { - [""] = { - function() require("config.yazi_session").toggle() end, - desc = "Toggle yazi (persistent session)", - }, - }, - t = { - [""] = { - 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 }, -}