Created
February 22, 2026 22:15
-
-
Save chris-piekarski/94ced5062bc69b595dc36c10fac2f2ed to your computer and use it in GitHub Desktop.
Multi-Session History System
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ============================================================ | |
| # Advanced Multi-Session History System | |
| # ============================================================ | |
| # ---------------------------- | |
| # Core History Configuration | |
| # ---------------------------- | |
| shopt -s histappend | |
| export HISTSIZE=100000 | |
| export HISTFILESIZE=200000 | |
| export HISTCONTROL=ignoreboth:erasedups | |
| export HISTTIMEFORMAT='%F %T ' | |
| export HISTIGNORE='hs*:hg*:history*:clear' | |
| # ---------------------------- | |
| # Session History File | |
| # ---------------------------- | |
| HISTDIR="$HOME/.bash_sessions" | |
| mkdir -p "$HISTDIR" | |
| SESSION_ID="$(date +%Y%m%d-%H%M%S)_$(tty 2>/dev/null | tr '/' '_' | sed 's/^_//')_pid$$" | |
| HISTFILE="$HISTDIR/history.$SESSION_ID" | |
| # ---------------------------- | |
| # Global Append-Only Ledger | |
| # ---------------------------- | |
| GLOBAL_HIST="$HOME/.bash_history_global" | |
| __log_global() { | |
| local cmd | |
| cmd="$(history 1 | sed 's/^ *[0-9]\+ *//')" | |
| [ -z "$cmd" ] && return | |
| [[ "$cmd" == " "* ]] && return | |
| local base_cmd="${cmd%% *}" | |
| case "$base_cmd" in | |
| hs|hg|history|clear) | |
| return | |
| ;; | |
| esac | |
| local last_cmd | |
| last_cmd="$(tail -n 1 "$GLOBAL_HIST" 2>/dev/null | awk -F'\t' '{print $3}')" | |
| [[ "$cmd" == "$last_cmd" ]] && return | |
| printf '%s\t%s\t%s\n' \ | |
| "$(date '+%F %T')" \ | |
| "$(tty 2>/dev/null)" \ | |
| "$cmd" >> "$GLOBAL_HIST" | |
| } | |
| __history_guard() { | |
| local last | |
| last="$(history 1 | sed 's/^ *[0-9]\+ *//')" | |
| local base="${last%% *}" | |
| case "$base" in | |
| hs|hg|history|clear) | |
| history -d $((HISTCMD-1)) | |
| ;; | |
| esac | |
| } | |
| PROMPT_COMMAND='__history_guard; history -a; __log_global' | |
| # ============================================================ | |
| # History Help Banner | |
| # ============================================================ | |
| __hist_help() { | |
| local cmd="$1" desc="$2" dflt="$3" | |
| cat <<EOF | |
| _ _ _ _ | |
| | || |___| |_ __| |_ ___ _ _ _ _ | |
| | __ / -_) | '_ \\ ' \\/ _ \\ '_| || | | |
| |_||_\\___|_| .__/_||_\\___/_| \\_, | | |
| |_| |__/ | |
| $cmd — $desc | |
| Usage: | |
| $cmd # show last $dflt entries | |
| $cmd -n N # show last N entries | |
| $cmd REGEX # regex search (case-insensitive) | |
| $cmd -n N REGEX # regex search, limit results | |
| $cmd clean # clear history | |
| $cmd -h | --help | help # show this help | |
| Regex applies to COMMAND only. | |
| Examples: | |
| $cmd | |
| $cmd '^git' | |
| $cmd -n 25 'docker|podman' | |
| EOF | |
| } | |
| # ============================================================ | |
| # History Filtering (match command only) | |
| # ============================================================ | |
| __hist_filter_history_output() { | |
| local limit="$1"; shift | |
| local pattern="$*" | |
| if [ -z "$pattern" ]; then | |
| tail -n "$limit" | |
| return 0 | |
| fi | |
| gawk -v pat="$pattern" -v lim="$limit" ' | |
| BEGIN { IGNORECASE=1 } | |
| { | |
| orig=$0 | |
| cmd=$0 | |
| sub(/^ *[0-9]+[ \t]+/, "", cmd) | |
| sub(/^[0-9]{4}-[0-9]{2}-[0-9]{2}[ \t]+[0-9]{2}:[0-9]{2}:[0-9]{2}[ \t]+/, "", cmd) | |
| if (cmd ~ pat) { | |
| pos = index(orig, cmd) | |
| pre = (pos > 0) ? substr(orig, 1, pos-1) : "" | |
| c = cmd | |
| c = gensub(pat, "\033[1;31m&\033[0m", "g", c) | |
| out[++n] = pre c | |
| } | |
| } | |
| END { | |
| start = (n > lim) ? (n - lim + 1) : 1 | |
| for (i = start; i <= n; i++) print out[i] | |
| } | |
| ' | |
| } | |
| # ============================================================ | |
| # hs — Session History | |
| # ============================================================ | |
| hs() { | |
| local limit=100 | |
| case "${1-}" in | |
| -h|--help|help) | |
| __hist_help "hs" "session history (this shell only)" "$limit" | |
| return 0 | |
| ;; | |
| clean) | |
| echo "Clearing current session history..." | |
| history -c | |
| history -w | |
| echo "Session history cleared." | |
| return 0 | |
| ;; | |
| esac | |
| if [[ "${1-}" == "-n" ]]; then | |
| limit="${2-100}" | |
| shift 2 | |
| fi | |
| history | __hist_filter_history_output "$limit" "$*" | |
| } | |
| # ============================================================ | |
| # hg — Global History | |
| # ============================================================ | |
| hg() { | |
| local limit=200 | |
| case "${1-}" in | |
| -h|--help|help) | |
| __hist_help "hg" "global history (all sessions)" "$limit" | |
| return 0 | |
| ;; | |
| clean) | |
| echo "⚠️ This will permanently erase ALL global history." | |
| read -rp "Type 'yes' to confirm: " confirm | |
| if [[ "$confirm" == "yes" ]]; then | |
| > "$GLOBAL_HIST" | |
| echo "Global history cleared." | |
| else | |
| echo "Aborted." | |
| fi | |
| return 0 | |
| ;; | |
| esac | |
| if [[ "${1-}" == "-n" ]]; then | |
| limit="${2-200}" | |
| shift 2 | |
| fi | |
| local pattern="$*" | |
| if [ -z "$pattern" ]; then | |
| tail -n "$limit" "$GLOBAL_HIST" | nl -ba | |
| return 0 | |
| fi | |
| gawk -v pat="$pattern" -v lim="$limit" ' | |
| BEGIN { IGNORECASE=1; FS="\t" } | |
| { | |
| orig=$0 | |
| cmd=$3 | |
| if (cmd ~ pat) { | |
| sub(/\t[^\t]*$/, "\t" gensub(pat, "\033[1;31m&\033[0m", "g", cmd), orig) | |
| out[++n] = orig | |
| } | |
| } | |
| END { | |
| start = (n > lim) ? (n - lim + 1) : 1 | |
| for (i = start; i <= n; i++) print out[i] | |
| } | |
| ' "$GLOBAL_HIST" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment