Dotfiles update 2025-12-24 22:47

This commit is contained in:
Aaron D. Lee
2025-12-24 22:47:27 -05:00
parent b1274a6209
commit f55ea98231
9 changed files with 392 additions and 1114 deletions

View File

@@ -59,9 +59,7 @@ btrfs-usage() {
_btrfs_check || return 1
local mount="${1:-$BTRFS_DEFAULT_MOUNT}"
df_print_func_header "Btrfs Filesystem Usage:"
#echo -e "${DF_BLUE}Btrfs Filesystem Usage: ${DF_YELLOW}${mount}${DF_NC}"
echo ""
df_print_func_name "Btrfs Filesystem Usage: ${mount}"
sudo btrfs filesystem usage "$mount" -h
}
@@ -72,8 +70,6 @@ btrfs-subs() {
local mount="${1:-$BTRFS_DEFAULT_MOUNT}"
df_print_func_name "Btrfs Subvolumes"
#echo -e "${DF_BLUE}Btrfs Subvolumes"
echo ""
echo -e "${DF_CYAN}Subvolume List:${DF_NC}"
sudo btrfs subvolume list "$mount" | while read -r line; do
@@ -93,7 +89,8 @@ btrfs-balance() {
local mount="${1:-$BTRFS_DEFAULT_MOUNT}"
local usage="${2:-50}" # Default: rebalance chunks with <50% usage
echo -e "${DF_BLUE}==>${DF_NC} Starting btrfs balance on ${mount}"
df_print_func_name "Btrfs Balance"
echo -e "${DF_YELLOW}${DF_NC} This may take a while and use significant I/O"
echo ""
@@ -116,6 +113,8 @@ btrfs-balance-status() {
_btrfs_check || return 1
local mount="${1:-$BTRFS_DEFAULT_MOUNT}"
df_print_func_name "Btrfs Balance Status"
sudo btrfs balance status "$mount"
}
@@ -132,9 +131,8 @@ btrfs-balance-cancel() {
btrfs-scrub() {
_btrfs_check || return 1
local mount="${1:-$BTRFS_DEFAULT_MOUNT}"
df_print_func_name "Btrfs Scrub"
#echo -e "${DF_BLUE}Btrfs Scrub"
echo ""
# Check if scrub is already running
local status=$(sudo btrfs scrub status "$mount" 2>/dev/null)
@@ -165,6 +163,8 @@ btrfs-scrub-status() {
_btrfs_check || return 1
local mount="${1:-$BTRFS_DEFAULT_MOUNT}"
df_print_func_name "Btrfs Scrub Status"
sudo btrfs scrub status "$mount"
}
@@ -187,15 +187,16 @@ btrfs-defrag() {
return 1
fi
echo -e "${DF_BLUE}==>${DF_NC} Defragmenting: $target"
df_print_func_name "Btrfs Defragment"
if [[ -d "$target" ]]; then
echo -e "${DF_YELLOW}${DF_NC} Recursive defrag on directory"
echo -e "${DF_YELLOW}${DF_NC} Recursive defrag on directory: $target"
read -q "REPLY?Continue? [y/N]: "; echo
[[ ! "$REPLY" =~ ^[Yy]$ ]] && return 0
sudo btrfs filesystem defragment -r -v "$target"
else
echo -e "${DF_BLUE}==>${DF_NC} Defragmenting: $target"
sudo btrfs filesystem defragment -v "$target"
fi
@@ -213,9 +214,7 @@ btrfs-compress() {
return 1
fi
df_print_func_header "Btrfs Compression Statistics"
#echo -e "${DF_BLUE}Btrfs Compression Statistics${FD_NC}"
echo ""
df_print_func_name "Btrfs Compression Statistics"
sudo compsize "$target"
}
@@ -228,10 +227,10 @@ btrfs-compress() {
btrfs-info() {
_btrfs_check || return 1
local mount="${1:-$BTRFS_DEFAULT_MOUNT}"
df_print_func_name "Btrfs Filesystem Information"
#echo -e "${DF_BLUE}Btrfs Filesystem Information${DF_NC}"
echo -e "\n${DF_CYAN}Filesystem Show:${DF_NC}"
df_print_func_name "Btrfs Filesystem Information"
echo -e "${DF_CYAN}Filesystem Show:${DF_NC}"
sudo btrfs filesystem show "$mount"
echo -e "\n${DF_CYAN}Filesystem df:${DF_NC}"
@@ -249,8 +248,6 @@ btrfs-health() {
local mount="${1:-$BTRFS_DEFAULT_MOUNT}"
df_print_func_name "Btrfs Health Check"
#echo -e "${DF_BLUE}Btrfs Health Check${DF_NC}"
echo ""
local issues=0
@@ -322,15 +319,22 @@ btrfs-snap-usage() {
_btrfs_check || return 1
df_print_func_name "Snapshot Disk Space Usage"
#echo -e "${DF_BLUE}Snapshot Space Usage${DF_NC}"
echo ""
if [[ -d "/.snapshots" ]]; then
echo -e "${DF_CYAN}Snapshot Directory:${DF_NC}"
sudo du -sh /.snapshots 2>/dev/null || echo " Unable to calculate"
# Use timeout to prevent hanging, and run in background with wait
local size
size=$(timeout 10 sudo du -sh /.snapshots 2>/dev/null | cut -f1)
if [[ -n "$size" ]]; then
echo " $size"
else
echo " Unable to calculate (timeout or error)"
fi
echo -e "\n${DF_CYAN}Individual Snapshots:${DF_NC}"
sudo du -sh /.snapshots/*/ 2>/dev/null | sort -h | tail -10 | sed 's/^/ /'
echo -e "\n${DF_CYAN}Individual Snapshots (top 10 by size):${DF_NC}"
# List snapshots with timeout protection
timeout 30 sudo du -sh /.snapshots/*/ 2>/dev/null | sort -h | tail -10 | sed 's/^/ /' || \
echo " Unable to list snapshots"
else
echo -e "${DF_YELLOW}${DF_NC} No /.snapshots directory found"
fi
@@ -348,8 +352,7 @@ btrfs-maintain() {
local mount="${1:-$BTRFS_DEFAULT_MOUNT}"
df_print_func_name "Btrfs Maintenance Routine"
#echo -e "${DF_BLUE}Btrfs Maintenance Routine${DF_NC}"
echo ""
echo "This will perform:"
echo " 1. Health check"
echo " 2. Balance (low usage chunks)"
@@ -391,7 +394,6 @@ alias btrc='btrfs-compress'
btrfs-help() {
df_print_func_name "Btrfs Helper Commands"
#echo -e "${DF_BLUE}Btrfs Helper Commands${DF_NC}"
cat << 'EOF'

View File

@@ -231,10 +231,10 @@ bookmark() {
case "$bm_name" in
list|ls)
df_print_func_name "Bookmarks"
if [[ -s "$PALETTE_BOOKMARKS_FILE" ]]; then
echo "Bookmarks:"
while IFS='|' read -r stored_name stored_path || [[ -n "$stored_name" ]]; do
[[ -n "$stored_name" ]] && echo " $stored_name$stored_path"
[[ -n "$stored_name" ]] && echo -e " ${DF_GREEN}${DF_NC} $stored_name$stored_path"
done < "$PALETTE_BOOKMARKS_FILE"
else
echo "No bookmarks yet"
@@ -251,7 +251,7 @@ bookmark() {
local temp_file="${PALETTE_BOOKMARKS_FILE}.tmp.$$"
grep -v "^${to_delete}|" "$PALETTE_BOOKMARKS_FILE" > "$temp_file" 2>/dev/null || true
mv -f "$temp_file" "$PALETTE_BOOKMARKS_FILE"
echo "Deleted: $to_delete"
echo -e "${DF_GREEN}${DF_NC} Deleted: $to_delete"
else
echo "No bookmarks to delete"
fi
@@ -265,7 +265,7 @@ bookmark() {
fi
# Add new bookmark
echo "${bm_name}|${bm_path}" >> "$PALETTE_BOOKMARKS_FILE"
echo "Bookmarked: $bm_name$bm_path"
echo -e "${DF_GREEN}${DF_NC} Bookmarked: $bm_name$bm_path"
;;
esac
}

View File

@@ -77,6 +77,7 @@ pw() {
case "$cmd" in
list|ls|l)
df_print_func_name "LastPass Vault"
_lp_list
;;
@@ -96,6 +97,7 @@ pw() {
search|find|s)
local query="$1"
[[ -z "$query" ]] && { echo "Usage: pw search <query>"; return 1; }
df_print_func_name "LastPass Search: $query"
_lp_search "$query"
;;
@@ -110,21 +112,20 @@ pw() {
echo -n "$value" | xclip -selection clipboard 2>/dev/null || \
echo -n "$value" | xsel --clipboard 2>/dev/null || \
{ echo "Could not copy to clipboard"; return 1; }
echo "Copied to clipboard"
echo -e "${DF_GREEN}${DF_NC} Copied to clipboard"
else
echo "Item not found or empty"
echo -e "${DF_RED}${DF_NC} Item not found or empty"
return 1
fi
;;
lock)
lpass logout -f 2>/dev/null
echo "Logged out of LastPass"
echo -e "${DF_GREEN}${DF_NC} Logged out of LastPass"
;;
help|--help|-h|*)
echo -e "${DF_BLUE}Password Manager CLI (LastPass)${DF_NC}"
echo
df_print_func_name "Password Manager CLI"
echo "Usage: pw <command> [args]"
echo
echo "Commands:"
@@ -190,7 +191,7 @@ if command -v fzf &>/dev/null; then
if [[ -n "$otp" ]]; then
echo -n "$otp" | xclip -selection clipboard 2>/dev/null || \
echo -n "$otp" | xsel --clipboard 2>/dev/null
echo "OTP copied: $otp"
echo -e "${DF_GREEN}${DF_NC} OTP copied: $otp"
fi
fi
}

File diff suppressed because it is too large Load Diff

View File

@@ -18,9 +18,7 @@ snap-create() {
local snap_config="root"
local limine_conf="/boot/limine.conf"
echo -e "\n${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Snapper Snapshot Creation & Validation ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}\n"
df_print_func_name "Snapper Snapshot Creation"
if [[ -z "$description" ]]; then
echo -e "${DF_YELLOW}${DF_NC} No description provided"
@@ -90,21 +88,20 @@ snap-create() {
validation_passed=false
fi
echo -e "\n${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Summary ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}"
echo -e "Snapshot Number: #$snapshot_num"
echo -e "Description: \"$description\""
echo -e "Config: $snap_config"
echo -e "Before entries: $before_entries"
echo -e "After entries: $after_entries"
echo ""
echo -e "${DF_CYAN}Summary:${DF_NC}"
echo -e " Snapshot Number: #$snapshot_num"
echo -e " Description: \"$description\""
echo -e " Config: $snap_config"
echo -e " Before entries: $before_entries"
echo -e " After entries: $after_entries"
if [[ "$validation_passed" == true ]]; then
echo -e "Status: ${DF_GREEN}✓ VALIDATED${DF_NC}"
echo -e " Status: ${DF_GREEN}✓ VALIDATED${DF_NC}"
echo -e "\n${DF_GREEN}${DF_NC} Snapshot created and limine.conf successfully updated!"
return 0
else
echo -e "Status: ${DF_RED}✗ VALIDATION FAILED${DF_NC}"
echo -e " Status: ${DF_RED}✗ VALIDATION FAILED${DF_NC}"
echo -e "\n${DF_RED}${DF_NC} Snapshot created but limine.conf validation failed!"
echo -e "${DF_YELLOW}${DF_NC} Check if limine-snapper-sync service is running properly"
echo -e "${DF_YELLOW}Run:${DF_NC} sudo systemctl status limine-snapper-sync.service"
@@ -118,17 +115,20 @@ snap-create() {
snap-list() {
local count="${1:-10}"
echo -e "${DF_BLUE}Recent $count snapshots:${DF_NC}\n"
df_print_func_name "Snapper Snapshots (last $count)"
sudo snapper -c root list | tail -n "$((count + 1))"
}
snap-show() {
[[ -z "$1" ]] && { echo -e "${DF_RED}${DF_NC} Usage: snap-show <snapshot_number>"; return 1; }
echo -e "${DF_BLUE}Snapshot #$1 details:${DF_NC}\n"
df_print_func_name "Snapshot #$1 Details"
sudo snapper -c root list | grep "^\s*$1\s"
echo -e "\n${DF_BLUE}In limine.conf:${DF_NC}"
echo -e "\n${DF_CYAN}In limine.conf:${DF_NC}"
if sudo grep -qP "^\\s*///$1\\s*│" /boot/limine.conf; then
local entry_line=$(sudo grep -nP "^\\s*///$1\\s*│" /boot/limine.conf | head -n 1 | cut -d: -f1)
[[ -n "$entry_line" ]] && sudo sed -n "${entry_line}p; $((entry_line+1))p" /boot/limine.conf
@@ -143,7 +143,7 @@ snap-delete() {
local snapshot_num="$1"
local limine_conf="/boot/limine.conf"
echo -e "${DF_BLUE}==>${DF_NC} Deleting snapshot #$snapshot_num"
df_print_func_name "Delete Snapshot #$snapshot_num"
local before_entries=$(sudo grep -cP "^\\s*///\\d+\\s*│" "$limine_conf" || echo "0")
@@ -178,16 +178,14 @@ snap-delete() {
snap-check-limine() {
local limine_conf="/boot/limine.conf"
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Limine Snapshot Entries ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}\n"
df_print_func_name "Limine Snapshot Entries"
[[ ! -f "$limine_conf" ]] && { echo -e "${DF_RED}${DF_NC} Limine config not found: $limine_conf"; return 1; }
local latest_snapshot=$(sudo snapper -c root list | tail -n +3 | grep -v "^\s*0\s" | tail -n 1 | awk '{print $1}')
[[ -z "$latest_snapshot" ]] && { echo -e "${DF_YELLOW}${DF_NC} No snapshots found in snapper"; return 1; }
echo -e "${DF_BLUE}Latest snapshot:${DF_NC} #$latest_snapshot"
echo -e "${DF_CYAN}Latest snapshot:${DF_NC} #$latest_snapshot"
echo -e "${DF_BLUE}==>${DF_NC} Checking if latest snapshot is in limine.conf"
@@ -199,16 +197,18 @@ snap-check-limine() {
echo -e "\n${DF_BLUE}==>${DF_NC} Counting snapshot entries"
local entry_count=$(sudo grep -cP "^\\s*///\\d+\\s*│" "$limine_conf" || echo "0")
echo -e "${DF_BLUE}Total snapshot entries:${DF_NC} $entry_count\n"
echo -e "${DF_CYAN}Total snapshot entries:${DF_NC} $entry_count"
}
snap-sync() {
df_print_func_name "Limine-Snapper-Sync"
echo -e "${DF_BLUE}==>${DF_NC} Manually triggering limine-snapper-sync..."
if sudo systemctl start limine-snapper-sync.service; then
echo -e "${DF_GREEN}${DF_NC} Service triggered successfully"
sleep 2
echo -e "\n${DF_BLUE}Service status:${DF_NC}"
echo -e "\n${DF_CYAN}Service status:${DF_NC}"
sudo systemctl status limine-snapper-sync.service --no-pager -l | tail -n 10
else
echo -e "${DF_RED}${DF_NC} Failed to trigger service"
@@ -217,9 +217,7 @@ snap-sync() {
}
snap-validate-service() {
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Limine-Snapper-Sync Service Validation ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}\n"
df_print_func_name "Limine-Snapper-Sync Service Validation"
echo -e "${DF_BLUE}==>${DF_NC} Checking service unit"

View File

@@ -82,10 +82,7 @@ ssh-save() {
ssh-list() {
_ssh_init_profiles
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} SSH Connection Profiles ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}"
echo
df_print_func_name "SSH Connection Profiles"
local has_profiles=false
while IFS='|' read -r name connection port key options description; do
@@ -205,7 +202,7 @@ ssh-sync-dotfiles() {
local dotfiles_dir="${DOTFILES_DIR:-$HOME/.dotfiles}"
[[ ! -d "$dotfiles_dir" ]] && { _ssh_print_error "Dotfiles directory not found"; return 1; }
_ssh_print_step "Syncing dotfiles to: $connection"
df_print_func_name "Sync Dotfiles to: $connection"
local rsync_cmd="rsync -avz --exclude='.git' --exclude='*.local'"
[[ -n "$port" && "$port" != "22" ]] && rsync_cmd="$rsync_cmd -e 'ssh -p $port'"

View File

@@ -97,7 +97,7 @@ sclog() {
sclogs() {
local service="$1"
local lines="${2:-50}"
[[ -z "$service" ]] && { echo "Usage: sclog <service> [lines]"; return 1; }
[[ -z "$service" ]] && { echo "Usage: sclogs <service> [lines]"; return 1; }
sudo journalctl -xeu "$service" -n "$lines" --no-pager
}
@@ -108,11 +108,9 @@ sclogs() {
# Show failed services (system and user)
sc-failed() {
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Failed Services ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}"
df_print_func_name "Failed Services"
echo -e "\n${DF_CYAN}System Services:${DF_NC}"
echo -e "${DF_CYAN}System Services:${DF_NC}"
local sys_failed=$(systemctl --failed --no-pager --no-legend 2>/dev/null)
if [[ -z "$sys_failed" ]]; then
echo -e " ${DF_GREEN}${DF_NC} No failed system services"
@@ -133,11 +131,9 @@ sc-failed() {
# Show active timers
sc-timers() {
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Active Timers ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}"
df_print_func_name "Active Timers"
echo -e "\n${DF_CYAN}System Timers:${DF_NC}"
echo -e "${DF_CYAN}System Timers:${DF_NC}"
systemctl list-timers --no-pager | head -20
echo -e "\n${DF_CYAN}User Timers:${DF_NC}"
@@ -150,11 +146,9 @@ sc-timers() {
sc-recent() {
local count="${1:-15}"
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Recent Service Activity ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}"
df_print_func_name "Recent Service Activity"
echo -e "\n${DF_CYAN}Recently Started:${DF_NC}"
echo -e "${DF_CYAN}Recently Started:${DF_NC}"
systemctl list-units --type=service --state=running --no-pager --no-legend | \
head -"$count" | awk '{print " " $1}'
@@ -166,11 +160,9 @@ sc-recent() {
# Boot time analysis
sc-boot() {
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Boot Time Analysis ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}"
df_print_func_name "Boot Time Analysis"
echo -e "\n${DF_CYAN}Boot Summary:${DF_NC}"
echo -e "${DF_CYAN}Boot Summary:${DF_NC}"
systemd-analyze
echo -e "\n${DF_CYAN}Slowest Services (top 10):${DF_NC}"
@@ -191,8 +183,7 @@ sc-search() {
local query="$1"
[[ -z "$query" ]] && { echo "Usage: sc-search <query>"; return 1; }
echo -e "${DF_BLUE}==>${DF_NC} Searching for services matching: ${query}"
echo ""
df_print_func_name "Service Search: $query"
systemctl list-unit-files --type=service --no-pager | grep -i "$query"
}
@@ -202,11 +193,9 @@ sc-info() {
local service="$1"
[[ -z "$service" ]] && { echo "Usage: sc-info <service>"; return 1; }
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Service Info: ${service}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}"
df_print_func_name "Service Info: $service"
echo -e "\n${DF_CYAN}Status:${DF_NC}"
echo -e "${DF_CYAN}Status:${DF_NC}"
systemctl status "$service" --no-pager -l 2>/dev/null || \
sudo systemctl status "$service" --no-pager -l
@@ -305,9 +294,7 @@ alias jctlerr='journalctl -p err -b'
# ============================================================================
sc-help() {
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Systemd Helper Commands ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}"
df_print_func_name "Systemd Helper Commands"
cat << 'EOF'
@@ -318,7 +305,7 @@ sc-help() {
sce <service> Enable and start (--now)
scd <service> Disable and stop (--now)
sclog <service> Follow journal logs (-f)
scogs <service> Show recent logs (no follow)
sclogs <service> Show recent logs (no follow)
Status Commands:
sc-failed Show failed services

View File

@@ -100,10 +100,7 @@ EOF
tw-templates() {
_tw_init_templates
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Available Tmux Templates ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}"
echo
df_print_func_name "Available Tmux Templates"
for template in "$TW_TEMPLATES_DIR"/*.tmux; do
[[ ! -f "$template" ]] && continue
@@ -200,10 +197,7 @@ tw-attach() {
tw-list() {
_tw_check_tmux || return 1
echo -e "${DF_BLUE}╔════════════════════════════════════════════════════════════╗${DF_NC}"
echo -e "${DF_BLUE}${DF_NC} Active Tmux Workspaces ${DF_BLUE}${DF_NC}"
echo -e "${DF_BLUE}╚════════════════════════════════════════════════════════════╝${DF_NC}"
echo
df_print_func_name "Active Tmux Workspaces"
local has_workspaces=false

257
zsh/lib/utils.zsh Normal file
View File

@@ -0,0 +1,257 @@
# ============================================================================
# Shared Utility Functions for Zsh Dotfiles
# ============================================================================
# Common helper functions used across multiple function files
#
# Source this file in your .zshrc or in individual function files:
# source "$HOME/.dotfiles/zsh/lib/utils.zsh"
#
# Provides:
# - Standardized output formatting (step/success/error/warning/info)
# - Command dependency checking
# - User confirmation prompts
# - Common file/directory operations
# ============================================================================
# Ensure colors are loaded first
source "${0:A:h}/colors.zsh" 2>/dev/null || {
typeset -g DF_GREEN=$'\033[0;32m' DF_YELLOW=$'\033[1;33m'
typeset -g DF_RED=$'\033[0;31m' DF_BLUE=$'\033[0;34m'
typeset -g DF_CYAN=$'\033[0;36m' DF_DIM=$'\033[2m' DF_NC=$'\033[0m'
}
# ============================================================================
# Output Formatting Functions
# ============================================================================
# These provide consistent, styled output across all dotfiles functions.
# Use these instead of raw echo statements for a unified look.
# Print a step/action indicator (blue arrow)
# Usage: df_print_step "Installing packages"
df_print_step() {
echo -e "${DF_BLUE}==>${DF_NC} $1"
}
# Print a success message (green checkmark)
# Usage: df_print_success "Installation complete"
df_print_success() {
echo -e "${DF_GREEN}${DF_NC} $1"
}
# Print an error message (red X)
# Usage: df_print_error "Failed to connect"
df_print_error() {
echo -e "${DF_RED}${DF_NC} $1"
}
# Print a warning message (yellow warning sign)
# Usage: df_print_warning "Config file missing, using defaults"
df_print_warning() {
echo -e "${DF_YELLOW}${DF_NC} $1"
}
# Print an info message (cyan info icon)
# Usage: df_print_info "Using cached version"
df_print_info() {
echo -e "${DF_CYAN}${DF_NC} $1"
}
# Print a section header (cyan, for grouping output)
# Usage: df_print_section "Configuration"
df_print_section() {
echo -e "${DF_CYAN}$1:${DF_NC}"
}
# Print a bullet point item (green dot)
# Usage: df_print_item "my-alias" "git status"
df_print_item() {
local name="$1"
local description="${2:-}"
if [[ -n "$description" ]]; then
echo -e " ${DF_GREEN}${DF_NC} ${DF_CYAN}$name${DF_NC} - $description"
else
echo -e " ${DF_GREEN}${DF_NC} ${DF_CYAN}$name${DF_NC}"
fi
}
# Print indented content (for sub-items)
# Usage: df_print_indent "Additional details here"
df_print_indent() {
echo " $1"
}
# Print a function name header (box style) - already defined in colors.zsh
# but ensure it's available
if ! typeset -f df_print_func_name &>/dev/null; then
df_print_func_name() {
local name="$1"
local width=$((${#name} + 4))
local border=$(printf '─%.0s' $(seq 1 $width))
echo -e "${DF_CYAN}${border}${DF_NC}"
echo -e "${DF_CYAN}${DF_NC} $name ${DF_CYAN}${DF_NC}"
echo -e "${DF_CYAN}${border}${DF_NC}"
}
fi
# ============================================================================
# Command Dependency Checking
# ============================================================================
# Check if required commands are available before running functions.
# Check if a command exists
# Usage: df_cmd_exists git && echo "git is installed"
df_cmd_exists() {
command -v "$1" &>/dev/null
}
# Require a command, exit with error if missing
# Usage: df_require_cmd fzf || return 1
# Usage: df_require_cmd compsize "compsize" || return 1
df_require_cmd() {
local cmd="$1"
local package="${2:-$1}" # Default to command name as package name
if ! command -v "$cmd" &>/dev/null; then
df_print_error "$cmd not installed"
echo "Install: sudo pacman -S $package"
return 1
fi
return 0
}
# Require multiple commands at once
# Usage: df_require_cmds git fzf tmux || return 1
df_require_cmds() {
local missing=()
for cmd in "$@"; do
if ! command -v "$cmd" &>/dev/null; then
missing+=("$cmd")
fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
df_print_error "Missing required commands: ${missing[*]}"
echo "Install: sudo pacman -S ${missing[*]}"
return 1
fi
return 0
}
# ============================================================================
# User Confirmation Prompts
# ============================================================================
# Consistent confirmation dialogs for dangerous operations.
# Ask for yes/no confirmation (defaults to no)
# Usage: df_confirm "Delete all files?" || return
df_confirm() {
local prompt="$1"
read -q "REPLY?$prompt [y/N]: "
echo # Newline after response
[[ "$REPLY" =~ ^[Yy]$ ]]
}
# Ask for confirmation with a warning prefix
# Usage: df_confirm_warning "This will delete all data" || return
df_confirm_warning() {
local message="$1"
df_print_warning "$message"
df_confirm "Continue?"
}
# ============================================================================
# File and Directory Helpers
# ============================================================================
# Check if running inside a git repository
# Usage: df_in_git_repo && echo "In a git repo"
df_in_git_repo() {
git rev-parse --git-dir &>/dev/null 2>&1
}
# Get git root directory
# Usage: local root=$(df_git_root)
df_git_root() {
git rev-parse --show-toplevel 2>/dev/null
}
# Ensure a directory exists, create if missing
# Usage: df_ensure_dir "$HOME/.cache/myapp"
df_ensure_dir() {
local dir="$1"
[[ ! -d "$dir" ]] && mkdir -p "$dir"
}
# Ensure a file exists with optional default content
# Usage: df_ensure_file "$HOME/.config/myapp/config" "# Default config"
df_ensure_file() {
local file="$1"
local default_content="${2:-}"
if [[ ! -f "$file" ]]; then
df_ensure_dir "$(dirname "$file")"
if [[ -n "$default_content" ]]; then
echo "$default_content" > "$file"
else
touch "$file"
fi
fi
}
# ============================================================================
# String Helpers
# ============================================================================
# Truncate a string to a maximum length
# Usage: df_truncate "Long string here" 10 # "Long st..."
df_truncate() {
local str="$1"
local max="${2:-50}"
if [[ ${#str} -gt $max ]]; then
echo "${str:0:$((max-3))}..."
else
echo "$str"
fi
}
# Pad a string to a minimum length
# Usage: df_pad "short" 10 # "short "
df_pad() {
local str="$1"
local width="${2:-20}"
printf "%-${width}s" "$str"
}
# ============================================================================
# FZF Helpers
# ============================================================================
# Standard fzf options for consistent look
df_fzf_opts() {
echo "--height=50% --layout=reverse --border=rounded"
}
# Run fzf with standard options
# Usage: echo -e "opt1\nopt2" | df_fzf "Select > "
df_fzf() {
local prompt="${1:-Select > }"
shift
fzf $(df_fzf_opts) --prompt="$prompt" "$@"
}
# ============================================================================
# Environment Helpers
# ============================================================================
# Check if inside tmux
# Usage: df_in_tmux && echo "Inside tmux"
df_in_tmux() {
[[ -n "$TMUX" ]]
}
# Check if root filesystem is btrfs
# Usage: df_is_btrfs && echo "Using btrfs"
df_is_btrfs() {
[[ "$(df -T / | awk 'NR==2 {print $2}')" == "btrfs" ]]
}