Files
Kalina 6882349bf4 feat(shell): Kalina-CI-Prompt und Installer fuer weitere Maschinen (#2)
prompt.zsh: zweizeiliger zsh-Prompt aus den CI-Token (Tinte, Knochenweiss, Markenrot nur als Grafik, Text-Rot fuer Fehlercodes, Salbei nur an Git). install.sh: idempotent, sichert jede Datei, erkennt foot/qterminal/xfce4-terminal/xterm und prueft mit zsh -n, foot --check-config und xrdb.
2026-11-02 18:29:25 +01:00

177 lines
6.2 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kalina CI – zsh-Prompt
# ---------------------------------------------------------------------------
# Zweizeiliger Prompt in der Farbwelt von "Kalina CI Dark" (VS Code).
# Farbwerte: /home/mm/kalina-ci/tokens.json + Theme-Datei
# /home/mm/vscode/kalina-ci-theme/themes/kalina-ci-dark.json
# (terminal.ansi* = dieselben Rollen wie dort)
#
# ┌─ kalina ~/Projekte/kalina-ci main ✚1 ✎2 ·(venv) · 4.2s
# └─ ❯
#
# Abschalten: KALINA_CI_PROMPT=0 (vor dem source setzen)
# Truecolor: automatisch bei COLORTERM=truecolor/24bit; erzwingen mit
# KALINA_CI_TRUECOLOR=1, abschalten mit =0
# Kein Zeilenumbruch vor dem Prompt: KALINA_CI_NO_NEWLINE=1
[[ ${KALINA_CI_PROMPT:-1} == 0 ]] && return 0
zmodload zsh/datetime 2>/dev/null
autoload -Uz add-zsh-hook 2>/dev/null || true
typeset -g _KCI_TRUECOLOR=0
typeset -g _KCI_START=0 _KCI_DUR=0 _KCI_CODE=0 _KCI_FIRST=1
typeset -g _KCI_GIT=''
case ${COLORTERM:-} in
truecolor|24bit) _KCI_TRUECOLOR=1 ;;
esac
[[ ${TERM:-} == *-direct ]] && _KCI_TRUECOLOR=1
[[ -n ${KALINA_CI_TRUECOLOR:-} ]] && _KCI_TRUECOLOR=${KALINA_CI_TRUECOLOR}
# Hex -> Vordergrund-Sequenz, in %{ %} gewickelt (zsh rechnet sie sonst als Breite)
_kci_fg() {
local s=${1#\#}
local -i r=$(( 16#${s:0:2} )) g=$(( 16#${s:2:2} )) b=$(( 16#${s:4:2} ))
if (( _KCI_TRUECOLOR )); then
print -rn -- $'%{\e[38;2;'"${r};${g};${b}"$'m%}'
else
local -i ri=$(( (r * 5 + 127) / 255 )) gi=$(( (g * 5 + 127) / 255 )) bi=$(( (b * 5 + 127) / 255 ))
print -rn -- $'%{\e[38;5;'"$(( 16 + 36 * ri + 6 * gi + bi ))"$'m%}'
fi
}
# --- Palette (Rollen wie im Theme) -----------------------------------------
typeset -g _KCI_BONE=$(_kci_fg '#F5F5EF') # Text
typeset -g _KCI_ROT=$(_kci_fg '#C1121F') # Akzent/Grafik: Pfeil, i-Punkt
typeset -g _KCI_ROT_TXT=$(_kci_fg '#E0454F') # Text-Akzent (4,7:1 auf Tinte)
typeset -g _KCI_STEEL=$(_kci_fg '#3A4250') # Linien
typeset -g _KCI_STEEL_L=$(_kci_fg '#5C6675') # Sekundär-Meta
typeset -g _KCI_MUTED=$(_kci_fg '#8A94A2') # Host, Kommentar
typeset -g _KCI_BLUE=$(_kci_fg '#A3B6CB') # Branch
typeset -g _KCI_GREEN=$(_kci_fg '#7FA88C') # nur Git "hinzugefügt"
typeset -g _KCI_YELLOW=$(_kci_fg '#C7A46B') # nur Git "geändert" / venv
typeset -g _KCI_BRIGHTROT=$(_kci_fg '#FF6B75') # root
typeset -g _KCI_RESET=$'%{\e[0m%}'
typeset -g _KCI_BOLD=$'%{\e[1m%}'
# --- Git-Zustand einsammeln (ein Aufruf, keine Locks) ----------------------
_kci_git_info() {
reply=()
local out
out=$(command git --no-optional-locks -C "${PWD}" status --porcelain=v1 -b 2>/dev/null) || return 1
[[ -z $out ]] && return 1
local line=${out%%$'\n'*}
local br=${line#\#\# }
br=${br%%...*}
br=${br%% *}
local -i ahead=0 behind=0
[[ $line == *'[ahead '* ]] && ahead=${${line#*\[ahead }%%[,\]]*}
[[ $line == *'behind '* ]] && behind=${${line#*behind }%%[,\]]*}
local -i staged=0 mod=0 untracked=0
local l
for l in ${(f)out}; do
[[ $l == \#\#* ]] && continue
case $l in
'??'*) (( untracked++ )) ;;
[MTARCD]*) (( staged++ )); [[ ${l:1:1} != ' ' ]] && (( mod++ )) ;;
' '*) (( mod++ )) ;;
esac
done
(( ${#br} > 26 )) && br="${br:0:24}…"
reply=("$br" $staged $mod $untracked $ahead $behind)
}
_kci_preexec() { _KCI_START=$EPOCHREALTIME }
_kci_precmd() {
_KCI_CODE=$?
# allererster Prompt: $? stammt aus .zshrc, nicht aus einer Nutzereingabe
if (( _KCI_FIRST )); then _KCI_CODE=0; _KCI_FIRST=0; fi
if (( _KCI_START > 0 )); then
local -F 3 d=$(( EPOCHREALTIME - _KCI_START ))
_KCI_DUR=${d}
_KCI_START=0
else
_KCI_DUR=0
fi
[[ ${_KCI_DUR%.*} -lt 2 ]] && _KCI_DUR=0
local host=${(%):-%m}
local -i root=0
(( EUID == 0 )) && root=1
# Pfad: ~ für $HOME, tiefe Pfade auf die letzten drei Ebenen kürzen
local p
if [[ $PWD == $HOME ]]; then
p='~'
elif [[ $PWD == $HOME/* ]]; then
p="~${PWD#$HOME}"
else
p=$PWD
fi
if [[ $p != '~' && $p != '/' ]]; then
local -a parts=(${(s:/:)p})
(( ${#parts} > 4 )) && p="…/${(j:/:)parts[-3,-1]}"
fi
# Git
local gitseg=''
if _kci_git_info; then
local br=$reply[1]
gitseg=" ${_KCI_STEEL}·${_KCI_RESET} ${_KCI_BLUE}${br}${_KCI_RESET}"
(( reply[2] )) && gitseg+=" ${_KCI_GREEN}✚${reply[2]}${_KCI_RESET}"
(( reply[3] )) && gitseg+=" ${_KCI_YELLOW}✎${reply[3]}${_KCI_RESET}"
(( reply[4] )) && gitseg+=" ${_KCI_STEEL_L}?${reply[4]}${_KCI_RESET}"
(( reply[5] )) && gitseg+=" ${_KCI_GREEN}↑${reply[5]}${_KCI_RESET}"
(( reply[6] )) && gitseg+=" ${_KCI_YELLOW}↓${reply[6]}${_KCI_RESET}"
fi
# Umgebung
local envseg=''
[[ -n ${VIRTUAL_ENV:-} ]] && envseg+=" ${_KCI_STEEL}·${_KCI_RESET} ${_KCI_YELLOW}${VIRTUAL_ENV:t}${_KCI_RESET}"
[[ -n ${CONDA_DEFAULT_ENV:-} && -z ${VIRTUAL_ENV:-} ]] && envseg+=" ${_KCI_STEEL}·${_KCI_RESET} ${_KCI_YELLOW}${CONDA_DEFAULT_ENV}${_KCI_RESET}"
[[ -n ${KALINA_SSH_HOST:-} ]] && envseg+=" ${_KCI_STEEL}·${_KCI_RESET} ${_KCI_MUTED}ssh:${KALINA_SSH_HOST}${_KCI_RESET}"
local durseg=''
(( _KCI_DUR )) && durseg=" ${_KCI_STEEL}·${_KCI_RESET} ${_KCI_STEEL_L}$(printf '%.1fs' ${_KCI_DUR})${_KCI_RESET}"
local prefix=''
[[ ${KALINA_CI_NO_NEWLINE:-0} == 1 ]] || prefix=$'\n'
local hostsym=${_KCI_MUTED}
local marksym='❯'
local marksym_c=${_KCI_ROT}
if (( root )); then
hostsym=${_KCI_BRIGHTROT}
marksym='#'
marksym_c=${_KCI_BRIGHTROT}
fi
local codeseg=''
(( _KCI_CODE )) && codeseg="${_KCI_ROT_TXT}✗${_KCI_CODE}${_KCI_RESET} "
PROMPT="${prefix}${_KCI_STEEL}┌─${_KCI_RESET} ${hostsym}${host}${_KCI_RESET} ${_KCI_BONE}${p}${_KCI_RESET}${gitseg}${envseg}${durseg}"$'\n'
PROMPT+="${_KCI_STEEL}└─${_KCI_RESET} ${codeseg}${marksym_c}${marksym}${_KCI_RESET} "
RPROMPT=''
local -i j=${#jobstates}
(( j )) && RPROMPT="${_KCI_STEEL_L}⚙${j}${_KCI_RESET}"
}
if (( ${+functions[add-zsh-hook]} )); then
add-zsh-hook precmd _kci_precmd
add-zsh-hook preexec _kci_preexec
else
precmd_functions+=(_kci_precmd)
preexec_functions+=(_kci_preexec)
fi
# Initialer Prompt sofort beim Start (precmd feuert erst vor dem ersten Prompt)
if [[ -o interactive ]]; then
true
_kci_precmd
# doch noch kein Nutzerbefehl gelaufen: erster echter Prompt zeigt keinen Fehlercode
_KCI_FIRST=1
_KCI_CODE=0
fi