Add seasonal palettes and selection prompts

- Implement dynamic/static season support in shared PS1

- Add season selection prompts to Linux and macOS installers
This commit is contained in:
2026-01-24 09:11:07 +00:00
parent dbeadcf1e4
commit 006a3add58
3 changed files with 178 additions and 12 deletions

View File

@@ -23,6 +23,8 @@ MARKER_END="# <<< dotfiles (managed) <<<"
# Select install mode (PS1, banner, or both) # Select install mode (PS1, banner, or both)
install_ps1=1 install_ps1=1
install_banner=1 install_banner=1
season_mode="dynamic"
season_choice=""
if [[ -t 0 ]]; then if [[ -t 0 ]]; then
echo "Install options:" echo "Install options:"
echo " 1) PS1 only" echo " 1) PS1 only"
@@ -35,6 +37,39 @@ if [[ -t 0 ]]; then
""|3) install_ps1=1; install_banner=1 ;; ""|3) install_ps1=1; install_banner=1 ;;
*) echo "Invalid choice, using both."; install_ps1=1; install_banner=1 ;; *) echo "Invalid choice, using both."; install_ps1=1; install_banner=1 ;;
esac esac
if [[ "$install_ps1" -eq 1 ]]; then
echo
echo "Season mode:"
echo " 1) Dynamic (auto by date)"
echo " 2) Static (pick one season)"
read -r -p "Choose [1]: " season_mode_choice
case "${season_mode_choice}" in
2)
season_mode="static"
echo "Pick a season:"
echo " 1) Winter"
echo " 2) Spring"
echo " 3) Summer"
echo " 4) Autumn"
read -r -p "Choose [1]: " season_pick
case "${season_pick}" in
2) season_choice="spring" ;;
3) season_choice="summer" ;;
4) season_choice="autumn" ;;
""|1) season_choice="winter" ;;
*) echo "Invalid choice, using winter."; season_choice="winter" ;;
esac
;;
""|1)
season_mode="dynamic"
;;
*)
echo "Invalid choice, using dynamic."
season_mode="dynamic"
;;
esac
fi
fi fi
if [[ "$install_banner" -eq 1 ]]; then if [[ "$install_banner" -eq 1 ]]; then
@@ -94,8 +129,17 @@ fi
if [[ "$install_ps1" -eq 1 ]]; then if [[ "$install_ps1" -eq 1 ]]; then
cp -f "$SRC_PS1" "$DST_PS1" cp -f "$SRC_PS1" "$DST_PS1"
chmod 0644 "$DST_PS1" chmod 0644 "$DST_PS1"
{
printf 'PS1_SEASON_MODE=%s\n' "$season_mode"
if [[ "$season_mode" == "static" && -n "$season_choice" ]]; then
printf 'PS1_SEASON=%s\n' "$season_choice"
fi
} > /etc/ps1-season
chmod 0644 /etc/ps1-season
else else
rm -f "$DST_PS1" rm -f "$DST_PS1"
rm -f /etc/ps1-season
fi fi
if [[ "$install_banner" -eq 1 ]]; then if [[ "$install_banner" -eq 1 ]]; then

View File

