Files
dotfiles/config/nvim/lua/plugins/ui.lua
T
branderson 0f3e2c8362 Add cowsay/fortune, auto-open Claude Code, and a shared scratch volume to sandbox
cowsay/cowthink/fortune install to /usr/games on Debian, not on this image's
PATH by default - added the packages and extended PATH via ENV so nvim's
start-screen header (plugins/ui.lua) can actually find them as non-login
subprocesses. That surfaced a real, pre-existing bug in ui.lua itself
(unrelated to the sandbox): `cowsay -l` wraps cow names across multiple
space-separated lines after a header line, but the code treated each whole
line as a single cow name, so a wrapped line got passed to cowthink -f as
one bogus multi-word argument. Fixed to parse every name from every line.
Verified directly against the real cowsay/fortune installed in the image.

The sandbox now opens claudecode.nvim's terminal on startup (CLAUDE_SANDBOX-
gated, so this doesn't affect normal host nvim use) instead of requiring
<leader>ac - starting a Claude session is the point of being in there.
:ClaudeCode is only defined once the plugin loads (it's lazy-loaded on that
keymap, no `cmd` in its spec), so the autocmd force-loads it first.

Also adds an optional read-write scratch volume (~/shared in the container,
$SANDBOX_SHARE_DIR on the host, auto-created) separate from the project
mount, for passing files back and forth with a sandboxed session without
touching the actual project checkout. Mentioned in sandbox-context.sh so a
sandboxed agent knows it's there.
2026-07-19 19:11:12 -07:00

102 lines
2.9 KiB
Lua

return {
{
"ellisonleao/gruvbox.nvim",
priority = 1000,
opts = {
italic = { strings = true, comments = true, operators = false, folds = true },
invert_selection = true,
invert_signs = false,
},
config = function(_, opts)
require("gruvbox").setup(opts)
vim.o.background = "dark"
local ok = pcall(vim.cmd.colorscheme, "gruvbox")
if not ok then
vim.cmd.colorscheme("desert")
end
end,
},
{
"nvim-lualine/lualine.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
event = "VeryLazy",
opts = {
options = { theme = "gruvbox" },
},
},
{
"akinsho/bufferline.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
event = "VeryLazy",
opts = {},
},
{
"lukas-reineke/indent-blankline.nvim",
main = "ibl",
event = { "BufReadPost", "BufNewFile" },
opts = {},
},
{
"HiPhish/rainbow-delimiters.nvim",
event = { "BufReadPost", "BufNewFile" },
},
{ "nvim-tree/nvim-web-devicons", opts = {} },
{
"goolord/alpha-nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
event = "VimEnter",
config = function()
local alpha = require("alpha")
local dashboard = require("alpha.themes.dashboard")
local function fortune_header()
-- cowsay -l prints a header line, then wraps every cow name across
-- several space-separated lines (not one name per line), so a name
-- has to be picked from all of them split on whitespace, not by
-- treating a whole (possibly multi-name) line as one name.
local raw = vim.fn.systemlist("cowsay -l")
local cow = "default"
local names = {}
for i = 2, #raw do
for name in raw[i]:gmatch("%S+") do
table.insert(names, name)
end
end
if #names > 0 then
cow = names[math.random(#names)]
end
local moods = { "b", "d", "g", "p", "s", "t", "w", "y" }
local mood = moods[math.random(#moods)]
local cmd = string.format(
"fortune -a -s | fmt -80 -s | cowthink -%s -f %s -n",
mood,
cow
)
local ok, lines = pcall(vim.fn.systemlist, cmd)
if not ok or #lines == 0 then
return { "Welcome to Neovim" }
end
return lines
end
dashboard.section.header.val = fortune_header()
dashboard.section.buttons.val = {
dashboard.button("e", " New file", ":enew<CR>"),
dashboard.button("f", " Find file", ":Telescope find_files<CR>"),
dashboard.button("g", " Live grep", ":Telescope live_grep<CR>"),
dashboard.button("s", " Restore session", ":lua require('persistence').load()<CR>"),
dashboard.button("q", " Quit", ":qa<CR>"),
}
alpha.setup(dashboard.opts)
vim.keymap.set("n", "<leader><leader>o", ":Alpha<CR>")
end,
},
}