#!/usr/bin/env bash # Must be sourced if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then echo "Bruk: source ps1.sh" exit 1 fi case "$-" in *i*) ;; *) return 0 ;; esac # ------------------------------------------------- # Time-based symbol (Europe/Oslo) # Updates naturally when time passes (no session-lock). # ------------------------------------------------- _ps1_symbol() { local hh mm h m hh="$(TZ=Europe/Oslo date +%H)" mm="$(TZ=Europe/Oslo date +%M)" h=$((10#$hh)) m=$((10#$mm)) if (( h >= 5 && h <= 8 )); then printf '%s' "🌅" # tidlig elif (( h >= 9 && h <= 10 )); then printf '%s' "☕" # formiddag elif (( h == 11 && m < 30 )); then printf '%s' "🥪" # lunsj elif (( (h == 11 && m >= 30) || (h >= 12 && h <= 15) )); then printf '%s' "💻" # dag elif (( h == 16 )); then printf '%s' "🍲" # middag elif (( h >= 17 && h <= 22 )); then printf '%s' "🌆" # kveld else 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="$(_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\]" # 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}╰──${status_color}➜ \\$${RST} ${sym} " printf '%s' "$ps1" } # ------------------------------------------------- # Enable / disable # ------------------------------------------------- __PS1_PREV_PROMPT_COMMAND="${PROMPT_COMMAND-}" ps1_on() { # 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)" } ps1_off() { PROMPT_COMMAND="$__PS1_PREV_PROMPT_COMMAND" }