# ░█▀▀░█░█░█▀█░█▀▀░▀█▀░▀█▀░█▀█░█▀█░█▀▀ # ░█▀▀░█░█░█░█░█░░░░█░░░█░░█░█░█░█░▀▀█ # ░▀░░░▀▀▀░▀░▀░▀▀▀░░▀░░▀▀▀░▀▀▀░▀░▀░▀▀▀ ## 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, 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 # fzf removed — no longer installed # 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 "$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"' } # ═══════════════════════════════════════════════════════════════════════════════ # Modern, workspace-aware man page viewer # - Kitty/tmux/iTerm split panes, syntax highlighting via bat # - Optional qman integration for interactive TOC/search # - Order-flexible + apropos search # ═══════════════════════════════════════════════════════════════════════════════ man() { if [[ $# -eq 0 ]]; then echo "Usage:" echo " man [section]" echo " man [section] " echo " man ? # apropos search" return 1 fi # Apropos mode if [[ "$1" == "?" ]]; then shift /usr/bin/man -k "$@" return fi # Support both orders: man 2 open OR man open 2 local cmd section if [[ "$1" =~ ^[0-9]+$ && -n "$2" ]]; then section="$1"; cmd="$2" else cmd="$1"; section="${2:-}" fi # Verify 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}" echo "💡 Try: man ? $cmd" return 1 fi # Choose backend local display_cmd if command -v qman >/dev/null 2>&1; then display_cmd="qman ${section:+$section }-- '$cmd'" else local bat_path; bat_path=$(command -v bat 2>/dev/null || true) if [[ -n "$bat_path" ]]; then display_cmd="export MANWIDTH=\$(tput cols); /usr/bin/man ${section:+$section} '$cmd' 2>/dev/null \ | col -bx \ | '$bat_path' --language=man --style=grid --theme=\${BAT_THEME:-Nord} \ --paging=always --terminal-width=\$(tput cols) --wrap=auto" else display_cmd="export MANWIDTH=\$(tput cols); MANPAGER='less -R' /usr/bin/man ${section:+$section} '$cmd'" fi fi # Handle different terminal environments if [[ -n "${KITTY_WINDOW_ID:-}" ]]; then kitty @ launch \ --location=vsplit \ --title="📖 $cmd${section:+ ($section)}" \ --cwd=current \ --bias=${KITTY_BIAS:-60} \ zsh -lc "$display_cmd" >/dev/null elif [[ -n "${TMUX:-}" ]]; then tmux split-window -v -l ${TMUX_HEIGHT:-40%} "$display_cmd" elif [[ "${TERM_PROGRAM}" == "iTerm.app" ]]; then 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 echo "📖 Displaying man page inline:" eval "$display_cmd" fi } # ═══════════════════════════════════════════════════════════════════════════════ # 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 echo "✅ Configs backed up to: $backup_dir" } # ═══════════════════════════════════════════════════════════════════════════════ # LICENSE MANAGEMENT FUNCTIONS FOR PASS # ═══════════════════════════════════════════════════════════════════════════════ # License management: add a license entry with optional attached file license-add() { if [ $# -lt 1 ]; then echo "Usage: license-add [license-file-path]" return 1 fi local product="$1" local entry="licenses/$product" local dir="$HOME/.password-store/${entry}.gpg.d" echo "→ Paste activation code or license metadata for '$product', then press Ctrl+D:" pass insert -m "$entry" || return 1 if [ $# -eq 2 ]; then local filepath="$2" local filename="$(basename "$filepath")" mkdir -p "$dir" gpg -o "$dir/${filename}.gpg" -e -r "$(gpg --list-secret-keys --with-colons | awk -F: '/^uid:/ {print $10; exit}')" "$filepath" echo "✔️ Encrypted license file saved as: $dir/${filename}.gpg" else echo "✔️ Code-only license entry created for '$product'." fi } # Edit a license entry in the pass store license-edit() { if [ $# -ne 1 ]; then echo "Usage: license-edit " return 1 fi local product="$1" pass edit "licenses/$product" } # List all stored licenses license-list() { pass ls licenses/ | sed 's/^licenses\///' | sort } # Show license details and attached files for a product license-info() { if [ $# -ne 1 ]; then echo "Usage: license-info " return 1 fi local product="$1" local entry="licenses/$product" local pass_file="$HOME/.password-store/${entry}.gpg" local attach_dir="$HOME/.password-store/${entry}.gpg.d" if [ ! -f "$pass_file" ]; then echo "❌ No license entry found for '$product'" return 1 fi echo "🔐 License entry: $product" echo "----------------------------------------" pass show "$entry" echo if [ -d "$attach_dir" ]; then echo "📎 Attached encrypted file(s):" find "$attach_dir" -type f -name '*.gpg' -exec basename {} \; else echo "📎 No attached files." fi }