shell-prompt.zsh
· 9.6 KiB · Bash
Brut
# shell-prompt.zsh
# Powerline-style prompt untuk Zsh di macOS Tahoe.
# Diadaptasi dari konfigurasi synth-shell Bash.
[[ -o interactive ]] || return
# -----------------------------------------------------------------------------
# Konfigurasi tampilan
# -----------------------------------------------------------------------------
SSP_FORMAT=(USER HOST PWD GIT PYENV TF KUBE DATE CLOCK)
SSP_SEPARATOR_CHAR=$'\uE0B0'
SSP_SEGMENT_PADDING=' '
SSP_MAX_PWD_CHAR=25
SSP_GIT_SYNCED=''
SSP_GIT_AHEAD=' ▲'
SSP_GIT_BEHIND=' ▼'
SSP_GIT_DIVERGED=' ◆'
SSP_GIT_DIRTY=' ◔'
SSP_GIT_DIRTY_AHEAD=' ◔ △'
SSP_GIT_DIRTY_BEHIND=' ◔ ▽'
SSP_GIT_DIRTY_DIVERGED=' ◔ ◇'
SSP_GIT_STASH='🗎'
SSP_GIT_UPDATE_PERIOD_MINUTES=15
# color-name -> ANSI foreground/background base codes.
_ssp_8bit_code() {
case "$1" in
default|none) echo 9 ;;
black) echo 0 ;;
red) echo 1 ;;
green) echo 2 ;;
yellow) echo 3 ;;
blue) echo 4 ;;
magenta|purple|pink) echo 5 ;;
cyan) echo 6 ;;
light-gray) echo 7 ;;
dark-gray) echo 60 ;;
light-red) echo 61 ;;
light-green) echo 62 ;;
light-yellow) echo 63 ;;
light-blue) echo 64 ;;
light-magenta|light-purple) echo 65 ;;
light-cyan) echo 66 ;;
white) echo 67 ;;
*) echo 0 ;;
esac
}
_ssp_fg_code() {
local color="$1"
if [[ "$color" == <-> ]] && (( color >= 0 && color < 256 )); then
printf '38;5;%s' "$color"
else
local bit=$(_ssp_8bit_code "$color")
(( bit == 9 )) && printf '39' || printf '%d' $((bit + 30))
fi
}
_ssp_bg_code() {
local color="$1"
if [[ "$color" == <-> ]] && (( color >= 0 && color < 256 )); then
printf '48;5;%s' "$color"
else
local bit=$(_ssp_8bit_code "$color")
(( bit == 9 )) && printf '49' || printf '%d' $((bit + 40))
fi
}
_ssp_effect_code() {
case "$1" in
bold|bright) echo 1 ;;
dim) echo 2 ;;
underline) echo 4 ;;
blink) echo 5 ;;
reverse) echo 7 ;;
hidden) echo 8 ;;
strikeout) echo 9 ;;
*) echo 0 ;;
esac
}
_ssp_ansi() {
printf '%%{\033[%sm%%}' "$1"
}
# -----------------------------------------------------------------------------
# Warna tiap segment: foreground background effect
# -----------------------------------------------------------------------------
typeset -gA SSP_COLOR_FG SSP_COLOR_BG SSP_COLOR_EFFECT
SSP_COLOR_FG[USER]='black'; SSP_COLOR_BG[USER]='green'; SSP_COLOR_EFFECT[USER]='bold'
SSP_COLOR_FG[HOST]='white'; SSP_COLOR_BG[HOST]='light-blue'; SSP_COLOR_EFFECT[HOST]='bold'
SSP_COLOR_FG[PWD]='dark-gray'; SSP_COLOR_BG[PWD]='white'; SSP_COLOR_EFFECT[PWD]='bold'
SSP_COLOR_FG[GIT]='light-gray'; SSP_COLOR_BG[GIT]='dark-gray'; SSP_COLOR_EFFECT[GIT]='bold'
SSP_COLOR_FG[PYENV]='white'; SSP_COLOR_BG[PYENV]='blue'; SSP_COLOR_EFFECT[PYENV]='bold'
SSP_COLOR_FG[KUBE]='white'; SSP_COLOR_BG[KUBE]='purple'; SSP_COLOR_EFFECT[KUBE]='bold'
SSP_COLOR_FG[TF]='purple'; SSP_COLOR_BG[TF]='light-purple'; SSP_COLOR_EFFECT[TF]='bold'
SSP_COLOR_FG[DATE]='white'; SSP_COLOR_BG[DATE]='light-purple'; SSP_COLOR_EFFECT[DATE]='bold'
SSP_COLOR_FG[CLOCK]='white'; SSP_COLOR_BG[CLOCK]='black'; SSP_COLOR_EFFECT[CLOCK]='bold'
SSP_COLOR_FG[INPUT]='45'; SSP_COLOR_BG[INPUT]='none'; SSP_COLOR_EFFECT[INPUT]='bold'
_ssp_git_branch() {
command -v git >/dev/null 2>&1 || return
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return
local branch
branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null) || return
# Periodic fetch. macOS memakai stat -f, bukan GNU stat -c.
if (( SSP_GIT_UPDATE_PERIOD_MINUTES >= 0 )); then
local gitdir fetch_head last_update now elapsed
gitdir=$(git rev-parse --git-dir 2>/dev/null)
[[ "$gitdir" != /* ]] && gitdir="$PWD/$gitdir"
fetch_head="$gitdir/FETCH_HEAD"
if [[ -f "$fetch_head" ]]; then
last_update=$(stat -f '%m' "$fetch_head" 2>/dev/null)
now=$(date +%s)
if [[ -n "$last_update" ]]; then
elapsed=$(( (now - last_update) / 60 ))
if (( elapsed >= SSP_GIT_UPDATE_PERIOD_MINUTES )); then
(git fetch --recurse-submodules >/dev/null 2>&1 &!)
fi
fi
fi
fi
local porcelain tracking dirty=false ahead=false behind=false symbol=''
porcelain=$(git status --porcelain 2>/dev/null)
[[ -n "$porcelain" ]] && dirty=true
tracking=$(git status --porcelain -uno -b 2>/dev/null)
[[ "$tracking" == *ahead* ]] && ahead=true
[[ "$tracking" == *behind* ]] && behind=true
if $dirty && $ahead && $behind; then
symbol=$SSP_GIT_DIRTY_DIVERGED
elif $dirty && $ahead; then
symbol=$SSP_GIT_DIRTY_AHEAD
elif $dirty && $behind; then
symbol=$SSP_GIT_DIRTY_BEHIND
elif $dirty; then
symbol=$SSP_GIT_DIRTY
elif $ahead && $behind; then
symbol=$SSP_GIT_DIVERGED
elif $ahead; then
symbol=$SSP_GIT_AHEAD
elif $behind; then
symbol=$SSP_GIT_BEHIND
else
symbol=$SSP_GIT_SYNCED
fi
local stash_count stash='' tags tag=''
stash_count=$(git stash list 2>/dev/null | wc -l | tr -d ' ')
(( stash_count > 0 )) && stash=" ${stash_count}${SSP_GIT_STASH}"
tags=$(git tag --points-at HEAD 2>/dev/null | paste -sd ',' -)
[[ -n "$tags" ]] && tag=" $tags"
printf '%s%s%s%s' "$branch" "$symbol" "$stash" "$tag"
}
_ssp_terraform() {
command -v terraform >/dev/null 2>&1 || return
[[ -d .terraform ]] || return
terraform workspace show 2>/dev/null | tr -d '\n'
}
_ssp_pyenv() {
if [[ -n "${CONDA_DEFAULT_ENV:-}" ]]; then
printf '%s' "$CONDA_DEFAULT_ENV"
elif [[ -n "${VIRTUAL_ENV:-}" ]]; then
basename "$VIRTUAL_ENV"
fi
}
_ssp_kube() {
command -v kubectl >/dev/null 2>&1 || return
local ctx cluster
ctx=$(kubectl config current-context 2>/dev/null) || return
[[ -n "$ctx" ]] || return
cluster=$(kubectl config view -o "jsonpath={.contexts[?(@.name==\"$ctx\")].context.cluster}" 2>/dev/null)
[[ -n "$cluster" ]] && printf '%s' "$cluster" || printf '%s' "$ctx"
}
_ssp_indonesian_date() {
local day month hari bulan
day=$(LC_ALL=C date +%A)
month=$(LC_ALL=C date +%B)
case "$day" in
Monday) hari='Senin' ;;
Tuesday) hari='Selasa' ;;
Wednesday) hari='Rabu' ;;
Thursday) hari='Kamis' ;;
Friday) hari="Jum'at" ;;
Saturday) hari='Sabtu' ;;
Sunday) hari='Ahad' ;;
*) hari="$day" ;;
esac
case "$month" in
January) bulan='Januari' ;;
February) bulan='Februari' ;;
March) bulan='Maret' ;;
April) bulan='April' ;;
May) bulan='Mei' ;;
June) bulan='Juni' ;;
July) bulan='Juli' ;;
August) bulan='Agustus' ;;
September) bulan='September' ;;
October) bulan='Oktober' ;;
November) bulan='November' ;;
December) bulan='Desember' ;;
*) bulan="$month" ;;
esac
printf '%s, %s %s %s' "$hari" "$(date +%d)" "$bulan" "$(date +%Y)"
}
_ssp_short_pwd() {
local p="$PWD"
p=${p/#$HOME/~}
if (( ${#p} > SSP_MAX_PWD_CHAR )); then
printf '…%s' "${p: -$((SSP_MAX_PWD_CHAR - 1))}"
else
printf '%s' "$p"
fi
}
_ssp_segment_text() {
case "$1" in
USER) printf '%s' "$USER" ;;
HOST) hostname -s 2>/dev/null || printf '%s' "$HOST" ;;
PWD) _ssp_short_pwd ;;
GIT) _ssp_git_branch ;;
PYENV) _ssp_pyenv ;;
TF) _ssp_terraform ;;
KUBE) _ssp_kube ;;
DATE) _ssp_indonesian_date ;;
CLOCK) date +%H:%M:%S ;;
esac
}
_ssp_print_segment() {
local element="$1" text="$2" next_bg="$3"
local fg=${SSP_COLOR_FG[$element]}
local bg=${SSP_COLOR_BG[$element]}
local effect=${SSP_COLOR_EFFECT[$element]}
local text_code sep_code reset
text_code=$(_ssp_ansi "$(_ssp_fg_code "$fg");$(_ssp_bg_code "$bg");$(_ssp_effect_code "$effect")")
sep_code=$(_ssp_ansi "$(_ssp_fg_code "$bg");$(_ssp_bg_code "$next_bg")")
reset=$(_ssp_ansi '0')
printf '%s%s%s%s%s%s%s' \
"$text_code" "$SSP_SEGMENT_PADDING" "$text" "$SSP_SEGMENT_PADDING" \
"$sep_code" "$SSP_SEPARATOR_CHAR" "$reset"
}
_ssp_build_prompt() {
local -a active
local element text i current next next_bg prompt=''
for element in "${SSP_FORMAT[@]}"; do
text=$(_ssp_segment_text "$element")
[[ -n "$text" ]] && active+=("$element:$text")
done
for (( i=1; i<=${#active[@]}; i++ )); do
current=${active[$i]}
element=${current%%:*}
text=${current#*:}
if (( i < ${#active[@]} )); then
next=${active[$((i+1))]}
next=${next%%:*}
next_bg=${SSP_COLOR_BG[$next]}
else
next_bg='none'
fi
prompt+=$(_ssp_print_segment "$element" "$text" "$next_bg")
done
local input_code reset
input_code=$(_ssp_ansi "$(_ssp_fg_code "${SSP_COLOR_FG[INPUT]}");$(_ssp_bg_code "${SSP_COLOR_BG[INPUT]}");$(_ssp_effect_code "${SSP_COLOR_EFFECT[INPUT]}")")
reset=$(_ssp_ansi '0')
# Dua baris seperti prompt Debian: ╭ segments ... lalu ╰>$
PROMPT=$'\n╭'"${prompt}"$'\n╰>'"${input_code}"'$ '"${reset}"
# Judul terminal.
print -Pn "\e]0;${USER}@$(hostname -s): ${PWD}\a"
}
# Hook native Zsh, menggantikan PROMPT_COMMAND milik Bash.
autoload -Uz add-zsh-hook
add-zsh-hook precmd _ssp_build_prompt
# Bangun prompt pertama kali saat file di-source.
_ssp_build_prompt
| 1 | # shell-prompt.zsh |
| 2 | # Powerline-style prompt untuk Zsh di macOS Tahoe. |
| 3 | # Diadaptasi dari konfigurasi synth-shell Bash. |
| 4 | |
| 5 | [[ -o interactive ]] || return |
| 6 | |
| 7 | # ----------------------------------------------------------------------------- |
| 8 | # Konfigurasi tampilan |
| 9 | # ----------------------------------------------------------------------------- |
| 10 | SSP_FORMAT=(USER HOST PWD GIT PYENV TF KUBE DATE CLOCK) |
| 11 | SSP_SEPARATOR_CHAR=$'\uE0B0' |
| 12 | SSP_SEGMENT_PADDING=' ' |
| 13 | SSP_MAX_PWD_CHAR=25 |
| 14 | |
| 15 | SSP_GIT_SYNCED='' |
| 16 | SSP_GIT_AHEAD=' ▲' |
| 17 | SSP_GIT_BEHIND=' ▼' |
| 18 | SSP_GIT_DIVERGED=' ◆' |
| 19 | SSP_GIT_DIRTY=' ◔' |
| 20 | SSP_GIT_DIRTY_AHEAD=' ◔ △' |
| 21 | SSP_GIT_DIRTY_BEHIND=' ◔ ▽' |
| 22 | SSP_GIT_DIRTY_DIVERGED=' ◔ ◇' |
| 23 | SSP_GIT_STASH='🗎' |
| 24 | SSP_GIT_UPDATE_PERIOD_MINUTES=15 |
| 25 | |
| 26 | # color-name -> ANSI foreground/background base codes. |
| 27 | _ssp_8bit_code() { |
| 28 | case "$1" in |
| 29 | default|none) echo 9 ;; |
| 30 | black) echo 0 ;; |
| 31 | red) echo 1 ;; |
| 32 | green) echo 2 ;; |
| 33 | yellow) echo 3 ;; |
| 34 | blue) echo 4 ;; |
| 35 | magenta|purple|pink) echo 5 ;; |
| 36 | cyan) echo 6 ;; |
| 37 | light-gray) echo 7 ;; |
| 38 | dark-gray) echo 60 ;; |
| 39 | light-red) echo 61 ;; |
| 40 | light-green) echo 62 ;; |
| 41 | light-yellow) echo 63 ;; |
| 42 | light-blue) echo 64 ;; |
| 43 | light-magenta|light-purple) echo 65 ;; |
| 44 | light-cyan) echo 66 ;; |
| 45 | white) echo 67 ;; |
| 46 | *) echo 0 ;; |
| 47 | esac |
| 48 | } |
| 49 | |
| 50 | _ssp_fg_code() { |
| 51 | local color="$1" |
| 52 | if [[ "$color" == <-> ]] && (( color >= 0 && color < 256 )); then |
| 53 | printf '38;5;%s' "$color" |
| 54 | else |
| 55 | local bit=$(_ssp_8bit_code "$color") |
| 56 | (( bit == 9 )) && printf '39' || printf '%d' $((bit + 30)) |
| 57 | fi |
| 58 | } |
| 59 | |
| 60 | _ssp_bg_code() { |
| 61 | local color="$1" |
| 62 | if [[ "$color" == <-> ]] && (( color >= 0 && color < 256 )); then |
| 63 | printf '48;5;%s' "$color" |
| 64 | else |
| 65 | local bit=$(_ssp_8bit_code "$color") |
| 66 | (( bit == 9 )) && printf '49' || printf '%d' $((bit + 40)) |
| 67 | fi |
| 68 | } |
| 69 | |
| 70 | _ssp_effect_code() { |
| 71 | case "$1" in |
| 72 | bold|bright) echo 1 ;; |
| 73 | dim) echo 2 ;; |
| 74 | underline) echo 4 ;; |
| 75 | blink) echo 5 ;; |
| 76 | reverse) echo 7 ;; |
| 77 | hidden) echo 8 ;; |
| 78 | strikeout) echo 9 ;; |
| 79 | *) echo 0 ;; |
| 80 | esac |
| 81 | } |
| 82 | |
| 83 | _ssp_ansi() { |
| 84 | printf '%%{\033[%sm%%}' "$1" |
| 85 | } |
| 86 | |
| 87 | # ----------------------------------------------------------------------------- |
| 88 | # Warna tiap segment: foreground background effect |
| 89 | # ----------------------------------------------------------------------------- |
| 90 | typeset -gA SSP_COLOR_FG SSP_COLOR_BG SSP_COLOR_EFFECT |
| 91 | SSP_COLOR_FG[USER]='black'; SSP_COLOR_BG[USER]='green'; SSP_COLOR_EFFECT[USER]='bold' |
| 92 | SSP_COLOR_FG[HOST]='white'; SSP_COLOR_BG[HOST]='light-blue'; SSP_COLOR_EFFECT[HOST]='bold' |
| 93 | SSP_COLOR_FG[PWD]='dark-gray'; SSP_COLOR_BG[PWD]='white'; SSP_COLOR_EFFECT[PWD]='bold' |
| 94 | SSP_COLOR_FG[GIT]='light-gray'; SSP_COLOR_BG[GIT]='dark-gray'; SSP_COLOR_EFFECT[GIT]='bold' |
| 95 | SSP_COLOR_FG[PYENV]='white'; SSP_COLOR_BG[PYENV]='blue'; SSP_COLOR_EFFECT[PYENV]='bold' |
| 96 | SSP_COLOR_FG[KUBE]='white'; SSP_COLOR_BG[KUBE]='purple'; SSP_COLOR_EFFECT[KUBE]='bold' |
| 97 | SSP_COLOR_FG[TF]='purple'; SSP_COLOR_BG[TF]='light-purple'; SSP_COLOR_EFFECT[TF]='bold' |
| 98 | SSP_COLOR_FG[DATE]='white'; SSP_COLOR_BG[DATE]='light-purple'; SSP_COLOR_EFFECT[DATE]='bold' |
| 99 | SSP_COLOR_FG[CLOCK]='white'; SSP_COLOR_BG[CLOCK]='black'; SSP_COLOR_EFFECT[CLOCK]='bold' |
| 100 | SSP_COLOR_FG[INPUT]='45'; SSP_COLOR_BG[INPUT]='none'; SSP_COLOR_EFFECT[INPUT]='bold' |
| 101 | |
| 102 | _ssp_git_branch() { |
| 103 | command -v git >/dev/null 2>&1 || return |
| 104 | git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return |
| 105 | |
| 106 | local branch |
| 107 | branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null) || return |
| 108 | |
| 109 | # Periodic fetch. macOS memakai stat -f, bukan GNU stat -c. |
| 110 | if (( SSP_GIT_UPDATE_PERIOD_MINUTES >= 0 )); then |
| 111 | local gitdir fetch_head last_update now elapsed |
| 112 | gitdir=$(git rev-parse --git-dir 2>/dev/null) |
| 113 | [[ "$gitdir" != /* ]] && gitdir="$PWD/$gitdir" |
| 114 | fetch_head="$gitdir/FETCH_HEAD" |
| 115 | if [[ -f "$fetch_head" ]]; then |
| 116 | last_update=$(stat -f '%m' "$fetch_head" 2>/dev/null) |
| 117 | now=$(date +%s) |
| 118 | if [[ -n "$last_update" ]]; then |
| 119 | elapsed=$(( (now - last_update) / 60 )) |
| 120 | if (( elapsed >= SSP_GIT_UPDATE_PERIOD_MINUTES )); then |
| 121 | (git fetch --recurse-submodules >/dev/null 2>&1 &!) |
| 122 | fi |
| 123 | fi |
| 124 | fi |
| 125 | fi |
| 126 | |
| 127 | local porcelain tracking dirty=false ahead=false behind=false symbol='' |
| 128 | porcelain=$(git status --porcelain 2>/dev/null) |
| 129 | [[ -n "$porcelain" ]] && dirty=true |
| 130 | tracking=$(git status --porcelain -uno -b 2>/dev/null) |
| 131 | [[ "$tracking" == *ahead* ]] && ahead=true |
| 132 | [[ "$tracking" == *behind* ]] && behind=true |
| 133 | |
| 134 | if $dirty && $ahead && $behind; then |
| 135 | symbol=$SSP_GIT_DIRTY_DIVERGED |
| 136 | elif $dirty && $ahead; then |
| 137 | symbol=$SSP_GIT_DIRTY_AHEAD |
| 138 | elif $dirty && $behind; then |
| 139 | symbol=$SSP_GIT_DIRTY_BEHIND |
| 140 | elif $dirty; then |
| 141 | symbol=$SSP_GIT_DIRTY |
| 142 | elif $ahead && $behind; then |
| 143 | symbol=$SSP_GIT_DIVERGED |
| 144 | elif $ahead; then |
| 145 | symbol=$SSP_GIT_AHEAD |
| 146 | elif $behind; then |
| 147 | symbol=$SSP_GIT_BEHIND |
| 148 | else |
| 149 | symbol=$SSP_GIT_SYNCED |
| 150 | fi |
| 151 | |
| 152 | local stash_count stash='' tags tag='' |
| 153 | stash_count=$(git stash list 2>/dev/null | wc -l | tr -d ' ') |
| 154 | (( stash_count > 0 )) && stash=" ${stash_count}${SSP_GIT_STASH}" |
| 155 | tags=$(git tag --points-at HEAD 2>/dev/null | paste -sd ',' -) |
| 156 | [[ -n "$tags" ]] && tag=" $tags" |
| 157 | |
| 158 | printf '%s%s%s%s' "$branch" "$symbol" "$stash" "$tag" |
| 159 | } |
| 160 | |
| 161 | _ssp_terraform() { |
| 162 | command -v terraform >/dev/null 2>&1 || return |
| 163 | [[ -d .terraform ]] || return |
| 164 | terraform workspace show 2>/dev/null | tr -d '\n' |
| 165 | } |
| 166 | |
| 167 | _ssp_pyenv() { |
| 168 | if [[ -n "${CONDA_DEFAULT_ENV:-}" ]]; then |
| 169 | printf '%s' "$CONDA_DEFAULT_ENV" |
| 170 | elif [[ -n "${VIRTUAL_ENV:-}" ]]; then |
| 171 | basename "$VIRTUAL_ENV" |
| 172 | fi |
| 173 | } |
| 174 | |
| 175 | _ssp_kube() { |
| 176 | command -v kubectl >/dev/null 2>&1 || return |
| 177 | local ctx cluster |
| 178 | ctx=$(kubectl config current-context 2>/dev/null) || return |
| 179 | [[ -n "$ctx" ]] || return |
| 180 | cluster=$(kubectl config view -o "jsonpath={.contexts[?(@.name==\"$ctx\")].context.cluster}" 2>/dev/null) |
| 181 | [[ -n "$cluster" ]] && printf '%s' "$cluster" || printf '%s' "$ctx" |
| 182 | } |
| 183 | |
| 184 | _ssp_indonesian_date() { |
| 185 | local day month hari bulan |
| 186 | day=$(LC_ALL=C date +%A) |
| 187 | month=$(LC_ALL=C date +%B) |
| 188 | |
| 189 | case "$day" in |
| 190 | Monday) hari='Senin' ;; |
| 191 | Tuesday) hari='Selasa' ;; |
| 192 | Wednesday) hari='Rabu' ;; |
| 193 | Thursday) hari='Kamis' ;; |
| 194 | Friday) hari="Jum'at" ;; |
| 195 | Saturday) hari='Sabtu' ;; |
| 196 | Sunday) hari='Ahad' ;; |
| 197 | *) hari="$day" ;; |
| 198 | esac |
| 199 | |
| 200 | case "$month" in |
| 201 | January) bulan='Januari' ;; |
| 202 | February) bulan='Februari' ;; |
| 203 | March) bulan='Maret' ;; |
| 204 | April) bulan='April' ;; |
| 205 | May) bulan='Mei' ;; |
| 206 | June) bulan='Juni' ;; |
| 207 | July) bulan='Juli' ;; |
| 208 | August) bulan='Agustus' ;; |
| 209 | September) bulan='September' ;; |
| 210 | October) bulan='Oktober' ;; |
| 211 | November) bulan='November' ;; |
| 212 | December) bulan='Desember' ;; |
| 213 | *) bulan="$month" ;; |
| 214 | esac |
| 215 | |
| 216 | printf '%s, %s %s %s' "$hari" "$(date +%d)" "$bulan" "$(date +%Y)" |
| 217 | } |
| 218 | |
| 219 | _ssp_short_pwd() { |
| 220 | local p="$PWD" |
| 221 | p=${p/#$HOME/~} |
| 222 | if (( ${#p} > SSP_MAX_PWD_CHAR )); then |
| 223 | printf '…%s' "${p: -$((SSP_MAX_PWD_CHAR - 1))}" |
| 224 | else |
| 225 | printf '%s' "$p" |
| 226 | fi |
| 227 | } |
| 228 | |
| 229 | _ssp_segment_text() { |
| 230 | case "$1" in |
| 231 | USER) printf '%s' "$USER" ;; |
| 232 | HOST) hostname -s 2>/dev/null || printf '%s' "$HOST" ;; |
| 233 | PWD) _ssp_short_pwd ;; |
| 234 | GIT) _ssp_git_branch ;; |
| 235 | PYENV) _ssp_pyenv ;; |
| 236 | TF) _ssp_terraform ;; |
| 237 | KUBE) _ssp_kube ;; |
| 238 | DATE) _ssp_indonesian_date ;; |
| 239 | CLOCK) date +%H:%M:%S ;; |
| 240 | esac |
| 241 | } |
| 242 | |
| 243 | _ssp_print_segment() { |
| 244 | local element="$1" text="$2" next_bg="$3" |
| 245 | local fg=${SSP_COLOR_FG[$element]} |
| 246 | local bg=${SSP_COLOR_BG[$element]} |
| 247 | local effect=${SSP_COLOR_EFFECT[$element]} |
| 248 | local text_code sep_code reset |
| 249 | |
| 250 | text_code=$(_ssp_ansi "$(_ssp_fg_code "$fg");$(_ssp_bg_code "$bg");$(_ssp_effect_code "$effect")") |
| 251 | sep_code=$(_ssp_ansi "$(_ssp_fg_code "$bg");$(_ssp_bg_code "$next_bg")") |
| 252 | reset=$(_ssp_ansi '0') |
| 253 | |
| 254 | printf '%s%s%s%s%s%s%s' \ |
| 255 | "$text_code" "$SSP_SEGMENT_PADDING" "$text" "$SSP_SEGMENT_PADDING" \ |
| 256 | "$sep_code" "$SSP_SEPARATOR_CHAR" "$reset" |
| 257 | } |
| 258 | |
| 259 | _ssp_build_prompt() { |
| 260 | local -a active |
| 261 | local element text i current next next_bg prompt='' |
| 262 | |
| 263 | for element in "${SSP_FORMAT[@]}"; do |
| 264 | text=$(_ssp_segment_text "$element") |
| 265 | [[ -n "$text" ]] && active+=("$element:$text") |
| 266 | done |
| 267 | |
| 268 | for (( i=1; i<=${#active[@]}; i++ )); do |
| 269 | current=${active[$i]} |
| 270 | element=${current%%:*} |
| 271 | text=${current#*:} |
| 272 | |
| 273 | if (( i < ${#active[@]} )); then |
| 274 | next=${active[$((i+1))]} |
| 275 | next=${next%%:*} |
| 276 | next_bg=${SSP_COLOR_BG[$next]} |
| 277 | else |
| 278 | next_bg='none' |
| 279 | fi |
| 280 | prompt+=$(_ssp_print_segment "$element" "$text" "$next_bg") |
| 281 | done |
| 282 | |
| 283 | local input_code reset |
| 284 | input_code=$(_ssp_ansi "$(_ssp_fg_code "${SSP_COLOR_FG[INPUT]}");$(_ssp_bg_code "${SSP_COLOR_BG[INPUT]}");$(_ssp_effect_code "${SSP_COLOR_EFFECT[INPUT]}")") |
| 285 | reset=$(_ssp_ansi '0') |
| 286 | |
| 287 | # Dua baris seperti prompt Debian: ╭ segments ... lalu ╰>$ |
| 288 | PROMPT=$'\n╭'"${prompt}"$'\n╰>'"${input_code}"'$ '"${reset}" |
| 289 | |
| 290 | # Judul terminal. |
| 291 | print -Pn "\e]0;${USER}@$(hostname -s): ${PWD}\a" |
| 292 | } |
| 293 | |
| 294 | # Hook native Zsh, menggantikan PROMPT_COMMAND milik Bash. |
| 295 | autoload -Uz add-zsh-hook |
| 296 | add-zsh-hook precmd _ssp_build_prompt |
| 297 | |
| 298 | # Bangun prompt pertama kali saat file di-source. |
| 299 | _ssp_build_prompt |
| 300 |