From ecdfa232f514a4e79a80b5202132992c9e8af361 Mon Sep 17 00:00:00 2001 From: steffen Date: Sat, 24 Jan 2026 04:00:46 +0000 Subject: [PATCH] med fallback --- bashscript.sh | 246 +++++++++++++++++++++++++++----------------------- 1 file changed, 132 insertions(+), 114 deletions(-) diff --git a/bashscript.sh b/bashscript.sh index 2d483ce..008de67 100644 --- a/bashscript.sh +++ b/bashscript.sh @@ -1,129 +1,147 @@ #!/usr/bin/env bash -# NOTE: -# This prompt uses Nerd Font (Powerline glyphs). -# Recommended font: JetBrainsMono Nerd Font -# -# If separators like    look broken: -# 1) Run ./install-nerdfont.sh -# 2) Select "JetBrainsMono Nerd Font" in your terminal - - -set -euo pipefail - -# Must be root -if [[ "${EUID}" -ne 0 ]]; then - echo "Kjør som root: sudo bash $0" +# Must be sourced +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + echo "Bruk: source ps1.sh" exit 1 fi -### 1) Ensure required packages installed -need_pkgs=(landscape-common figlet lolcat) -missing=() -for p in "${need_pkgs[@]}"; do - if ! dpkg -s "$p" >/dev/null 2>&1; then - missing+=("$p") - fi -done - -if ((${#missing[@]} > 0)); then - echo "Installerer manglende pakker: ${missing[*]}" - export DEBIAN_FRONTEND=noninteractive - apt-get update -y - apt-get install -y "${missing[@]}" -fi - -### 2) Ask punchline (clear wording, always from TTY) -echo -read -r -p "Skriv ønsket punchline (vises under hostname i banneret): " PUNCHLINE /dev/null || true - -# Remove old managed block (if any) -tmp="$(mktemp)" -awk -v s="$MARKER_START" -v e="$MARKER_END" ' - $0==s {inside=1; next} - $0==e {inside=0; next} - !inside {print} -' "$GLOBAL_BASHRC" > "$tmp" -cat "$tmp" > "$GLOBAL_BASHRC" -rm -f "$tmp" - -# Append fresh managed block (NO expansion while writing) -cat >> "$GLOBAL_BASHRC" <<'EOF' - -# >>> global custom bashrc (managed) >>> -# Only run in interactive shells case "$-" in *i*) ;; - *) return ;; + *) return 0 ;; esac -##### HISTORY / BASICS ##### -HISTCONTROL=ignoreboth -shopt -s histappend -HISTSIZE=999999 -HISTFILESIZE=999999 -shopt -s checkwinsize - -[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" - -##### PROMPT (GLOBAL) ##### -export PS1="\[\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\]╰──🚀 \[\e[0m\]" - -##### COLORS / ALIASES ##### -if [ -x /usr/bin/dircolors ]; then - test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" - alias ls='ls --color=auto' - alias grep='grep --color=auto' - alias fgrep='fgrep --color=auto' - alias egrep='egrep --color=auto' -fi - -alias ll='ls -alF' -alias la='ls -A' -alias l='ls -CF' - -if [ -f ~/.bash_aliases ]; then - . ~/.bash_aliases -fi - -if ! shopt -oq posix; then - if [ -f /usr/share/bash-completion/bash_completion ]; then - . /usr/share/bash-completion/bash_completion - elif [ -f /etc/bash_completion ]; then - . /etc/bash_completion +# ------------------------------------------------- +# Nerd Font detection + fallback controls +# +# Env overrides: +# PS1_FORCE_ASCII=1 -> always use ASCII/Unicode fallback separators +# PS1_FORCE_NF=1 -> always use Nerd Font separators +# ------------------------------------------------- +_ps1_has_nf() { + # Explicit overrides win + if [[ "${PS1_FORCE_ASCII:-0}" == "1" ]]; then + return 1 + fi + if [[ "${PS1_FORCE_NF:-0}" == "1" ]]; then + return 0 fi -fi -##### BANNER ##### -LOLCAT="/usr/games/lolcat" -if [ ! -x "$LOLCAT" ]; then - LOLCAT="$(command -v lolcat 2>/dev/null || true)" -fi -[ -z "$LOLCAT" ] && LOLCAT="cat" + # Heuristic: if fc-list exists and shows a Nerd Font family, assume NF works. + if command -v fc-list >/dev/null 2>&1; then + # Keep it generic: any "Nerd Font" is good enough + if fc-list 2>/dev/null | grep -qi "Nerd Font"; then + return 0 + fi + fi -figlet "$(hostname)" -c | "$LOLCAT" -figlet -f digital "__PUNCHLINE__" -c | "$LOLCAT" -landscape-sysinfo | "$LOLCAT" -# <<< global custom bashrc (managed) <<< + # Otherwise: safe fallback + return 1 +} -EOF +# ------------------------------------------------- +# Time-based emoji (Europe/Oslo) +# ------------------------------------------------- +_ps1_symbol() { + local h m hh mm + hh=$(TZ=Europe/Oslo date +%H); mm=$(TZ=Europe/Oslo date +%M) + h=$((10#$hh)); m=$((10#$mm)) -# Replace placeholder with user punchline (safe) -safe_punchline="$(printf '%s' "$PUNCHLINE" | sed 's/[\/&]/\\&/g')" -sed -i "s/__PUNCHLINE__/${safe_punchline}/g" "$GLOBAL_BASHRC" + if (( h >= 5 && h <= 8 )); then echo "🌅" # tidlig + elif (( h >= 9 && h <= 10 )); then echo "☕" # formiddag + elif (( h == 11 && m < 30 )); then echo "🥪" # lunsj + elif (( (h == 11 && m >= 30) || (h >= 12 && h <= 15) )); then echo "💻" # dag + elif (( h == 16 )); then echo "🍲" # middag + elif (( h >= 17 && h <= 22 )); then echo "🌆" # kveld + else echo "🌙" # natt + fi +} -echo -echo "Ferdig ✅" -echo "Global PS1 + banner er nå aktivt for alle brukere." -echo "Kjør scriptet på nytt for å endre punchline." +# ------------------------------------------------- +# Path shortening (keeps /home/user visible) +# Compatible with bash 3.2+ (no negative array indexes) +# ------------------------------------------------- +_ps1_path() { + local p="$PWD" + local parts=() + IFS='/' read -ra parts <<< "$p" + + # If short, keep full + if ((${#parts[@]} < 6)); then + echo "$p" + return + fi + + # / + first two comps + … + last two comps + local n=${#parts[@]} + local a="${parts[1]}" + local b="${parts[2]}" + local c="${parts[$((n-2))]}" + local d="${parts[$((n-1))]}" + + echo "/${a}/${b}/…/${c}/${d}" +} + +# ------------------------------------------------- +# Dynamic vars updated before each prompt +# ------------------------------------------------- +__PS1_SYM="" +__PS1_PATH="" +__PS1_STATUS=0 +__PS1_USE_NF=0 + +_ps1_update() { + __PS1_STATUS=$? + __PS1_SYM="$(_ps1_symbol)" + __PS1_PATH="$(_ps1_path)" + if _ps1_has_nf; then __PS1_USE_NF=1; else __PS1_USE_NF=0; fi +} + +# ------------------------------------------------- +# Enable / disable +# ------------------------------------------------- +__PS1_PREV_PROMPT_COMMAND="${PROMPT_COMMAND-}" + +ps1_on() { + PROMPT_COMMAND="_ps1_update" + + local RST="\[\e[0m\]" + + # Two-zone palette (as requested) + # Zone 1: gray-blue pastel (date/time/user) + local Z1_BG="\[\e[48;5;61m\]" + local Z1_FG="\[\e[38;5;255m\]" + + # Zone 2: turquoise / cool green (host/path) + local Z2_BG="\[\e[48;5;37m\]" + local Z2_FG="\[\e[38;5;255m\]" + local PATH_FG="\[\e[38;5;194m\]" + + # Frame line + local FRAME="\[\e[38;5;60m\]" + + # Status colors + local OK="\[\e[38;5;76m\]" + local BAD="\[\e[38;5;203m\]" + + # Build separators based on NF availability (evaluated at prompt time via $__PS1_USE_NF) + # We avoid embedding raw variables that bash re-parses weirdly by using $(...) inside PS1 only for + # selecting literal separators (safe), while keeping all color escapes static and balanced. + local SEP_EXPR='\$( [ "$__PS1_USE_NF" -eq 1 ] && printf "" || printf "▶" )' + local LEFT_EXPR='\$( [ "$__PS1_USE_NF" -eq 1 ] && printf "" || printf "[" )' + local RIGHT_EXPR='\$( [ "$__PS1_USE_NF" -eq 1 ] && printf "" || printf "]" )' + + local PROMPT_SYM="\$( [ \$__PS1_STATUS -eq 0 ] && printf '${OK}' || printf '${BAD}' )➜${RST}" + + # Keep exact order: date -> time -> user -> host -> path, then newline, then prompt + # Note: \d, \A, \u, \h are PS1 escapes. + PS1="\ +${FRAME}╭─${RST}\ +${Z1_BG}${Z1_FG}${LEFT_EXPR} \d \A \u ${RST}${Z1_BG}${Z2_BG}${Z2_FG}${SEP_EXPR}${RST}\ +${Z2_BG}${Z2_FG} @\h ${PATH_FG}\${__PS1_PATH} ${RST}${Z2_BG}${Z2_FG}${RIGHT_EXPR}${RST}\ +\n${FRAME}╰── ${RST}${PROMPT_SYM} \${__PS1_SYM} " +} + +ps1_off() { + PROMPT_COMMAND="$__PS1_PREV_PROMPT_COMMAND" +}