@@ -7,14 +7,57 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
SRC_PS1="$REPO_ROOT/ps1/ps1.sh" SRC_PS1="$REPO_ROOT/ps1/ps1.sh"
DST_DIR="$HOME/.config/ps1" DST_DIR="$HOME/.config/ps1"
DST_PS1="$DST_DIR/ps1.sh" DST_PS1="$DST_DIR/ps1.sh"
SEASON_FILE="$DST_DIR/season"
MARKER_START="# >>> user ps1 (managed) >>>" MARKER_START="# >>> user ps1 (managed) >>>"
MARKER_END="# <<< user ps1 (managed) <<<" MARKER_END="# <<< user ps1 (managed) <<<"
season_mode="dynamic"
season_choice=""
if [[ -t 0 ]]; then
echo "Season mode:"
echo " 1) Dynamic (auto by date)"
echo " 2) Static (pick one season)"
read -r -p "Choose [1]: " season_mode_choice
case "${season_mode_choice}" in
2)
season_mode="static"
echo "Pick a season:"
echo " 1) Winter"
echo " 2) Spring"
echo " 3) Summer"
echo " 4) Autumn"
read -r -p "Choose [1]: " season_pick
case "${season_pick}" in
2) season_choice="spring" ;;
3) season_choice="summer" ;;
4) season_choice="autumn" ;;
""|1) season_choice="winter" ;;
*) echo "Invalid choice, using winter."; season_choice="winter" ;;
esac
;;
""|1)
season_mode="dynamic"
;;
*)
echo "Invalid choice, using dynamic."
season_mode="dynamic"
;;
esac
fi
mkdir -p "$DST_DIR" mkdir -p "$DST_DIR"
cp -f "$SRC_PS1" "$DST_PS1" cp -f "$SRC_PS1" "$DST_PS1"
chmod 0644 "$DST_PS1" chmod 0644 "$DST_PS1"
{
printf 'PS1_SEASON_MODE=%s\n' "$season_mode"
if [[ "$season_mode" == "static" && -n "$season_choice" ]]; then
printf 'PS1_SEASON=%s\n' "$season_choice"
fi
} > "$SEASON_FILE"
chmod 0644 "$SEASON_FILE"
add_source_block() { add_source_block() {
local file="$1" local file="$1"
[[ -f "$file" ]] || touch "$file" [[ -f "$file" ]] || touch "$file"

View File

@@ -37,6 +37,58 @@ _ps1_has_nf() {
return 1 return 1
} }
# Season selection (dynamic or static)
# PS1_SEASON_MODE=dynamic|static
# PS1_SEASON= winter|spring|summer|autumn
# Also reads config from /etc/ps1-season or ~/.config/ps1/season
_ps1_season_config() {
local cfg=""
if [[ -r /etc/ps1-season ]]; then
cfg="/etc/ps1-season"
elif [[ -r "$HOME/.config/ps1/season" ]]; then
cfg="$HOME/.config/ps1/season"
fi
if [[ -n "$cfg" ]]; then
while IFS='=' read -r k v; do
k="${k//[[:space:]]/}"
v="${v//[[:space:]]/}"
case "$k" in
PS1_SEASON_MODE) export PS1_SEASON_MODE="$v" ;;
PS1_SEASON) export PS1_SEASON="$v" ;;
esac
done < "$cfg"
fi
}
_ps1_season_dynamic() {
local mm dd m d
mm=$(TZ=Europe/Oslo date +%m); dd=$(TZ=Europe/Oslo date +%d)
m=$((10#$mm)); d=$((10#$dd))
if (( m >= 3 && m <= 5 )); then
echo "spring"
elif (( m >= 6 && m <= 8 )); then
echo "summer"
elif (( m == 9 || m == 10 || (m == 11 && d < 15) )); then
echo "autumn"
else
echo "winter"
fi
}
_ps1_season() {
_ps1_season_config
local mode="${PS1_SEASON_MODE:-dynamic}"
local season="${PS1_SEASON:-}"
if [[ "$mode" == "static" && -n "$season" ]]; then
echo "$season"
else
_ps1_season_dynamic
fi
}
# Time-based emoji (Europe/Oslo) # Time-based emoji (Europe/Oslo)
_ps1_symbol() { _ps1_symbol() {
local hh mm h m local hh mm h m
@@ -73,22 +125,48 @@ __PS1_SYM=""
__PS1_PATH="" __PS1_PATH=""
__PS1_STATUS=0 __PS1_STATUS=0
__PS1_USE_NF=0 __PS1_USE_NF=0
__PS1_SEASON="winter"
_ps1_set_prompt() { _ps1_set_prompt() {
local RST="\[\e[0m\]" local RST="\[\e[0m\]"
# Two-zone palette # Seasonal palettes (Z1 is darker than Z2)
# Zone 1: gray-blue pastel (date/time/user) local Z1_BG Z1_FG Z2_BG Z2_FG PATH_FG FRAME
local Z1_BG="\[\e[48;5;61m\]" case "$__PS1_SEASON" in
local Z1_FG="\[\e[38;5;255m\]" spring)
Z1_BG="\[\e[48;5;71m\]"
# Zone 2: turquoise / cool green (host/path) Z1_FG="\[\e[38;5;255m\]"
local Z2_BG="\[\e[48;5;37m\]" Z2_BG="\[\e[48;5;120m\]"
local Z2_FG="\[\e[38;5;255m\]" Z2_FG="\[\e[38;5;255m\]"
local PATH_FG="\[\e[38;5;194m\]" PATH_FG="\[\e[38;5;193m\]"
FRAME="\[\e[38;5;65m\]"
# Frame ;;
local FRAME="\[\e[38;5;60m\]" summer)
Z1_BG="\[\e[48;5;142m\]"
Z1_FG="\[\e[38;5;255m\]"
Z2_BG="\[\e[48;5;214m\]"
Z2_FG="\[\e[38;5;0m\]"
PATH_FG="\[\e[38;5;223m\]"
FRAME="\[\e[38;5;130m\]"
;;
autumn)
Z1_BG="\[\e[48;5;95m\]"
Z1_FG="\[\e[38;5;255m\]"
Z2_BG="\[\e[48;5;173m\]"
Z2_FG="\[\e[38;5;255m\]"
PATH_FG="\[\e[38;5;223m\]"
FRAME="\[\e[38;5;95m\]"
;;
*)
# winter (default)
Z1_BG="\[\e[48;5;61m\]"
Z1_FG="\[\e[38;5;255m\]"
Z2_BG="\[\e[48;5;37m\]"
Z2_FG="\[\e[38;5;255m\]"
PATH_FG="\[\e[38;5;194m\]"
FRAME="\[\e[38;5;60m\]"
;;
esac
# Status colors # Status colors
local OK="\[\e[38;5;76m\]" local OK="\[\e[38;5;76m\]"
@@ -122,6 +200,7 @@ _ps1_update() {
__PS1_STATUS=$? __PS1_STATUS=$?
__PS1_SYM="$(_ps1_symbol)" __PS1_SYM="$(_ps1_symbol)"
__PS1_PATH="$(_ps1_path)" __PS1_PATH="$(_ps1_path)"
__PS1_SEASON="$(_ps1_season)"
if _ps1_has_nf; then __PS1_USE_NF=1; else __PS1_USE_NF=0; fi if _ps1_has_nf; then __PS1_USE_NF=1; else __PS1_USE_NF=0; fi
_ps1_set_prompt _ps1_set_prompt
} }