Kalina CI in der Shell: Prompt-Modul und Installer #3
No files matched your search
@@ -4,6 +4,27 @@ Format: Datum — was — warum. Die CI beginnt versioniert am 2026-10-23; davor
|
||||
sie verstreut (Marke in `brand/`, Dokument-CSS im Open-WebUI-Skill) und wurde nicht
|
||||
versioniert.
|
||||
|
||||
## 1.3.0 — 2026-11-02
|
||||
|
||||
- **Die CI reicht bis in die Shell.** `shell/prompt.zsh` rendert einen zweizeiligen Prompt
|
||||
(`┌─ kalina ~/kalina-ci · main ✚1 ✎2 · 4.2s` / `└─ ❯`) aus denselben Werten wie
|
||||
`themes/kalina-ci-dark.json`: Tinte `#0B0F14`, Knochenweiß `#F5F5EF`, Markenrot `#C1121F`
|
||||
nur als Grafik, Text-Rot `#E0454F` (4,70:1), Salbei `#7FA88C` nur an Git. Ausgerollt auf
|
||||
kalina, ROG, imac und Kalini 1 (Gast-VM); die Pixelprobe zeigt auf jedem Host `#0B0F14`.
|
||||
- **`shell/install.sh` richtet weitere Maschinen ohne meinen Zugriff ein.** Idempotent, sichert
|
||||
jede Datei nach `.vor-kalina-ci-<stempel>`, erkennt foot, qterminal, xfce4-terminal und xterm
|
||||
und prüft anschließend mit `zsh -n`, `foot --check-config` und `xrdb`-Query.
|
||||
- **Vier Erkenntnisse, die das Ausrollen gekostet hat:** p10k lässt sich nicht umfärben, nur
|
||||
ablösen (der dreizeilige Instant-Prompt hinterlässt beim Auskommentieren ein `fi`, danach
|
||||
startet keine Shell mehr); `${PWD/#$HOME/~}` ersetzt in zsh 5.9 nichts; `COLORTERM` wird per
|
||||
SSH nicht übertragen, remote bleibt es beim 256-Farben-Ersatz; wer die Login-Shell auf zsh
|
||||
umstellt, braucht `no_nomatch` in `~/.zshenv`, sonst brechen `ssh host '…'`-Aufrufe an leeren
|
||||
Globs ab, wo bash weitermachte.
|
||||
- **Terminal-Paletten sind nicht ratbar, sie sind messbar.** qterminal liest sein Schema nur
|
||||
aus `XDG_DATA_DIRS` (nicht aus `~/.local/share/qterminal`), xfce4-terminal ignoriert
|
||||
`terminalrc`, solange `xfconf` `/color-use-theme=true` hält, und foot 1.28 will
|
||||
`[colors-dark]` mit `cursor=<text> <grund>` statt `[colors]` mit `cursor-text`.
|
||||
|
||||
## 1.2.0 — 2026-10-23
|
||||
|
||||
- **Jede Seite wird durchgestempelt, keine eigene Impressumsseite** (Mathias: „Alle
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# Kalina CI in der Shell
|
||||
|
||||
Prompt und Terminal-Palette in derselben Farbwelt wie das VS-Code-Theme
|
||||
(`themes/kalina-ci-dark.json`). Der Prompt ist ein eigenstaendiges zsh-Modul,
|
||||
kein oh-my-zsh und kein powerlevel10k noetig.
|
||||
|
||||
```
|
||||
┌─ kalina ~/kalina-ci · main ✚1 ✎2 · 4.2s
|
||||
└─ ❯
|
||||
```
|
||||
|
||||
| Farbe | Wert | Rolle |
|
||||
|---|---|---|
|
||||
| Tinte | `#0B0F14` | Flaeche |
|
||||
| Knochenweiss | `#F5F5EF` | Text, Pfad |
|
||||
| Markenrot | `#C1121F` | **nur Grafik** (Pfeil, Cursor) — 3,09:1 auf Tinte |
|
||||
| Text-Rot | `#E0454F` | Fehlercode, Akzent — 4,70:1 auf Tinte |
|
||||
| Salbei | `#7FA88C` | **nur** Git „hinzugefuegt" |
|
||||
| Steel | `#3A4250` | Linien |
|
||||
| Muted | `#8A94A2` | Hostname |
|
||||
|
||||
## Installation auf einer neuen Maschine
|
||||
|
||||
```sh
|
||||
git clone http://192.168.188.161:3000/mm/kalina-ci.git
|
||||
cd kalina-ci/shell
|
||||
./install.sh --dry-run # zeigen, was passieren wuerde
|
||||
./install.sh # ausfuehren
|
||||
```
|
||||
|
||||
Das Skript ist idempotent, sichert jede Datei nach `.vor-kalina-ci-<stempel>`
|
||||
und laesst sich in Teilen fahren:
|
||||
|
||||
| Schalter | Wirkung |
|
||||
|---|---|
|
||||
| `--dry-run` | nichts schreiben, nur anzeigen |
|
||||
| `--shell-only` | nur zsh + Prompt |
|
||||
| `--terminal-only` | nur Terminal-Palette |
|
||||
| `--no-chsh` | Login-Shell nicht umstellen |
|
||||
|
||||
Erkannt und eingerichtet werden: **foot** (`~/.config/foot/foot.ini`,
|
||||
`[colors-dark]`), **qterminal** (`~/.local/share/qterminal-ci/…/KalinaCI.colorscheme`
|
||||
plus `~/.config/qterminal.org/qterminal.ini` und ein `environment.d`-Eintrag,
|
||||
weil qtermwidget6 nur `XDG_DATA_DIRS` durchsucht), **xfce4-terminal**
|
||||
(`~/.config/xfce4/terminal/terminalrc` **und** `xfconf-query`, sonst gewinnt
|
||||
das GTK-Theme) sowie **xterm** (`~/.Xresources`, aktiv nach `xrdb -merge`).
|
||||
|
||||
## Schalter im Prompt
|
||||
|
||||
| Variable | Wirkung |
|
||||
|---|---|
|
||||
| `KALINA_CI_PROMPT=0` | Prompt abschalten (Modul wird nicht geladen) |
|
||||
| `KALINA_CI_NO_NEWLINE=1` | keine Leerzeile vor dem Prompt |
|
||||
| `KALINA_CI_TRUECOLOR=0\|1` | Farbmodus erzwingen (sonst Automatik) |
|
||||
|
||||
## Fallen, die beim Ausrollen aufgefallen sind
|
||||
|
||||
- **Truecolor kommt per SSH nicht an.** `COLORTERM` wird nicht uebertragen, remote
|
||||
greift der 256-Farben-Ersatz (231/145/60/161 statt exakt). Das ist gewollt.
|
||||
- **Der erste Prompt darf kein `✗1` zeigen.** `precmd` liest `$?` aus dem Ende der
|
||||
`.zshrc`; das Modul setzt den ersten echten Prompt deshalb auf 0.
|
||||
- **p10k wird abgeloest, nicht umgef aerbt.** Wer `~/.p10k.zsh` behaelt, muss
|
||||
`ZSH_THEME=""` setzen und die Instant-Prompt-Zeilen samt `fi` auskommentieren —
|
||||
sonst startet jede Shell mit `parse error near 'fi'`.
|
||||
- **Login-Shell-Wechsel:** nicht-interaktive zsh-Aufrufe (`ssh host '…'`) brechen bei
|
||||
leerem Glob ab, bash nicht. Das Modul setzt deshalb `no_nomatch` in `~/.zshenv`.
|
||||
Executable
+447
@@ -0,0 +1,447 @@
|
||||
#!/usr/bin/env bash
|
||||
# Kalina CI — Shell-Prompt und Terminal-Palette installieren.
|
||||
#
|
||||
# Einmal auf einer neuen Maschine ausfuehren, danach ist die Shell im Kalina-CI
|
||||
# (Tinte #0B0F14, Knochenweiss #F5F5EF, Markenrot #C1121F als Grafik-Akzent).
|
||||
#
|
||||
# ./install.sh # alles, was erkannt wird
|
||||
# ./install.sh --dry-run # nur zeigen, was passieren wuerde
|
||||
# ./install.sh --shell-only # nur zsh + Prompt
|
||||
# ./install.sh --terminal-only # nur Terminal-Palette
|
||||
# ./install.sh --no-chsh # Login-Shell nicht anfassen
|
||||
#
|
||||
# Grundsaetze: jede Datei wird vorher gesichert (.vor-kalina-ci-<stempel>),
|
||||
# jeder Block ist an einem Marker erkennbar und wird nicht doppelt geschrieben,
|
||||
# jede veraenderte Datei wird anschliessend mit dem passenden Pruefer getestet.
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
MARK_ON="# >>> kalina-ci >>>"
|
||||
MARK_OFF="# <<< kalina-ci <<<"
|
||||
TS="$(date +%Y%m%d-%H%M%S)"
|
||||
CONF_DIR="$HOME/.config/kalina-ci"
|
||||
PROMPT="$CONF_DIR/prompt.zsh"
|
||||
SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
DRY=0; DO_SHELL=1; DO_TERM=1; DO_CHSH=1
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--dry-run) DRY=1 ;;
|
||||
--shell-only) DO_TERM=0 ;;
|
||||
--terminal-only) DO_SHELL=0 ;;
|
||||
--no-chsh) DO_CHSH=0 ;;
|
||||
-h|--help) sed -n '2,18p' "$0"; exit 0 ;;
|
||||
*) echo "unbekannte Option: $arg" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
say() { printf '%s\n' "$*"; }
|
||||
step() { printf '\n\033[38;2;224;69;79m▸\033[0m %s\n' "$*"; }
|
||||
ok() { printf ' \033[38;2;127;168;140m✓\033[0m %s\n' "$*"; }
|
||||
warn() { printf ' \033[38;2;199;164;107m!\033[0m %s\n' "$*"; }
|
||||
run() { if [ "$DRY" = 1 ]; then printf ' [dry] %s\n' "$*"; else "$@"; fi }
|
||||
|
||||
backup() {
|
||||
[ -e "$1" ] || return 0
|
||||
local dst="$1.vor-kalina-ci-$TS"
|
||||
run cp -a "$1" "$dst"
|
||||
ok "Sicherung: $dst"
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------- Hilfsmittel
|
||||
SUDO=""
|
||||
if [ "$(id -u)" = 0 ]; then SUDO=""
|
||||
elif command -v sudo >/dev/null && sudo -n true 2>/dev/null; then SUDO="sudo -n"
|
||||
fi
|
||||
|
||||
install_zsh() {
|
||||
command -v zsh >/dev/null && { ok "zsh vorhanden: $(zsh --version)"; return 0; }
|
||||
local pm=""
|
||||
for c in apt-get dnf pacman zypper apk; do command -v "$c" >/dev/null && pm="$c" && break; done
|
||||
[ -n "$pm" ] || { warn "kein bekannter Paketmanager — zsh bitte von Hand installieren"; return 1; }
|
||||
if [ -z "$SUDO" ] && [ "$(id -u)" != 0 ]; then
|
||||
warn "zsh fehlt und sudo verlangt ein Passwort. Bitte selbst ausfuehren:"
|
||||
case "$pm" in
|
||||
apt-get) say " sudo apt-get install -y zsh" ;;
|
||||
dnf) say " sudo dnf install -y zsh" ;;
|
||||
pacman) say " sudo pacman -S --needed zsh" ;;
|
||||
zypper) say " sudo zypper install -y zsh" ;;
|
||||
apk) say " sudo apk add zsh" ;;
|
||||
esac
|
||||
return 1
|
||||
fi
|
||||
case "$pm" in
|
||||
apt-get) run $SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y zsh ;;
|
||||
dnf) run $SUDO dnf install -y zsh ;;
|
||||
pacman) run $SUDO pacman -S --needed --noconfirm zsh ;;
|
||||
zypper) run $SUDO zypper --non-interactive install zsh ;;
|
||||
apk) run $SUDO apk add zsh ;;
|
||||
esac
|
||||
command -v zsh >/dev/null && ok "zsh installiert: $(zsh --version)" || warn "zsh weiterhin nicht auffindbar"
|
||||
}
|
||||
|
||||
# Block mit Markern an eine Datei anhaengen (nicht doppelt)
|
||||
append_block() {
|
||||
local file="$1"
|
||||
if [ -f "$file" ] && grep -qF "$MARK_ON" "$file"; then
|
||||
ok "$(basename "$file"): Kalina-CI-Block ist schon drin"
|
||||
return 0
|
||||
fi
|
||||
backup "$file"
|
||||
if [ "$DRY" = 1 ]; then
|
||||
printf ' [dry] Block an %s anhaengen\n' "$file"
|
||||
else
|
||||
{ printf '\n%s\n' "$MARK_ON"; cat; printf '%s\n' "$MARK_OFF"; } >> "$file"
|
||||
fi
|
||||
ok "$(basename "$file"): Block angehaengt"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ Shell
|
||||
do_shell() {
|
||||
step "Shell (zsh + Kalina-CI-Prompt)"
|
||||
install_zsh || true
|
||||
|
||||
run mkdir -p "$CONF_DIR"
|
||||
if [ -f "$PROMPT" ] && [ -f "$SRC_DIR/prompt.zsh" ]; then
|
||||
backup "$PROMPT"
|
||||
run cp -f "$SRC_DIR/prompt.zsh" "$PROMPT"
|
||||
ok "prompt.zsh aus $SRC_DIR uebernommen"
|
||||
elif [ -f "$SRC_DIR/prompt.zsh" ]; then
|
||||
run cp -f "$SRC_DIR/prompt.zsh" "$PROMPT"
|
||||
ok "prompt.zsh installiert"
|
||||
elif [ -f "$PROMPT" ]; then
|
||||
ok "prompt.zsh liegt bereits in $CONF_DIR"
|
||||
else
|
||||
warn "prompt.zsh weder neben dem Skript noch in $CONF_DIR — Shell-Teil uebersprungen"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local zshrc="$HOME/.zshrc"
|
||||
if [ ! -f "$zshrc" ]; then
|
||||
backup "$zshrc"
|
||||
if [ "$DRY" = 0 ]; then
|
||||
cat > "$zshrc" <<'RC'
|
||||
# Grundgeruest (angelegt von install.sh aus mm/kalina-ci)
|
||||
HISTFILE=~/.zsh_history
|
||||
HISTSIZE=20000
|
||||
SAVEHIST=20000
|
||||
setopt append_history share_history hist_ignore_dups hist_ignore_space extended_history
|
||||
setopt autocd interactive_comments
|
||||
unsetopt beep
|
||||
autoload -Uz compinit && compinit -u -d "$HOME/.zcompdump"
|
||||
zstyle ':completion:*' menu select
|
||||
bindkey -e
|
||||
RC
|
||||
fi
|
||||
ok "~/.zshrc angelegt"
|
||||
fi
|
||||
|
||||
printf '\n[[ -r ~/.config/kalina-ci/prompt.zsh ]] && source ~/.config/kalina-ci/prompt.zsh\n' \
|
||||
| append_block "$zshrc"
|
||||
|
||||
# Nicht-interaktive Aufrufe (ssh host '...') erwarten bash-Verhalten
|
||||
local zshenv="$HOME/.zshenv"
|
||||
if ! grep -qs "kalina-ci" "$zshenv"; then
|
||||
backup "$zshenv"
|
||||
if [ "$DRY" = 0 ]; then
|
||||
{
|
||||
printf '%s\n' "$MARK_ON"
|
||||
printf '# Leerer Glob soll nicht abbrechen (bash-Verhalten fuer Automatik/Remote).\n'
|
||||
printf 'if ! [[ -o interactive ]]; then setopt no_nomatch 2>/dev/null; fi\n'
|
||||
printf '%s\n' "$MARK_OFF"
|
||||
} >> "$zshenv"
|
||||
fi
|
||||
ok "~/.zshenv: no_nomatch fuer nicht-interaktive Shells"
|
||||
else
|
||||
ok "~/.zshenv: schon eingerichtet"
|
||||
fi
|
||||
|
||||
if [ "$DRY" = 0 ]; then
|
||||
zsh -n "$zshrc" && ok "zsh -n ~/.zshrc" || warn "~/.zshrc hat einen Syntaxfehler"
|
||||
zsh -n "$PROMPT" && ok "zsh -n prompt.zsh" || warn "prompt.zsh hat einen Syntaxfehler"
|
||||
fi
|
||||
|
||||
# Login-Shell
|
||||
local cur; cur="$(getent passwd "$(id -un)" | cut -d: -f7)"
|
||||
if [ "$cur" = "$(command -v zsh 2>/dev/null)" ]; then
|
||||
ok "Login-Shell ist bereits zsh"
|
||||
elif [ "$DO_CHSH" = 0 ]; then
|
||||
warn "Login-Shell bleibt $cur (--no-chsh); Start mit 'exec zsh' oder 'chsh -s $(command -v zsh)'"
|
||||
else
|
||||
run $SUDO chsh -s "$(command -v zsh)" "$(id -un)" && ok "Login-Shell auf zsh gestellt (greift beim naechsten Login)"
|
||||
fi
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------- Terminal
|
||||
do_terminal() {
|
||||
step "Terminal-Palette"
|
||||
|
||||
local chosen=""
|
||||
if command -v foot >/dev/null; then
|
||||
chosen=foot; foot_setup
|
||||
elif command -v qterminal >/dev/null; then
|
||||
chosen=qterminal; qterminal_setup
|
||||
elif command -v xfce4-terminal >/dev/null; then
|
||||
chosen=xfce4-terminal; xfce_setup
|
||||
fi
|
||||
|
||||
# xterm-Ressourcen zusaetzlich, wenn xterm daneben installiert ist.
|
||||
if command -v xterm >/dev/null && [ "$chosen" != xterm ]; then
|
||||
chosen="${chosen:-xterm}"; xterm_setup
|
||||
fi
|
||||
|
||||
[ -n "$chosen" ] || warn "kein bekanntes Terminal gefunden (foot, qterminal, xfce4-terminal, xterm)"
|
||||
}
|
||||
|
||||
foot_setup() {
|
||||
local cfg="$HOME/.config/foot"
|
||||
run mkdir -p "$cfg"
|
||||
if [ -f "$cfg/foot.ini" ] && grep -qF "Kalina CI" "$cfg/foot.ini"; then
|
||||
ok "foot: CI-Palette ist schon drin"
|
||||
else
|
||||
backup "$cfg/foot.ini"
|
||||
if [ "$DRY" = 0 ]; then
|
||||
cat >> "$cfg/foot.ini" <<'FOOT'
|
||||
|
||||
# --- Kalina CI -------------------------------------------------------------
|
||||
# Absichtlich NACH einem eventuellen include: in foot gewinnt die spaetere
|
||||
# Angabe, damit die CI-Palette jedes Theme-Update ueberlebt.
|
||||
[colors-dark]
|
||||
background=0b0f14
|
||||
foreground=f5f5ef
|
||||
regular0=1a212a
|
||||
regular1=e0454f
|
||||
regular2=7fa88c
|
||||
regular3=c7a46b
|
||||
regular4=7e93ad
|
||||
regular5=be8fa0
|
||||
regular6=8fb3b3
|
||||
regular7=f5f5ef
|
||||
bright0=5c6675
|
||||
bright1=ff6b75
|
||||
bright2=9cc2a8
|
||||
bright3=e0c08a
|
||||
bright4=a3b6cb
|
||||
bright5=d3a8b8
|
||||
bright6=aecbcb
|
||||
bright7=ffffff
|
||||
selection-foreground=0b0f14
|
||||
selection-background=f5f5ef
|
||||
cursor=0b0f14 c1121f
|
||||
# --- Ende Kalina CI --------------------------------------------------------
|
||||
FOOT
|
||||
fi
|
||||
ok "foot: [colors-dark] angehaengt"
|
||||
fi
|
||||
if command -v foot >/dev/null && [ "$DRY" = 0 ]; then
|
||||
foot --check-config 2>&1 | grep -v "UTF-8 locale" | grep . && warn "foot meldet Konfigurationsfehler (siehe oben)" \
|
||||
|| ok "foot --check-config: keine Fehler"
|
||||
fi
|
||||
}
|
||||
|
||||
qterminal_setup() {
|
||||
local share="$HOME/.local/share/qterminal-ci/qtermwidget6/color-schemes"
|
||||
local ini="$HOME/.config/qterminal.org/qterminal.ini"
|
||||
run mkdir -p "$share" "$(dirname "$ini")"
|
||||
if [ "$DRY" = 0 ]; then
|
||||
cat > "$share/KalinaCI.colorscheme" <<'SCHEME'
|
||||
[Color0]
|
||||
Color=26,33,42
|
||||
[Color0Intense]
|
||||
Color=92,102,117
|
||||
[Color0Faint]
|
||||
Color=20,26,34
|
||||
[Color1]
|
||||
Color=224,69,79
|
||||
[Color1Intense]
|
||||
Color=255,107,117
|
||||
[Color1Faint]
|
||||
Color=146,50,57
|
||||
[Color2]
|
||||
Color=127,168,140
|
||||
[Color2Intense]
|
||||
Color=156,194,168
|
||||
[Color2Faint]
|
||||
Color=84,110,91
|
||||
[Color3]
|
||||
Color=199,164,107
|
||||
[Color3Intense]
|
||||
Color=224,192,138
|
||||
[Color3Faint]
|
||||
Color=128,107,74
|
||||
[Color4]
|
||||
Color=126,147,173
|
||||
[Color4Intense]
|
||||
Color=163,182,203
|
||||
[Color4Faint]
|
||||
Color=85,97,113
|
||||
[Color5]
|
||||
Color=190,143,160
|
||||
[Color5Intense]
|
||||
Color=211,168,184
|
||||
[Color5Faint]
|
||||
Color=122,95,105
|
||||
[Color6]
|
||||
Color=143,179,179
|
||||
[Color6Intense]
|
||||
Color=174,203,203
|
||||
[Color6Faint]
|
||||
Color=94,116,116
|
||||
[Color7]
|
||||
Color=245,245,239
|
||||
[Color7Intense]
|
||||
Color=255,255,255
|
||||
[Color7Faint]
|
||||
Color=155,155,152
|
||||
[Background]
|
||||
Color=11,15,20
|
||||
[BackgroundIntense]
|
||||
Color=26,33,42
|
||||
[BackgroundFaint]
|
||||
Color=11,15,20
|
||||
[Foreground]
|
||||
Color=245,245,239
|
||||
[ForegroundIntense]
|
||||
Color=255,255,255
|
||||
[ForegroundFaint]
|
||||
Color=138,148,162
|
||||
[General]
|
||||
Description=Kalina CI
|
||||
Opacity=1
|
||||
SCHEME
|
||||
ok "qterminal: Farbschema geschrieben"
|
||||
fi
|
||||
|
||||
backup "$ini"
|
||||
if [ "$DRY" = 0 ]; then
|
||||
mkdir -p "$(dirname "$ini")"; touch "$ini"
|
||||
if ! grep -q '^\[General\]' "$ini"; then printf '[General]\n' | cat - "$ini" > "$ini.neu" && mv "$ini.neu" "$ini"; fi
|
||||
set_ini() { # set_ini <schluessel> <wert>
|
||||
if grep -qE "^$1=" "$ini"; then
|
||||
sed -i "s|^$1=.*|$1=$2|" "$ini"
|
||||
else
|
||||
sed -i "/^\[General\]/a $1=$2" "$ini"
|
||||
fi
|
||||
}
|
||||
set_ini colorScheme KalinaCI
|
||||
set_ini fontFamily "DejaVu Sans Mono"
|
||||
set_ini fontSize 11
|
||||
set_ini TerminalTransparency 0
|
||||
fi
|
||||
ok "qterminal: colorScheme/font/TerminalTransparency gesetzt"
|
||||
|
||||
# qtermwidget6 durchsucht XDG_DATA_DIRS — eigenen Pfad dort einhaengen
|
||||
local envd="$HOME/.config/environment.d"
|
||||
run mkdir -p "$envd"
|
||||
if [ "$DRY" = 0 ]; then
|
||||
cat > "$envd/60-kalina-ci-terminal.conf" <<'ENVD'
|
||||
# Kalina CI: Farbschema fuer QTerminal/QTermWidget (ohne sudo)
|
||||
XDG_DATA_DIRS=${HOME}/.local/share/qterminal-ci:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}
|
||||
ENVD
|
||||
fi
|
||||
ok "environment.d/60-kalina-ci-terminal.conf (greift nach dem naechsten Login)"
|
||||
}
|
||||
|
||||
xfce_setup() {
|
||||
local dir="$HOME/.config/xfce4/terminal" rc
|
||||
rc="$dir/terminalrc"
|
||||
run mkdir -p "$dir"
|
||||
backup "$rc"
|
||||
if [ "$DRY" = 0 ]; then
|
||||
cat > "$rc" <<'XFCE'
|
||||
[Configuration]
|
||||
FontName=DejaVu Sans Mono 11
|
||||
MiscAlwaysShowTabs=FALSE
|
||||
MiscBell=FALSE
|
||||
MiscCursorBlinks=FALSE
|
||||
MiscCursorShape=TERMINAL_CURSOR_SHAPE_BLOCK
|
||||
MiscShowUnsafePasteDialog=FALSE
|
||||
ColorForeground=#f5f5ef
|
||||
ColorBackground=#0b0f14
|
||||
ColorCursor=#c1121f
|
||||
ColorCursorUseDefault=FALSE
|
||||
ColorPalette=#1a212a;#e0454f;#7fa88c;#c7a46b;#7e93ad;#be8fa0;#8fb3b3;#f5f5ef;#5c6675;#ff6b75;#9cc2a8;#e0c08a;#a3b6cb;#d3a8b8;#aecbcb;#ffffff
|
||||
ColorUseTheme=false
|
||||
BoldIsBright=TRUE
|
||||
BackgroundMode=TERMINAL_BACKGROUND_SOLID
|
||||
XFCE
|
||||
fi
|
||||
ok "xfce4-terminal: terminalrc geschrieben"
|
||||
|
||||
if command -v xfconf-query >/dev/null; then
|
||||
local have=0
|
||||
command -v xfconf-query >/dev/null && xfconf-query -c xfce4-terminal -l >/dev/null 2>&1 && have=1
|
||||
if [ "$have" = 1 ]; then
|
||||
xfset() { # xfset <eigenschaft> <typ> <wert>
|
||||
if xfconf-query -c xfce4-terminal -p "$1" >/dev/null 2>&1; then
|
||||
run xfconf-query -c xfce4-terminal -p "$1" -t "$2" -s "$3" >/dev/null
|
||||
else
|
||||
run xfconf-query -c xfce4-terminal -p "$1" -n -t "$2" -s "$3" >/dev/null
|
||||
fi
|
||||
}
|
||||
xfset /color-background string "#0b0f14"
|
||||
xfset /color-foreground string "#f5f5ef"
|
||||
xfset /color-cursor string "#c1121f"
|
||||
xfset /color-cursor-use-default bool false
|
||||
xfset /color-use-theme bool false
|
||||
xfset /font-name string "DejaVu Sans Mono 11"
|
||||
xfset /color-palette string "#1a212a;#e0454f;#7fa88c;#c7a46b;#7e93ad;#be8fa0;#8fb3b3;#f5f5ef;#5c6675;#ff6b75;#9cc2a8;#e0c08a;#a3b6cb;#d3a8b8;#aecbcb;#ffffff"
|
||||
ok "xfce4-terminal: laufende Sitzung (xfconf) gesetzt — wichtig, sonst gewinnt das GTK-Theme"
|
||||
else
|
||||
warn "xfconf-query ohne Verbindung zur Sitzung (per SSH normal); terminalrc greift beim naechsten Login"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
xterm_setup() {
|
||||
local xr="$HOME/.Xresources"
|
||||
if [ -f "$xr" ] && grep -qF "Kalina CI" "$xr"; then
|
||||
ok "~/.Xresources: xterm-Block ist schon drin"
|
||||
return 0
|
||||
fi
|
||||
backup "$xr"
|
||||
if [ "$DRY" = 0 ]; then
|
||||
cat >> "$xr" <<'XRES'
|
||||
|
||||
! --- Kalina CI (xterm) -----------------------------------------------------
|
||||
xterm*background: #0B0F14
|
||||
xterm*foreground: #F5F5EF
|
||||
xterm*cursorColor: #C1121F
|
||||
xterm*pointerColor: #C1121F
|
||||
xterm*colorBD: #F5F5EF
|
||||
xterm*colorUL: #C1121F
|
||||
xterm*faceName: DejaVu Sans Mono
|
||||
xterm*faceSize: 11
|
||||
xterm*color0: #1A212A
|
||||
xterm*color1: #E0454F
|
||||
xterm*color2: #7FA88C
|
||||
xterm*color3: #C7A46B
|
||||
xterm*color4: #7E93AD
|
||||
xterm*color5: #BE8FA0
|
||||
xterm*color6: #8FB3B3
|
||||
xterm*color7: #F5F5EF
|
||||
xterm*color8: #5C6675
|
||||
xterm*color9: #FF6B75
|
||||
xterm*color10: #9CC2A8
|
||||
xterm*color11: #E0C08A
|
||||
xterm*color12: #A3B6CB
|
||||
xterm*color13: #D3A8B8
|
||||
xterm*color14: #AECBCB
|
||||
xterm*color15: #FFFFFF
|
||||
! --- Ende Kalina CI -------------------------------------------------------
|
||||
XRES
|
||||
fi
|
||||
ok "~/.Xresources: xterm-Farben ergaenzt (aktiv nach 'xrdb -merge ~/.Xresources')"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------- Ablauf
|
||||
say "Kalina CI — Installation auf $(hostname), Ziel $HOME"
|
||||
[ "$DRY" = 1 ] && say "(Probelauf: es wird nichts geschrieben)"
|
||||
|
||||
[ "$DO_SHELL" = 1 ] && do_shell
|
||||
[ "$DO_TERM" = 1 ] && do_terminal
|
||||
|
||||
step "Fertig"
|
||||
say " Prompt pruefen: zsh -i (oder neue Terminal-Sitzung)"
|
||||
say " Abschalten: KALINA_CI_PROMPT=0 zsh -i"
|
||||
say " Palette pruefen: Terminal neu starten; nach environment.d-Aenderung einmal neu anmelden"
|
||||
@@ -0,0 +1,176 @@
|
||||
# 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
|
||||
Reference in new issue
Block a user