Add ps1.sh

This commit is contained in:
2026-01-24 02:18:55 +00:00
parent 6cac49b7c4
commit 4cdbad53ae

109
ps1.sh Normal file
View File

@@ -0,0 +1,109 @@
#!/usr/bin/env bash
# ps1.sh - Bash PS1 with emoji + optional animation helpers
# Source this file: source /path/to/ps1.sh
# Then enable: ps1_on
# Optional animate: psanimate 0.5
# Stop animation: psanimate_stop
# Disable: ps1_off
# Only for interactive bash
case "$-" in
*i*) ;;
*) return 0 ;;
esac
# ---- Emoji pools (edit these) ----
# Keep them as simple strings; terminals must support the emoji glyphs.
__PS1_EMOJI_FUN=( "🚀" "✨" "🔥" "🌈" "🧠" "🛠️" "📦" "🧩" "🧪" "⚡" "🐧" "🛰️" )
# ---- Emoji function (simple random) ----
_ps1_emoji() {
local n="${#__PS1_EMOJI_FUN[@]}"
# RANDOM is bash built-in
printf '%s' "${__PS1_EMOJI_FUN[RANDOM % n]}"
}
# ---- Your PS1 core (edit to taste) ----
# This is intentionally simple: time, jobs, host, cwd, emoji.
# Use \\[ \\] around non-printing escape sequences to keep line editing sane.
_ps1_build() {
local emoji="$(_ps1_emoji)"
# Colors: 35 (purple) + 38 (cyan-ish) from your earlier style
printf '%b' \
"\[\e[0m\]\[\e[38;5;35m\]╭─(\[\e[38;5;38m\]\t\[\e[38;5;35m\])-(\[\e[38;5;38m\]\j\[\e[38;5;35m\])-(\[\e[38;5;38m\]\H\[\e[38;5;35m\])-(\[\e[38;5;38m\]\w\[\e[38;5;35m\])\n\[\e[38;5;35m\]╰──${emoji} \[\e[0m\]"
}
# ---- PROMPT_COMMAND hook (updates PS1 each prompt) ----
# We add our updater without nuking an existing PROMPT_COMMAND.
__PS1_PREV_PROMPT_COMMAND=""
_ps1_set_prompt_command() {
# Save existing PROMPT_COMMAND once
if [[ -z "${__PS1_PREV_PROMPT_COMMAND+x}" || -z "$__PS1_PREV_PROMPT_COMMAND" ]]; then
__PS1_PREV_PROMPT_COMMAND="${PROMPT_COMMAND-}"
fi
local updater='_PS1=$(_ps1_build); export PS1="$_PS1"'
if [[ -z "${PROMPT_COMMAND-}" ]]; then
PROMPT_COMMAND="$updater"
else
# Avoid duplicating if user runs ps1_on multiple times
case "$PROMPT_COMMAND" in
*"_ps1_build"*) : ;;
*)
PROMPT_COMMAND="$updater; $PROMPT_COMMAND"
;;
esac
fi
}
_ps1_restore_prompt_command() {
PROMPT_COMMAND="${__PS1_PREV_PROMPT_COMMAND-}"
}
# ---- Public controls ----
ps1_on() {
_ps1_set_prompt_command
# Force immediate update
_PS1="$(_ps1_build)"; export PS1="$_PS1"
}
ps1_off() {
psanimate_stop >/dev/null 2>&1 || true
_ps1_restore_prompt_command
}
# ---- Animation helpers (simple loop that forces prompt refresh) ----
# This follows the same basic idea as in the Medium post: background loop updates prompt periodically. :contentReference[oaicite:2]{index=2}
__PSANIMATE_PIDFILE="/tmp/psanimatepid-$$"
psanimate() {
local interval="${1:-0.5}"
# Stop existing animator for this shell, if any
psanimate_stop >/dev/null 2>&1 || true
# Ensure prompt is enabled
ps1_on
(
while :; do
# Trigger a prompt rebuild by setting PS1; next prompt draw will use it.
_PS1="$(_ps1_build)"; export PS1="$_PS1"
sleep "$interval"
done
) &
echo "$!" > "$__PSANIMATE_PIDFILE"
}
psanimate_stop() {
if [[ -f "$__PSANIMATE_PIDFILE" ]]; then
local pid
pid="$(cat "$__PSANIMATE_PIDFILE" 2>/dev/null || true)"
if [[ -n "${pid:-}" ]]; then
kill "$pid" 2>/dev/null || true
fi
rm -f "$__PSANIMATE_PIDFILE"
fi
}