From ca3a0a7c93e5ca63ab6b98c4dd7323312f8eaf3b Mon Sep 17 00:00:00 2001 From: steffen Date: Sat, 24 Jan 2026 03:32:36 +0000 Subject: [PATCH] . --- ps1.sh | 95 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 14 deletions(-) diff --git a/ps1.sh b/ps1.sh index 8ec6971..b1c2467 100644 --- a/ps1.sh +++ b/ps1.sh @@ -12,7 +12,8 @@ case "$-" in esac # ------------------------------------------------- -# Emoji / symbol based on time (Europe/Oslo) +# Time-based symbol (Europe/Oslo) +# Updates naturally when time passes (no session-lock). # ------------------------------------------------- _ps1_symbol() { local hh mm h m @@ -22,40 +23,104 @@ _ps1_symbol() { m=$((10#$mm)) if (( h >= 5 && h <= 8 )); then - printf '%s' "🌅" + printf '%s' "🌅" # tidlig elif (( h >= 9 && h <= 10 )); then - printf '%s' "☕" + printf '%s' "☕" # formiddag elif (( h == 11 && m < 30 )); then - printf '%s' "🥪" + printf '%s' "🥪" # lunsj elif (( (h == 11 && m >= 30) || (h >= 12 && h <= 15) )); then - printf '%s' "💻" + printf '%s' "💻" # dag elif (( h == 16 )); then - printf '%s' "🍲" + printf '%s' "🍲" # middag elif (( h >= 17 && h <= 22 )); then - printf '%s' "🌆" + printf '%s' "🌆" # kveld else - printf '%s' "🌙" + printf '%s' "🌙" # natt fi } +# ------------------------------------------------- +# Path shortening (keeps /home/user visible; shortens deeper paths) +# Example: +# /home/steffen/projects/very/long/path -> /home/steffen/…/long/path +# ------------------------------------------------- +_ps1_path() { + local p="$PWD" + local max_tail=2 # keep last 2 path components + local parts=() + + # Split path into array + IFS='/' read -r -a parts <<< "$p" + + # If path is short enough, return it unchanged + # Heuristic: fewer than 6 components -> keep full path + if ((${#parts[@]} < 6)); then + printf '%s' "$p" + return + fi + + # Build prefix: / + first 2 non-empty components (e.g. home/steffen) + local prefix="/" + local taken=0 + local i + + for ((i=0; i<${#parts[@]}; i++)); do + [[ -z "${parts[i]}" ]] && continue + prefix+="${parts[i]}" + taken=$((taken+1)) + if (( taken >= 2 )); then + break + fi + prefix+="/" + done + + # Build tail: last N components + local tail="" + local count=0 + for ((i=${#parts[@]}-1; i>=0; i--)); do + [[ -z "${parts[i]}" ]] && continue + tail="/${parts[i]}${tail}" + count=$((count+1)) + if (( count >= max_tail )); then + break + fi + done + + printf '%s' "${prefix}/…${tail}" +} + # ------------------------------------------------- # Build PS1 +# Adds: +# 2) Exit-status feedback: arrow + $ turns red when last cmd failed +# 3) Shorter path (but keeps /home/user visible) # ------------------------------------------------- _ps1_build() { local sym path sym="$(_ps1_symbol)" - path="$(pwd)" + path="$(_ps1_path)" + # Pastel-ish 256 colors local BOX="\[\e[38;5;183m\]" local VAL="\[\e[38;5;117m\]" local ACC="\[\e[38;5;229m\]" local RST="\[\e[0m\]" - # NOTE: - # - PS1 escapes must be \\d \\A \\u \\h \\n - # - NO $variables inside PS1 (PS1 re-parses $) + # Status colors + local OK="\[\e[38;5;76m\]" # green-ish + local BAD="\[\e[38;5;203m\]" # red-ish + + # Arrow + $ changes color based on last exit code. + # NOTE: PROMPT_COMMAND runs after the command; $? is last command status here. + local status_color + if [[ "${__PS1_LAST_STATUS:-0}" -eq 0 ]]; then + status_color="$OK" + else + status_color="$BAD" + fi + local ps1 - ps1="${BOX}╭─(${ACC}\\d${BOX} ${ACC}\\A${BOX})-(${VAL}\\u${BOX}@${VAL}\\h${BOX})-(${VAL}${path}${BOX})${RST}\\n${BOX}╰──➜ ${RST}\\$ ${sym} " + ps1="${BOX}╭─(${ACC}\\d${BOX} ${ACC}\\A${BOX})-(${VAL}\\u${BOX}@${VAL}\\h${BOX})-(${VAL}${path}${BOX})${RST}\\n${BOX}╰──${status_color}➜ \\$${RST} ${sym} " printf '%s' "$ps1" } @@ -66,7 +131,9 @@ _ps1_build() { __PS1_PREV_PROMPT_COMMAND="${PROMPT_COMMAND-}" ps1_on() { - PROMPT_COMMAND='_PS1="$(_ps1_build)"; PS1="$_PS1"' + # Capture last command status each time before building PS1 + PROMPT_COMMAND='__PS1_LAST_STATUS=$?; _PS1="$(_ps1_build)"; PS1="$_PS1"' + __PS1_LAST_STATUS=$? PS1="$(_ps1_build)" }