feat(nvim): add PIM panel with calendar, alot mail, and abook
Adds itchyny/calendar.vim plugin and keybinds for a PIM sidebar: - r: full-screen tab with alot (top), calendar + abook (bottom split) - n/g/f: individual vsplit toggles for alot, calendar, abook - Restores <C-hjkl> window nav inside calendar buffers - shell-setup.sh installs notmuch, alot, abook (AUR) and syncs lazy.nvim Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>main
parent
867686e409
commit
00b178103e
|
|
@ -37,6 +37,7 @@ require("lazy").setup({
|
||||||
"nvim-mini/mini.icons",
|
"nvim-mini/mini.icons",
|
||||||
"tadmccorkle/markdown.nvim",
|
"tadmccorkle/markdown.nvim",
|
||||||
{ "ellisonleao/glow.nvim", config = true },
|
{ "ellisonleao/glow.nvim", config = true },
|
||||||
|
"itchyny/calendar.vim",
|
||||||
{
|
{
|
||||||
"greggh/claude-code.nvim",
|
"greggh/claude-code.nvim",
|
||||||
dependencies = { "nvim-lua/plenary.nvim" },
|
dependencies = { "nvim-lua/plenary.nvim" },
|
||||||
|
|
@ -92,6 +93,18 @@ vim.keymap.set("n", "<C-h>", "<C-w>h")
|
||||||
vim.keymap.set("n", "<C-j>", "<C-w>j")
|
vim.keymap.set("n", "<C-j>", "<C-w>j")
|
||||||
vim.keymap.set("n", "<C-k>", "<C-w>k")
|
vim.keymap.set("n", "<C-k>", "<C-w>k")
|
||||||
|
|
||||||
|
-- calendar.vim steals <C-hjkl> for month nav; restore window movement
|
||||||
|
vim.api.nvim_create_autocmd("FileType", {
|
||||||
|
pattern = "calendar",
|
||||||
|
callback = function()
|
||||||
|
local o = { buffer = true, silent = true }
|
||||||
|
vim.keymap.set("n", "<C-l>", "<C-w>w", o)
|
||||||
|
vim.keymap.set("n", "<C-h>", "<C-w>h", o)
|
||||||
|
vim.keymap.set("n", "<C-j>", "<C-w>j", o)
|
||||||
|
vim.keymap.set("n", "<C-k>", "<C-w>k", o)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
-- quick actions
|
-- quick actions
|
||||||
vim.keymap.set("n", "t", ":FloatermNew<CR>", { silent = true })
|
vim.keymap.set("n", "t", ":FloatermNew<CR>", { silent = true })
|
||||||
vim.keymap.set("n", "e", ":NERDTreeToggle<CR><C-W>l", { silent = true })
|
vim.keymap.set("n", "e", ":NERDTreeToggle<CR><C-W>l", { silent = true })
|
||||||
|
|
@ -145,3 +158,80 @@ end, { expr = true, silent = true })
|
||||||
vim.keymap.set("i", "<CR>", function()
|
vim.keymap.set("i", "<CR>", function()
|
||||||
return vim.fn["coc#pum#visible"]() == 1 and vim.fn["coc#pum#confirm"]() or "<CR>"
|
return vim.fn["coc#pum#visible"]() == 1 and vim.fn["coc#pum#confirm"]() or "<CR>"
|
||||||
end, { expr = true, silent = true })
|
end, { expr = true, silent = true })
|
||||||
|
|
||||||
|
-- ── PIM sidebar (calendar / notmuch / abook) ──────────────────────────────────
|
||||||
|
local function _pim_scratch(label, err)
|
||||||
|
vim.cmd("enew")
|
||||||
|
vim.bo.buftype = "nofile"
|
||||||
|
vim.bo.buflisted = false
|
||||||
|
vim.api.nvim_buf_set_lines(0, 0, -1, false, { "[" .. label .. " unavailable]", "", err or "" })
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _pim_close_win(win)
|
||||||
|
if not vim.api.nvim_win_is_valid(win) then return end
|
||||||
|
local buf = vim.api.nvim_win_get_buf(win)
|
||||||
|
vim.api.nvim_win_close(win, true)
|
||||||
|
if vim.api.nvim_buf_is_valid(buf) and vim.bo[buf].buftype == "terminal" then
|
||||||
|
pcall(vim.api.nvim_buf_delete, buf, { force = true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- individual toggles: n = notmuch/alot, g = calendar, f = find/abook
|
||||||
|
local _solo = {}
|
||||||
|
|
||||||
|
local function toggle_solo(key, cmd, label, width)
|
||||||
|
local win = _solo[key]
|
||||||
|
if win and vim.api.nvim_win_is_valid(win) then
|
||||||
|
_pim_close_win(win)
|
||||||
|
_solo[key] = nil
|
||||||
|
else
|
||||||
|
local prev = vim.api.nvim_get_current_win()
|
||||||
|
vim.cmd("topleft vsplit")
|
||||||
|
vim.api.nvim_win_set_width(0, width)
|
||||||
|
local ok, err = pcall(vim.cmd, cmd)
|
||||||
|
if not ok then _pim_scratch(label, err) end
|
||||||
|
_solo[key] = vim.api.nvim_get_current_win()
|
||||||
|
vim.api.nvim_set_current_win(prev)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.keymap.set("n", "n", function() toggle_solo("n", "terminal alot", "alot", 55) end, { silent = true })
|
||||||
|
vim.keymap.set("n", "g", function() toggle_solo("g", "Calendar", "calendar.vim", 35) end, { silent = true })
|
||||||
|
vim.keymap.set("n", "f", function() toggle_solo("f", "terminal abook", "abook", 80) end, { silent = true })
|
||||||
|
|
||||||
|
-- r = full-screen PIM tab (mail top, calendar bottom-left, abook bottom-right)
|
||||||
|
local _pim_tab = nil
|
||||||
|
|
||||||
|
local function toggle_pim()
|
||||||
|
if _pim_tab and vim.api.nvim_tabpage_is_valid(_pim_tab) then
|
||||||
|
vim.cmd("tabclose " .. vim.api.nvim_tabpage_get_number(_pim_tab))
|
||||||
|
_pim_tab = nil
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.cmd("tabnew")
|
||||||
|
_pim_tab = vim.api.nvim_get_current_tabpage()
|
||||||
|
|
||||||
|
-- top pane: alot (mail), full width
|
||||||
|
local ok, err = pcall(vim.cmd, "terminal alot")
|
||||||
|
if not ok then _pim_scratch("alot", err) end
|
||||||
|
|
||||||
|
-- split bottom third for calendar + abook
|
||||||
|
vim.cmd("belowright split")
|
||||||
|
vim.cmd("resize 24")
|
||||||
|
|
||||||
|
-- bottom-left: calendar
|
||||||
|
vim.cmd("leftabove vsplit")
|
||||||
|
ok, err = pcall(vim.cmd, "Calendar")
|
||||||
|
if not ok then _pim_scratch("calendar.vim", err) end
|
||||||
|
|
||||||
|
-- bottom-right: abook
|
||||||
|
vim.cmd("wincmd l")
|
||||||
|
ok, err = pcall(vim.cmd, "terminal abook")
|
||||||
|
if not ok then _pim_scratch("abook", err) end
|
||||||
|
|
||||||
|
-- focus mail
|
||||||
|
vim.cmd("wincmd k")
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.keymap.set("n", "r", toggle_pim, { silent = true })
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ log "Updating system..."
|
||||||
sudo pacman -Syu --noconfirm
|
sudo pacman -Syu --noconfirm
|
||||||
|
|
||||||
log "Installing base shell packages..."
|
log "Installing base shell packages..."
|
||||||
PACKAGES=(zsh neovim curl pyright bash atftp bash-language-server btop clang fastfetch fzf hyfetch lua-language-server micro nano pulsemixer yazi z qrencode distrobox dysk python python-pip glow)
|
PACKAGES=(zsh neovim curl pyright bash atftp bash-language-server btop clang fastfetch fzf hyfetch lua-language-server micro nano pulsemixer yazi z qrencode distrobox dysk python python-pip glow notmuch alot)
|
||||||
for pkg in "${PACKAGES[@]}"; do
|
for pkg in "${PACKAGES[@]}"; do
|
||||||
if ! pacman -Qi "$pkg" &>/dev/null; then
|
if ! pacman -Qi "$pkg" &>/dev/null; then
|
||||||
log "Installing $pkg..."
|
log "Installing $pkg..."
|
||||||
|
|
@ -16,6 +16,14 @@ for pkg in "${PACKAGES[@]}"; do
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# abook (AUR)
|
||||||
|
if ! command -v abook &>/dev/null; then
|
||||||
|
log "Installing abook (AUR)..."
|
||||||
|
yay -S --noconfirm --needed abook
|
||||||
|
else
|
||||||
|
skip "abook already installed."
|
||||||
|
fi
|
||||||
|
|
||||||
# yay
|
# yay
|
||||||
if ! command -v yay &>/dev/null; then
|
if ! command -v yay &>/dev/null; then
|
||||||
log "Installing yay..."
|
log "Installing yay..."
|
||||||
|
|
@ -64,6 +72,9 @@ cp -r ~/Dotfiles/micro ~/.config/
|
||||||
rm -rf ~/.config/nvim
|
rm -rf ~/.config/nvim
|
||||||
ln -sf ~/Dotfiles/nvim ~/.config/nvim
|
ln -sf ~/Dotfiles/nvim ~/.config/nvim
|
||||||
|
|
||||||
|
log "Syncing neovim plugins (lazy.nvim)..."
|
||||||
|
nvim --headless "+Lazy! sync" +qa 2>/dev/null || true
|
||||||
|
|
||||||
rm -rf ~/.config/yazi
|
rm -rf ~/.config/yazi
|
||||||
ln -sf ~/Dotfiles/yazi ~/.config/yazi
|
ln -sf ~/Dotfiles/yazi ~/.config/yazi
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue