From b4b165fb9611b550d998329290acebc3ad643cf1 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Thu, 23 Oct 2025 23:06:06 -0400 Subject: [PATCH] feat(lua): add custom startup picker and snacks configuration --- lua/plugins/astrocore.lua | 71 +++++++++++++++++++++++++++ lua/plugins/bufferline.lua | 98 ++++++++++++++++++-------------------- lua/plugins/snacks.lua | 53 +++++++++++++++++++++ 3 files changed, 171 insertions(+), 51 deletions(-) create mode 100644 lua/plugins/snacks.lua diff --git a/lua/plugins/astrocore.lua b/lua/plugins/astrocore.lua index 55e210e..2d07513 100644 --- a/lua/plugins/astrocore.lua +++ b/lua/plugins/astrocore.lua @@ -16,6 +16,7 @@ return { "AstroNvim/astrocore", ---@type AstroCoreOpts opts = { + sessions = { -- Configure auto saving autosave = { @@ -104,6 +105,76 @@ return { end, }, }, + -- Show recent files or git repos on startup + startup_picker = { + { + event = "VimEnter", + desc = "Show recent files for git repo or git repos picker on startup", + callback = function() + -- Skip if opening with arguments (files, directories, stdin) + if vim.fn.argc() > 0 then return end + + -- Skip if current buffer has content + local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) + if #lines > 1 or (#lines == 1 and lines[1] ~= "") then return end + + -- Delay to ensure everything is loaded + vim.defer_fn(function() + -- Check if we're in a git repo + local git_dir = vim.fn.systemlist("git rev-parse --git-dir 2>/dev/null")[1] + local is_git_repo = vim.v.shell_error == 0 and git_dir ~= nil and git_dir ~= "" + + if is_git_repo then + -- In a git repo: show recent files + require("snacks").picker.recent() + else + -- Not in a git repo: show git repos using ghq + if vim.fn.executable "ghq" == 1 then + -- Get list of repos from ghq + local repos = vim.fn.systemlist "ghq list --full-path" + if #repos > 0 then + -- Build items list with formatted display + local items = {} + for _, repo_path in ipairs(repos) do + -- Extract org/repo from path + local display = repo_path:match "github%.com/([^/]+/[^/]+)" or vim.fn.fnamemodify(repo_path, ":t") + table.insert(items, { + text = display, + path = repo_path, + }) + end + + -- Use snacks picker to show repos + require("snacks").picker({ + title = "Git Repositories", + layout = { preview = false }, + items = items, + format = function(item) + return { { item.text } } + end, + confirm = function(picker, item) + picker:close() + -- Change to the selected repo directory + vim.cmd("cd " .. item.path) + -- Show recent files from the new directory + vim.defer_fn(function() + require("snacks").picker.recent() + end, 50) + end, + }) + else + -- Fallback to recent files if no repos found + require("snacks").picker.recent() + end + else + -- ghq not available, just show recent files + require("snacks").picker.recent() + end + end + end, 10) + end, + }, + }, }, -- vim options can be configured here diff --git a/lua/plugins/bufferline.lua b/lua/plugins/bufferline.lua index d52e35c..1c9b25e 100644 --- a/lua/plugins/bufferline.lua +++ b/lua/plugins/bufferline.lua @@ -1,59 +1,55 @@ --- Bufferline configuration with AstroNvim integration ---- Provides enhanced buffer/tab management with diagnostics and custom close handlers +--- Overrides and customizations for bufferline.nvim +--- Relies on astrocommunity.bars-and-lines.bufferline-nvim for base setup --- @module plugins.bufferline ---@type LazySpec return { "akinsho/bufferline.nvim", - version = "*", - dependencies = { "nvim-tree/nvim-web-devicons", "AstroNvim/astrocore" }, - event = "VeryLazy", - config = function() - local bufferline = require "bufferline" - local groups = require "bufferline.groups" - - bufferline.setup { - options = { - mode = "buffers", - numbers = "none", - close_command = function(n) require("astrocore.buffer").close(n) end, - right_mouse_command = function(n) require("astrocore.buffer").close(n) end, - separator_style = "thick", - indicator = { style = "none", icon = "" }, - diagnostics = "nvim_lsp", - diagnostics_indicator = function(_, _, diagnostics_dict) - local s = " " - for e, _ in pairs(diagnostics_dict) do - local sym = e == "error" and " " or (e == "warning" and " " or " ") - s = s .. sym - end - return s - end, - always_show_bufferline = true, - show_buffer_close_icons = true, - show_close_icon = true, - modified_icon = "●", - buffer_close_icon = "󰅖", - close_icon = "", - left_trunc_marker = "", - right_trunc_marker = "", - offsets = { - { filetype = "snacks_picker", text = "", padding = 0 }, - }, + opts = { + options = { + mode = "buffers", + numbers = "none", + -- Use AstroCore buffer close handler for proper cleanup + close_command = function(n) require("astrocore.buffer").close(n) end, + right_mouse_command = function(n) require("astrocore.buffer").close(n) end, + separator_style = "thick", + indicator = { style = "none", icon = "" }, + diagnostics = "nvim_lsp", + diagnostics_indicator = function(_, _, diagnostics_dict) + local s = " " + for e, _ in pairs(diagnostics_dict) do + local sym = e == "error" and " " or (e == "warning" and " " or " ") + s = s .. sym + end + return s + end, + always_show_bufferline = true, + show_buffer_close_icons = true, + show_close_icon = true, + modified_icon = "●", + buffer_close_icon = "󰅖", + close_icon = "", + left_trunc_marker = "", + right_trunc_marker = "", + -- Offset for snacks picker to prevent overlap + offsets = { + { filetype = "snacks_picker", text = "", padding = 0 }, + { filetype = "neo-tree", text = "", padding = 0 }, }, - highlights = { - group_label = { fg = "#ffffff", bg = "#423f5a", bold = true }, - group_separator = { fg = "#585b70" }, - buffer_selected = { fg = "#89dceb", bold = true }, - buffer_visible = { fg = "#585b70" }, - background = { fg = "#585b70" }, - hint = { fg = "#94e2d5" }, - hint_selected = { fg = "#94e2d5", bold = true }, - warning = { fg = "#f9e2af" }, - warning_selected = { fg = "#f9e2af", bold = true }, - error = { fg = "#f38ba8" }, - error_selected = { fg = "#f38ba8", bold = true }, - }, - } - end, + }, + highlights = { + group_label = { fg = "#ffffff", bg = "#423f5a", bold = true }, + group_separator = { fg = "#585b70" }, + buffer_selected = { fg = "#89dceb", bold = true }, + buffer_visible = { fg = "#585b70" }, + background = { fg = "#585b70" }, + hint = { fg = "#94e2d5" }, + hint_selected = { fg = "#94e2d5", bold = true }, + warning = { fg = "#f9e2af" }, + warning_selected = { fg = "#f9e2af", bold = true }, + error = { fg = "#f38ba8" }, + error_selected = { fg = "#f38ba8", bold = true }, + }, + }, } diff --git a/lua/plugins/snacks.lua b/lua/plugins/snacks.lua new file mode 100644 index 0000000..6f358fe --- /dev/null +++ b/lua/plugins/snacks.lua @@ -0,0 +1,53 @@ +--- Snacks.nvim configuration +--- Overrides and customizations for snacks.nvim features +--- Relies on astrocommunity.recipes.telescope-nvim-snacks for base setup +--- @module plugins.snacks + +return { + "folke/snacks.nvim", + opts = { + -- Disable dashboard - we use custom startup picker in astrocore.lua + dashboard = { enabled = false }, + + -- Enable snacks features we use throughout config + bigfile = { enabled = true }, + input = { enabled = true }, + notifier = { enabled = true }, + picker = { enabled = true }, + quickfile = { enabled = true }, + rename = { enabled = true }, + scope = { enabled = true }, + scroll = { enabled = true }, + statuscolumn = { enabled = true }, + terminal = { enabled = true }, + words = { enabled = true }, + indent = { enabled = true }, + + -- Terminal styles + styles = { + terminal = { + bo = { filetype = "snacks_terminal" }, + wo = {}, + keys = { + q = "hide", + term_normal = { + "", + 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(200, 0, function() end) + return "" + end + end, + mode = "t", + expr = true, + desc = "Double escape to normal mode", + }, + }, + }, + }, + }, +}