summaryrefslogtreecommitdiff
path: root/dotfiles/common/.bashrc.d
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-01-26 17:36:38 -0600
committerCraig Jennings <c@cjennings.net>2026-01-26 17:36:38 -0600
commitdada2f255daaa2fb493ec8c7d47e2a8123aea494 (patch)
tree0c0eeb84bb7b6e66a2d7f41cdfd061b25f80cc14 /dotfiles/common/.bashrc.d
parentd50e5955837788fc69b4d5bc74cb574b859ed31a (diff)
refactor(dotfiles): rename system/ to common/ and remove unused configs
Rename dotfiles/system to dotfiles/common for clarity - indicates shared dotfiles used across all desktop environments (DWM, Hyprland). Removed config directories for uninstalled applications: - ghostty (using different terminal) - lf (using ranger instead) - mopidy (using mpd instead) - nitrogen (X11-only, obsolete for Wayland) - pychess (not installed) - JetBrains (not installed via archsetup) - youtube-dl (using yt-dlp with different config location) Kept audacious config for potential future use. Updated all references in archsetup, CLAUDE.md, todo.org, and validation.sh. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'dotfiles/common/.bashrc.d')
-rw-r--r--dotfiles/common/.bashrc.d/aliases.sh91
-rw-r--r--dotfiles/common/.bashrc.d/emacs.sh24
-rw-r--r--dotfiles/common/.bashrc.d/fzf.sh122
-rw-r--r--dotfiles/common/.bashrc.d/git.sh32
-rw-r--r--dotfiles/common/.bashrc.d/media.sh41
-rw-r--r--dotfiles/common/.bashrc.d/utilities.sh206
6 files changed, 516 insertions, 0 deletions
diff --git a/dotfiles/common/.bashrc.d/aliases.sh b/dotfiles/common/.bashrc.d/aliases.sh
new file mode 100644
index 0000000..28c0f3f
--- /dev/null
+++ b/dotfiles/common/.bashrc.d/aliases.sh
@@ -0,0 +1,91 @@
+# aliases.sh
+# Craig Jennings <c@cjennings.net>
+# Shell aliases - works in both bash and zsh
+
+# =============================================================================
+# Directory Navigation
+# =============================================================================
+alias cdot="cd ~/code/archsetup/dotfiles"
+alias cdpf="cd ~/projects/finances/"
+alias cdpj="cd ~/projects/jr-estate/"
+alias cdpd="cd ~/projects/documents/"
+
+# =============================================================================
+# File Listing (exa)
+# =============================================================================
+alias ls="exa --group-directories-first"
+alias l="exa -lhF --group-directories-first"
+alias ll="exa -lhAF --group-directories-first"
+alias lt="exa -lthAF --group-directories-first"
+
+# =============================================================================
+# File Operations
+# =============================================================================
+alias mkd="mkdir -pv"
+alias open="xdg-open"
+alias linkdel="find . -type l ! -exec test -d {} \; -delete"
+alias linkfind="find . -type l ! -exec test -d {} \; -print"
+
+# =============================================================================
+# System Administration
+# =============================================================================
+alias df='dfc -p /dev/'
+alias ducks='du -cksh * | sort -rh | head -n11'
+alias ntop="sudo bandwhich"
+alias ptop="sudo powertop"
+alias running_services='systemctl list-units --type=service --state=running'
+alias ssn="sudo shutdown now"
+alias boot2bios="sudo systemctl reboot --firmware-setup"
+alias backup='sudo rsyncshot backup 1000'
+alias sysinfo='sudo inxi -v 8 -a -xxxA -xxxB -xxxC -xxxD -xxxG -xxxI -xxxm -xxxN -xxxR -xxxS -xxx --usb -d -I -pl -n -s --slots'
+alias timeshift='sudo timeshift-gtk'
+alias sysupgrade="topgrade"
+
+# =============================================================================
+# Network
+# =============================================================================
+alias myip='curl -4 https://chroot-me.in/ip/ 2>/dev/null || w3m -4 -dump https://chroot-me.in/ip'
+alias whereami="curl ipinfo.io"
+alias speedtest="speedtest-go"
+
+# =============================================================================
+# Applications
+# =============================================================================
+alias vim="nvim"
+alias et="emacs -nw"
+alias weather="wego"
+alias crm="tickrs -s CRM"
+alias handbrake="ghb"
+alias smerge="/usr/bin/smerge"
+alias stext="/opt/sublime_text/sublime_text"
+alias steam="flatpak run com.valvesoftware.Steam"
+alias xterm="xterm -ti 340"
+
+# =============================================================================
+# Stow (dotfiles management)
+# =============================================================================
+alias stow="stow --target=/home/cjennings"
+
+# =============================================================================
+# Ranger (file manager)
+# =============================================================================
+alias cdr='. ranger'
+alias r='. ranger'
+
+# =============================================================================
+# Programming
+# =============================================================================
+alias cc="gcc -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wconversion -Wextra -std=c2x -pedantic"
+alias gdbx="gdb --batch --ex r --ex bt --ex q --args"
+
+# =============================================================================
+# Claude Code
+# =============================================================================
+alias hey='claude "Read ./docs/protocols.org and ./docs/NOTES.org, follow their instructions, then run session startup workflow."'
+
+# =============================================================================
+# Phenomenology RAG (ollama/deepseek)
+# =============================================================================
+phenom() {
+ aichat --rag phenom -m ollama:deepseek-r1:70b "$@"
+}
diff --git a/dotfiles/common/.bashrc.d/emacs.sh b/dotfiles/common/.bashrc.d/emacs.sh
new file mode 100644
index 0000000..0a8444b
--- /dev/null
+++ b/dotfiles/common/.bashrc.d/emacs.sh
@@ -0,0 +1,24 @@
+# emacs.sh
+# Craig Jennings <c@cjennings.net>
+# Emacs-specific settings and functions
+
+# GTK/Emacs accessibility bug workaround
+# https://unix.stackexchange.com/questions/230238/
+export NO_AT_BRIDGE=1
+
+# Wake emacs from elisp freeze
+alias emacswake='for i in $(seq 1 500); do killall -s USR2 emacs; done'
+
+# Vterm shell integration
+# Allows shell to send information to vterm via escape sequences
+vterm_printf() {
+ if [ -n "$TMUX" ] && { [ "${TERM%%-*}" = "tmux" ] || [ "${TERM%%-*}" = "screen" ]; }; then
+ # Tell tmux to pass the escape sequences through
+ printf "\ePtmux;\e\e]%s\007\e\\" "$1"
+ elif [ "${TERM%%-*}" = "screen" ]; then
+ # GNU screen
+ printf "\eP\e]%s\007\e\\" "$1"
+ else
+ printf "\e]%s\e\\" "$1"
+ fi
+}
diff --git a/dotfiles/common/.bashrc.d/fzf.sh b/dotfiles/common/.bashrc.d/fzf.sh
new file mode 100644
index 0000000..9a5a9bd
--- /dev/null
+++ b/dotfiles/common/.bashrc.d/fzf.sh
@@ -0,0 +1,122 @@
+# fzf.sh
+# Craig Jennings <c@cjennings.net>
+# FZF settings and utility functions
+
+# =============================================================================
+# Settings
+# =============================================================================
+export FZF_DEFAULT_OPTS='--height=70%'
+export FZF_DEFAULT_COMMAND='rg --files --no-ignore-vcs --hidden'
+export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
+
+# Directory paths for convenience functions
+IF_GAMES_DIR="$HOME/sync/org/text.games"
+BOOKS_DIR="$HOME/sync/books"
+
+# =============================================================================
+# Navigation
+# =============================================================================
+
+# cdff - change directory to where a file resides
+cdff() {
+ file=$(fzf +m -q "$1")
+ dir=$(dirname "$file")
+ cd "$dir" || return 1
+}
+
+# cdd - cd to directory with fzf
+cdd() {
+ destdir=$(find "${1:-.}" -path '*/\.*' -prune \
+ -o -type d -print 2>/dev/null | fzf +m) &&
+ cd "$destdir"
+}
+
+# =============================================================================
+# System Admin
+# =============================================================================
+
+# Kill process with fzf
+kp() {
+ pid=$(ps -ef | sed 1d | eval "fzf ${FZF_DEFAULT_OPTS} -m --header='[kill:process]'" | awk '{print $2}')
+ if [ -n "$pid" ]; then
+ echo "$pid" | xargs kill -"${1:-9}"
+ kp
+ fi
+}
+
+# Install packages with fzf preview
+yinstall() {
+ yay -Slq | fzf --multi --preview 'yay -Si {1}' | xargs -ro yay -S --noconfirm
+}
+
+yinstall-skipverify() {
+ yay -Slq | fzf --multi --preview 'yay -Si {1}' | xargs -ro yay -S --noconfirm --mflags --skipinteg
+}
+
+# Remove packages with fzf preview
+yrm() {
+ yay -Qq | fzf --multi --preview 'yay -Qi {1}' | xargs -ro yay -Rns
+}
+
+# Find in file with fzf
+fif() {
+ if [ "$#" -eq 0 ]; then
+ echo "Need a string to search for!"
+ return 1
+ fi
+ rg --files-with-matches --no-messages "$1" | \
+ fzf --preview "highlight -O ansi -l {} 2>/dev/null | \
+ rg --colors 'match:bg:yellow' --ignore-case --pretty --context 10 '$1' || \
+ rg --ignore-case --pretty --context 10 '$1' {}"
+}
+
+# =============================================================================
+# Convenience
+# =============================================================================
+
+# Find and read epub book in terminal
+bk() {
+ bkfile=$(find "$BOOKS_DIR" -iname "*.epub" -print | fzf)
+ if [ -n "$bkfile" ]; then
+ epr "$bkfile"
+ fi
+}
+
+# Find and play interactive fiction game
+tg() {
+ gamefile=$(find "$IF_GAMES_DIR" -type f \( -iname "*.z[1-8]" -o -iname "*.zblorb" -o -iname "*.blorb" \) -print | fzf)
+ if [ -n "$gamefile" ]; then
+ frotz "$gamefile"
+ fi
+}
+
+# =============================================================================
+# WireGuard
+# =============================================================================
+
+wgup() {
+ # Shutdown existing connections first
+ output=$(sudo wg 2>/dev/null)
+ if [ -n "$output" ]; then
+ for iface in $(sudo wg show interfaces); do
+ sudo wg-quick down "${iface}"
+ done
+ fi
+ # Select and start new connection
+ wgfile=$(sudo find /etc/wireguard/ -iname "*.conf" -exec basename -s .conf {} \; | fzf)
+ if [ -n "$wgfile" ]; then
+ sudo wg-quick up "$wgfile"
+ sudo wg
+ fi
+}
+
+wgdown() {
+ output=$(sudo wg 2>/dev/null)
+ if [ -n "$output" ]; then
+ for iface in $(sudo wg show interfaces); do
+ sudo wg-quick down "${iface}"
+ done
+ fi
+}
+
+alias wg=wgup
diff --git a/dotfiles/common/.bashrc.d/git.sh b/dotfiles/common/.bashrc.d/git.sh
new file mode 100644
index 0000000..6c2b6ad
--- /dev/null
+++ b/dotfiles/common/.bashrc.d/git.sh
@@ -0,0 +1,32 @@
+# git.sh
+# Craig Jennings <c@cjennings.net>
+# Git aliases and convenience functions
+
+# =============================================================================
+# Aliases
+# =============================================================================
+alias gitlog="git log --graph --pretty=format:'%Cred%h%Creset %an: %s - %Creset %C(yellow)%d%Creset %Cgreen(%cr)%Creset' --abbrev-commit --date=relative"
+alias gitstatus='git status -sb'
+alias gitcom='git commit -m'
+alias gitpp='git pull --prune'
+alias gittagbydate="git for-each-ref --sort=creatordate --format '%(refname) %(creatordate)' refs/tags"
+
+# =============================================================================
+# Functions
+# =============================================================================
+
+# Stash, pull, pop
+gitsp() {
+ git stash && git pull && git stash pop
+}
+
+# Checkout branch with fzf
+gitck() {
+ git checkout "$(git branch --all | fzf | tr -d '[:space:]')"
+}
+
+# Diff with fzf preview
+gitdiff() {
+ preview="git diff $@ --color=always -- {-1}"
+ git diff "$@" --name-only | fzf -m --ansi --preview "$preview"
+}
diff --git a/dotfiles/common/.bashrc.d/media.sh b/dotfiles/common/.bashrc.d/media.sh
new file mode 100644
index 0000000..92fe2ce
--- /dev/null
+++ b/dotfiles/common/.bashrc.d/media.sh
@@ -0,0 +1,41 @@
+# media.sh
+# Craig Jennings <c@cjennings.net>
+# Media utilities - music, video, downloads
+
+# =============================================================================
+# Terminal MPV
+# =============================================================================
+alias play='mpv --no-video'
+alias shuffle='mpv --no-video --shuffle'
+
+# =============================================================================
+# Tidal
+# =============================================================================
+alias tdl="tidal-dl -l"
+alias ttdl="tsp tidal-dl -l"
+
+# =============================================================================
+# YouTube (yt-dlp)
+# =============================================================================
+# Video - single
+alias yt="yt-dlp --ignore-config --no-playlist --add-metadata -i -o '%(channel)s-%(title)s.%(ext)s'"
+alias tyt="tsp yt-dlp --ignore-config --no-playlist --add-metadata -i -o '%(channel)s-%(title)s.%(ext)s'"
+
+# Video - playlist
+alias ytp="yt-dlp --ignore-config --yes-playlist --add-metadata -i -o '%(channel)s-%(playlist_title)s-%(playlist_index)s-%(title)s.%(ext)s'"
+alias tytp="tsp yt-dlp --ignore-config --yes-playlist --add-metadata -i -o '%(channel)s-%(playlist_title)s-%(playlist_index)s-%(title)s.%(ext)s'"
+
+# Audio - single
+alias yta="yt-dlp --ignore-config --no-playlist -x -f bestaudio/best -o '%(artist)s-%(title)s.%(ext)s'"
+alias tyta="tsp yt-dlp --ignore-config --no-playlist -x -f bestaudio/best -o '%(artist)s-%(title)s.%(ext)s'"
+
+# Audio - playlist
+alias ytap="yt-dlp --ignore-config --yes-playlist -x -f bestaudio/best -o '%(playlist_index)s-%(artist)s-%(title)s.%(ext)s'"
+alias tytap="tsp yt-dlp --ignore-config --yes-playlist -x -f bestaudio/best -o '%(playlist_index)s-%(artist)s-%(title)s.%(ext)s'"
+
+# =============================================================================
+# Audible Conversion (AAXtoMP3)
+# =============================================================================
+alias aax2flac='AAXtoMP3 -f'
+alias aax2mp3='AAXtoMP3 -c -e:mp3'
+alias aax2opus='AAXtoMP3 --opus -t . -c'
diff --git a/dotfiles/common/.bashrc.d/utilities.sh b/dotfiles/common/.bashrc.d/utilities.sh
new file mode 100644
index 0000000..431cac0
--- /dev/null
+++ b/dotfiles/common/.bashrc.d/utilities.sh
@@ -0,0 +1,206 @@
+# utilities.sh
+# Craig Jennings <c@cjennings.net>
+# General utility functions
+
+# =============================================================================
+# Archive Extraction
+# =============================================================================
+extract() {
+ if [ -f "$1" ]; then
+ case "$1" in
+ *.tar.bz2) tar xjf "$1" ;;
+ *.tar.gz) tar xzf "$1" ;;
+ *.bz2) bunzip2 "$1" ;;
+ *.rar) rar x "$1" ;;
+ *.gz) gunzip "$1" ;;
+ *.tar) tar xf "$1" ;;
+ *.tbz2) tar xjf "$1" ;;
+ *.tgz) tar xzf "$1" ;;
+ *.zip) unzip "$1" ;;
+ *.Z) uncompress "$1" ;;
+ *) echo "$1 cannot be extracted via extract()" ;;
+ esac
+ else
+ echo "$1 is not a valid file"
+ fi
+}
+
+# =============================================================================
+# Archive Compression
+# =============================================================================
+compress() {
+ if [ $# -ne 2 ]; then
+ echo "Usage: compress <format> <file_or_directory>"
+ echo "Formats: tar.bz2, tar.gz, bz2, tar, tbz2, tgz, zip, gz, Z"
+ return 1
+ fi
+
+ format="$1"
+ target="$2"
+
+ if [ ! -e "$target" ]; then
+ echo "Error: '$target' does not exist"
+ return 1
+ fi
+
+ basename=$(basename "$target")
+
+ case "$format" in
+ tar.bz2|tbz2) output="${basename}.tar.bz2" ;;
+ tar.gz|tgz) output="${basename}.tar.gz" ;;
+ bz2) output="${target}.bz2" ;;
+ gz) output="${target}.gz" ;;
+ tar) output="${basename}.tar" ;;
+ zip) output="${basename}.zip" ;;
+ Z) output="${target}.Z" ;;
+ *)
+ echo "Error: Unknown format '$format'"
+ return 1
+ ;;
+ esac
+
+ if [ -e "$output" ]; then
+ printf "Warning: '%s' already exists. Overwrite? (y/N): " "$output"
+ read -r response
+ case "$response" in
+ [yY]|[yY][eE][sS]) rm -f "$output" ;;
+ *) echo "Aborted." && return 1 ;;
+ esac
+ fi
+
+ case "$format" in
+ tar.bz2|tbz2) tar -cjf "$output" "$target" ;;
+ tar.gz|tgz) tar -czf "$output" "$target" ;;
+ bz2)
+ [ -d "$target" ] && echo "Error: bz2 only works on files" && return 1
+ bzip2 -k "$target"
+ ;;
+ gz)
+ [ -d "$target" ] && echo "Error: gz only works on files" && return 1
+ gzip -k "$target"
+ ;;
+ tar) tar -cf "$output" "$target" ;;
+ zip)
+ [ -d "$target" ] && zip -r "$output" "$target" || zip "$output" "$target"
+ ;;
+ Z)
+ [ -d "$target" ] && echo "Error: Z only works on files" && return 1
+ command compress -c "$target" > "$output"
+ ;;
+ esac
+
+ [ $? -eq 0 ] && echo "Created $output" || echo "Compression failed"
+}
+
+# =============================================================================
+# DD Helper
+# =============================================================================
+dd_with_bs() {
+ OUT_DIR=$(dirname "$2")
+ if [ ! -e "$1" ] || [ ! -e "$OUT_DIR" ]; then
+ echo "$1 or $OUT_DIR doesn't exist"
+ return 1
+ fi
+ IN_BS=$(stat -c "%o" "$1")
+ OUT_BS=$(stat -c "%o" "$OUT_DIR")
+ echo dd \"if=$1\" \"of=$2\" \"ibs=$IN_BS\" \"obs=$OUT_BS\"
+}
+
+# =============================================================================
+# Clock, Timer, Alarm, Stopwatch
+# =============================================================================
+export BEEP="/usr/share/sounds/freedesktop/stereo/bell.oga"
+alias beep='paplay $BEEP'
+
+clock() {
+ while true; do
+ tput clear
+ echo ""
+ date +" %l : %M %p" | figlet -f roman -w 200
+ sleep 1
+ done
+}
+
+timer() {
+ if [ "$#" -lt 2 ]; then
+ echo "Pass the time and a notification. Example: timer 1h30m Parking expiring"
+ return 1
+ fi
+ message="${*:2}"
+ start_time=$(date +"%H:%M:%S %p")
+ printf "\nStarting %s timer at %s\n" "$1" "$start_time"
+ snore "$1" && paplay "$BEEP" && notify-send "Timer" "$message"
+}
+
+alarm() {
+ if [ "$#" -lt 2 ]; then
+ echo "Pass both the time and a message. Example: alarm 1:45pm Time to eat!"
+ return 1
+ fi
+
+ if ! date -d "$1" >/dev/null 2>&1; then
+ echo "Invalid time: $1"
+ return 1
+ fi
+
+ echo "paplay \$BEEP && notify-send \"Alarm\" \"$*\"" | at "$1" >/dev/null 2>&1
+ echo ""
+ echo "Alarm '${*:2}' is queued for $1."
+ echo "To see all alarms: atq"
+ echo "To remove an alarm: atrm <number>"
+ echo ""
+}
+
+# Stopwatch
+sw_start_time=0
+sw_started=0
+
+swreset() {
+ sw_start_time=0
+ sw_started=0
+ echo "Stopwatch reset"
+}
+
+swshow() {
+ if [ "$sw_started" = 0 ]; then
+ echo "Error: Stopwatch not started" >&2
+ return 1
+ fi
+
+ current_time=$(date +%s)
+ elapsed_time=$((current_time - sw_start_time))
+
+ if [ "$elapsed_time" -lt 60 ]; then
+ echo "Elapsed time: $elapsed_time seconds"
+ elif [ "$elapsed_time" -lt 3600 ]; then
+ minutes=$((elapsed_time / 60))
+ seconds=$((elapsed_time % 60))
+ echo "Elapsed time: $minutes minutes, $seconds seconds"
+ else
+ hours=$((elapsed_time / 3600))
+ minutes=$(((elapsed_time / 60) % 60))
+ seconds=$((elapsed_time % 60))
+ echo "Elapsed time: $hours hours, $minutes minutes, $seconds seconds"
+ fi
+}
+
+swstop() {
+ swshow
+ swreset
+}
+
+swstart() {
+ if [ "$sw_started" = 1 ]; then
+ printf "Stopwatch is already started. Reset? (y/n): "
+ read -r answer
+ case "$answer" in
+ [yY]) swreset ;;
+ [nN]) echo "Stopwatch not reset." && swshow && return ;;
+ *) echo "Error: Invalid input." >&2 && return 1 ;;
+ esac
+ fi
+
+ sw_started=1
+ sw_start_time=$(date +%s)
+ printf "Stopwatch started at %s\n\n" "$(date +"%H:%M:%S %p")"
+}