## Enhanced man function following Prime Directive principles - **Durable**: Robust cross-terminal support (kitty/tmux/iTerm) - **Thoughtful**: Optimal 60/40 split (~100 chars CLI, ~64 chars reading) - **Lasting**: Clean code, proper error handling, graceful fallbacks ### Key Features - Beautiful syntax highlighting with Nord theme - Responsive width adaptation via MANWIDTH - Kitty remote control with proper resize shortcuts - Clean traditional appearance (no line numbers) - Stays open until user dismisses ### Technical Improvements - Uses /usr/bin/man explicitly to prevent recursion - Proper environment detection and fallback chain - Added kitty resize shortcuts to config - Removed debug output for clean UX ### Files Updated - shell/functions.zsh: Complete man() rewrite - config/kitty/kitty.conf: Added resize shortcuts - shell/aliases.zsh: Batman alias compatibility - Cleanup of merged files and plugin updates μέτρον γὰρ καὶ συμμετρία - measure, proportion, and what is fitting 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
309 lines
11 KiB
Bash
309 lines
11 KiB
Bash
# ░█▀▀░█░█░█▀█░█▀▀░▀█▀░▀█▀░█▀█░█▀█░█▀▀
|
|
# ░█▀▀░█░█░█░█░█░░░░█░░░█░░█░█░█░█░▀▀█
|
|
# ░▀░░░▀▀▀░▀░▀░▀▀▀░░▀░░▀▀▀░▀▀▀░▀░▀░▀▀▀
|
|
|
|
## I. PDF Compression #######################
|
|
pdfcompress ()
|
|
{
|
|
gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -dCompatibilityLevel=1.3 -dPDFSETTINGS=/screen -dEmbedAllFonts=true -dSubsetFonts=true -dColorImageDownsampleType=/Bicubic -dColorImageResolution=144 -dGrayImageDownsampleType=/Bicubic -dGrayImageResolution=144 -dMonoImageDownsampleType=/Bicubic -dMonoImageResolution=144 -sOutputFile=$1.compressed.pdf $1;
|
|
}
|
|
|
|
## II. Weather #######################
|
|
|
|
wttr() {
|
|
# Usage: wttr [location]
|
|
# Examples: wttr -> your IP-based location
|
|
# wttr 75012 -> Paris 12e
|
|
# wttr 23190 -> Crozant
|
|
local location=${1:-}
|
|
curl -s "wttr.in/${location}?n"
|
|
}
|
|
|
|
## III. Updates (system, brew, etc) #######################
|
|
## Description: Performs system updates, Homebrew cleanup, fzf refresh, moon phase logging, and dotfile sync ###########################
|
|
|
|
function sysupdate() {
|
|
local start_time=$(date +%s)
|
|
echo "🔧 Starting full system update at $(date)"
|
|
|
|
# Ensure sudo credentials are fresh
|
|
if ! sudo -vn 2>/dev/null; then
|
|
echo "🔒 sudo authentication required..."
|
|
sudo -v
|
|
fi
|
|
|
|
echo "🍎 Updating macOS Software..."
|
|
sudo softwareupdate -i -a
|
|
|
|
echo "🍺 Updating Homebrew packages..."
|
|
brew update
|
|
brew upgrade
|
|
brew cleanup
|
|
brew autoremove
|
|
|
|
# Mac App Store updates
|
|
echo "🍎 Updating Mac App Store apps..."
|
|
if command -v mas >/dev/null; then
|
|
local mas_outdated=$(mas outdated)
|
|
if [[ -n "$mas_outdated" ]]; then
|
|
echo "📱 Updating MAS apps:"
|
|
echo "$mas_outdated" | while read -r line; do
|
|
echo " $line"
|
|
done
|
|
mas upgrade || echo "⚠️ Some MAS updates may require manual intervention"
|
|
else
|
|
echo "✅ All MAS apps are up to date"
|
|
fi
|
|
else
|
|
echo "⚠️ mas not installed - install with: brew install mas"
|
|
fi
|
|
|
|
echo "🔄 Refreshing fzf..."
|
|
if [ -d ~/.fzf ]; then
|
|
cd ~/.fzf && git pull && ./install --all && cd -
|
|
fi
|
|
|
|
# Fix Zsh completion security warnings
|
|
echo "🔒 Checking Zsh completion security..."
|
|
if [[ -d "/opt/homebrew/share/zsh" ]]; then
|
|
# Fix common Homebrew Zsh permission issues
|
|
chmod 755 /opt/homebrew/share/zsh /opt/homebrew/share/zsh/site-functions 2>/dev/null || true
|
|
fi
|
|
|
|
echo "🧹 Checking for broken symlinks..."
|
|
find /usr/local/bin "$HOME/bin" "$HOME/.local/bin" -xtype l 2>/dev/null
|
|
|
|
echo "🌓 Moon phase at update time:"
|
|
if command -v curl &>/dev/null && command -v jq >/dev/null; then
|
|
# Use API key from SwiftBar script
|
|
local api_key="6ec71a8170214d828c08ba8bf2ca29e9"
|
|
moon_json=$(curl -s "https://api.ipgeolocation.io/astronomy?apiKey=$api_key" 2>/dev/null)
|
|
if [[ $? -eq 0 ]] && [[ -n "$moon_json" ]]; then
|
|
moon_phase=$(echo "$moon_json" | jq -r '.moon_phase // "Unknown"' | tr '_' ' ')
|
|
illum=$(echo "$moon_json" | jq -r '.moon_illumination_percentage // "Unknown"')
|
|
# Add moon emoji based on phase
|
|
local moon_emoji="🌙"
|
|
case "$moon_phase" in
|
|
"new moon") moon_emoji="🌑" ;;
|
|
"waxing crescent") moon_emoji="🌒" ;;
|
|
"first quarter") moon_emoji="🌓" ;;
|
|
"waxing gibbous") moon_emoji="🌔" ;;
|
|
"full moon") moon_emoji="🌕" ;;
|
|
"waning gibbous") moon_emoji="🌖" ;;
|
|
"last quarter") moon_emoji="🌗" ;;
|
|
"waning crescent") moon_emoji="🌘" ;;
|
|
esac
|
|
echo "$moon_emoji $moon_phase (${illum}%)"
|
|
else
|
|
echo "🌙 Moon phase unavailable"
|
|
fi
|
|
else
|
|
echo "🌙 Moon phase tracking disabled (missing curl or jq)"
|
|
fi
|
|
|
|
if [ -d "$HOME/.dotfiles" ]; then
|
|
echo "📝 Committing dotfile changes..."
|
|
cd ~/.dotfiles || return
|
|
git add . && git commit -m "🔧 Auto-commit from sysupdate on $(date '+%Y-%m-%d %H:%M')" && git push
|
|
brew bundle dump --force --file="$HOME/.dotfiles/Brewfile"
|
|
cd - >/dev/null || return
|
|
fi
|
|
|
|
echo "📊 System Info:"
|
|
echo "💻 $(uname -a)"
|
|
echo "📅 macOS: $(sw_vers | grep ProductVersion)"
|
|
echo "🧠 Memory: $(top -l 1 -s 0 | grep PhysMem)"
|
|
|
|
# Optional post-update hook
|
|
if [ -x "$HOME/.zsh/hooks/post-update" ]; then
|
|
"$HOME/.zsh/hooks/post-update"
|
|
fi
|
|
|
|
echo "🕓 Duration: $(($(date +%s) - $start_time))s"
|
|
osascript -e 'display notification "Update complete!" with title "System Maintenance" subtitle "All systems go 🚀"'
|
|
}
|
|
|
|
# 💤 Quiet version (no output, same functionality)
|
|
function quietupdate() {
|
|
local start_time=$(date +%s)
|
|
sudo -vn 2>/dev/null || sudo -v
|
|
sudo softwareupdate -i -a >/dev/null
|
|
brew update >/dev/null && brew upgrade >/dev/null && brew cleanup >/dev/null && brew autoremove >/dev/null
|
|
[ -d ~/.fzf ] && cd ~/.fzf && git pull >/dev/null && ./install --all >/dev/null && cd - >/dev/null
|
|
[ -d "$HOME/.dotfiles" ] && cd ~/.dotfiles && git add . && git commit -m "auto sysupdate" && git push && brew bundle dump --force --file="$HOME/.dotfiles/Brewfile" && cd - >/dev/null
|
|
if [ -x "$HOME/.zsh/hooks/post-update" ]; then "$HOME/.zsh/hooks/post-update"; fi
|
|
osascript -e 'display notification "Quiet update complete!" with title "System Maintenance"'
|
|
}
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# Man Page side-by-side viewer
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
# Detailed Kitty diagnostic
|
|
debug_kitty_launch() {
|
|
echo "=== Kitty Launch Debugging ==="
|
|
|
|
# Check basic remote control
|
|
echo "1. Testing basic remote control:"
|
|
kitty @ ls
|
|
echo " Exit code: $?"
|
|
|
|
# Test simple launch
|
|
echo -e "\n2. Testing simple window launch:"
|
|
kitty @ launch --type=window echo "Hello from new window"
|
|
echo " Exit code: $?"
|
|
|
|
# Test with bash -c
|
|
echo -e "\n3. Testing bash -c launch:"
|
|
kitty @ launch --type=window bash -c "echo 'Hello with bash -c'"
|
|
echo " Exit code: $?"
|
|
|
|
# Test overlay
|
|
echo -e "\n4. Testing overlay:"
|
|
kitty @ launch --type=overlay bash -c "echo 'Overlay test'; read -p 'Press enter to close'"
|
|
echo " Exit code: $?"
|
|
|
|
# Test with actual man command
|
|
echo -e "\n5. Testing with man command:"
|
|
kitty @ launch --type=window bash -c "man ls"
|
|
echo " Exit code: $?"
|
|
}
|
|
|
|
# Test the absolute simplest case
|
|
test_basic_split() {
|
|
echo "Testing basic split with sleep..."
|
|
kitty @ launch --location=vsplit sleep 5
|
|
echo "Exit code: $?"
|
|
}
|
|
|
|
# Beautiful man pages in resizable split pane
|
|
man() {
|
|
if [[ $# -eq 0 ]]; then
|
|
echo "Usage: man <command> [section]"
|
|
echo "Opens man page in resizable split pane (kitty/tmux) or new tab (iTerm)"
|
|
return 1
|
|
fi
|
|
|
|
local cmd="$1"
|
|
local section="${2:-}"
|
|
|
|
# Verify man page exists
|
|
if ! /usr/bin/man -w ${section:+$section} "$cmd" >/dev/null 2>&1; then
|
|
echo "❌ No manual entry for '$cmd'${section:+ in section $section}"
|
|
return 1
|
|
fi
|
|
|
|
# Build the display command that stays open and adapts to terminal width
|
|
local display_cmd
|
|
local bat_path=$(which bat 2>/dev/null)
|
|
if [[ -n "$bat_path" ]]; then
|
|
# Use bat with terminal width detection and better wrapping
|
|
display_cmd="export PATH=\"$PATH\"; export MANWIDTH=\$(tput cols); /usr/bin/man ${section:+$section} '$cmd' 2>/dev/null | col -bx | '$bat_path' --language=man --style=grid --theme=Nord --paging=always --terminal-width=\$(tput cols) --wrap=auto; echo; echo 'Press any key to close...'; read -k1"
|
|
else
|
|
# Fallback with responsive width
|
|
display_cmd="export MANWIDTH=\$(tput cols); MANPAGER='less -R' /usr/bin/man ${section:+$section} '$cmd'; echo; echo 'Press any key to close...'; read -k1"
|
|
fi
|
|
|
|
# Handle different terminals - always use split/resizable approach
|
|
if [[ -n "${KITTY_WINDOW_ID:-}" ]]; then
|
|
# Kitty: Create optimally-sized vertical split
|
|
# Left pane: ~100 chars for code, Right pane: ~64 chars for optimal reading
|
|
kitty @ launch \
|
|
--location=vsplit \
|
|
--title="📖 $cmd${section:+ ($section)}" \
|
|
--cwd=current \
|
|
--bias=60 \
|
|
zsh -c "$display_cmd" >/dev/null
|
|
elif [[ -n "${TMUX:-}" ]]; then
|
|
# TMUX: Create resizable horizontal split (easier to read)
|
|
tmux split-window -v -l 40% "$display_cmd"
|
|
elif [[ "${TERM_PROGRAM}" == "iTerm.app" ]]; then
|
|
# iTerm: Create new split pane
|
|
osascript -e "
|
|
tell application \"iTerm\"
|
|
tell current window
|
|
tell current session
|
|
split vertically with default profile
|
|
tell last session
|
|
write text \"$display_cmd\"
|
|
set name to \"📖 $cmd${section:+ ($section)}\"
|
|
end tell
|
|
end tell
|
|
end tell
|
|
end tell
|
|
" >/dev/null 2>&1
|
|
else
|
|
# Fallback: run inline
|
|
echo "📖 Displaying man page inline:"
|
|
eval "$display_cmd"
|
|
fi
|
|
}
|
|
|
|
# batman is already aliased to man in aliases.zsh
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# DOTFILES MANAGEMENT FUNCTIONS
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
# Quick navigation to dotfiles directory
|
|
dot() {
|
|
cd ~/dotfiles
|
|
[[ $# -gt 0 ]] && "$@"
|
|
}
|
|
|
|
# Quick edit common configs with automatic reload
|
|
zedit() {
|
|
${EDITOR:-nano} ~/.zshrc && source ~/.zshrc
|
|
echo "✅ .zshrc reloaded"
|
|
}
|
|
|
|
aedit() {
|
|
${EDITOR:-nano} ~/dotfiles/shell/aliases.zsh && source ~/.zshrc
|
|
echo "✅ aliases reloaded"
|
|
}
|
|
|
|
fedit() {
|
|
${EDITOR:-nano} ~/dotfiles/shell/functions.zsh && source ~/.zshrc
|
|
echo "✅ functions reloaded"
|
|
}
|
|
|
|
pedit() {
|
|
${EDITOR:-nano} ~/dotfiles/shell/paths.zsh && source ~/.zshrc
|
|
echo "✅ paths reloaded"
|
|
}
|
|
|
|
# Backup critical configs with timestamp
|
|
backup-configs() {
|
|
local backup_dir="$HOME/.config-backups/$(date +%Y%m%d-%H%M%S)"
|
|
mkdir -p "$backup_dir"
|
|
|
|
echo "📦 Backing up critical configs to: $backup_dir"
|
|
|
|
# SSH keys (if they exist)
|
|
if [[ -d ~/.ssh ]]; then
|
|
cp -R ~/.ssh "$backup_dir/" 2>/dev/null || true
|
|
echo " ✓ SSH configuration"
|
|
fi
|
|
|
|
# Shell history
|
|
if [[ -f ~/.zsh_history ]]; then
|
|
cp ~/.zsh_history "$backup_dir/" 2>/dev/null || true
|
|
echo " ✓ Shell history"
|
|
fi
|
|
|
|
# GPG keys (if they exist)
|
|
if [[ -d ~/.gnupg ]]; then
|
|
cp -R ~/.gnupg "$backup_dir/" 2>/dev/null || true
|
|
echo " ✓ GPG configuration"
|
|
fi
|
|
|
|
# AWS credentials (if they exist)
|
|
if [[ -d ~/.aws ]]; then
|
|
cp -R ~/.aws "$backup_dir/" 2>/dev/null || true
|
|
echo " ✓ AWS configuration"
|
|
fi
|
|
|
|
echo "✅ Configs backed up to: $backup_dir"
|
|
}
|
|
|