zsh: avoid global array of colors in prompt
This commit is contained in:
parent
a28fa3a3f8
commit
eff5a3d0b1
1 changed files with 86 additions and 59 deletions
|
@ -1,19 +1,6 @@
|
||||||
typeset -gA zfg=(
|
typeset -gA _fs_prompt=(
|
||||||
[reset]='%{%f%}'
|
[is_transient]=true
|
||||||
|
[transient_color]='%{%F{magenta}%}'
|
||||||
[black]='%{%F{black}%}'
|
|
||||||
[red]='%{%F{red}%}'
|
|
||||||
[green]='%{%F{green}%}'
|
|
||||||
[yellow]='%{%F{yellow}%}'
|
|
||||||
[blue]='%{%F{blue}%}'
|
|
||||||
[magenta]='%{%F{magenta}%}'
|
|
||||||
[cyan]='%{%F{cyan}%}'
|
|
||||||
[white]='%{%F{white}%}'
|
|
||||||
|
|
||||||
# %F{...} only supports the 8 basic colors by name
|
|
||||||
[gray]='%{%F{8}%}'
|
|
||||||
[bright]='%{%F{15}%}'
|
|
||||||
[faded]='%{%F{240}%}'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
typeset -gA icons=(
|
typeset -gA icons=(
|
||||||
|
@ -28,69 +15,101 @@ typeset -gA icons=(
|
||||||
)
|
)
|
||||||
|
|
||||||
fs_prompt_render_full() {
|
fs_prompt_render_full() {
|
||||||
local separator="${zfg[faded]} ❯ "
|
local black='%{%F{0}%}' red='%{%F{1}%}' green='%{%F{2}%}' yellow='%{%F{3}%}' \
|
||||||
|
blue='%{%F{4}%}' magenta='%{%F{5}%}' cyan='%{%F{6}%}' white='%{%F{7}%}' \
|
||||||
|
gray='%{%F{8}%}' orange='%{%F{166}%}' faded='%{%F{240}%}' \
|
||||||
|
reset='%{%f%}'
|
||||||
|
|
||||||
|
local sep_color="$faded" signal_color="$white" error_color="$red" reset="$reset"
|
||||||
|
|
||||||
local sections=(
|
local sections=(
|
||||||
"$(fs_prompt_exit_code)"
|
"$(fs_prompt_exit_code $error_color $signal_color)"
|
||||||
"$(fs_prompt_user_and_hostname)"
|
# root user separator
|
||||||
"$(fs_prompt_pwd)"
|
"$(fs_prompt_user_and_hostname $red $yellow $faded)"
|
||||||
"$(fs_prompt_git)"
|
"$(fs_prompt_pwd $cyan)"
|
||||||
"$(fs_prompt_virtualenv)"
|
# branch ahead behind untracked staged dirty conflict separator
|
||||||
"$(fs_prompt_jobs)"
|
"$(fs_prompt_git $blue $blue $cyan $white $green $orange $red $gray)"
|
||||||
"$(fs_prompt_exec_time)"
|
"$(fs_prompt_virtualenv $yellow)"
|
||||||
|
"$(fs_prompt_jobs $magenta)"
|
||||||
|
"$(fs_prompt_exec_time $gray)"
|
||||||
)
|
)
|
||||||
echo "\n${(@pj.$separator.)sections:#}${zfg[reset]}"
|
local sep="$sep_color ❯ "
|
||||||
|
echo "\n${(@pj:$sep:)sections:#}$reset"
|
||||||
|
|
||||||
if ((PROMPT_EXIT_CODE == 0)); then
|
if ((PROMPT_EXIT_CODE == 0)); then
|
||||||
echo -n "${zfg[faded]}"
|
echo -n "$sep_color"
|
||||||
elif ((PROMPT_EXIT_CODE > 128 && PROMPT_EXIT_CODE < 160)); then
|
elif ((PROMPT_EXIT_CODE > 128 && PROMPT_EXIT_CODE < 160)); then
|
||||||
echo -n "${zfg[white]}"
|
echo -n "$signal_color"
|
||||||
else
|
else
|
||||||
echo -n "${zfg[red]}"
|
echo -n "$error_color"
|
||||||
fi
|
fi
|
||||||
(($SHLVL > 1)) && printf '%.0s' {2..$SHLVL}
|
(($SHLVL > 1)) && printf '%.0s' {2..$SHLVL}
|
||||||
echo -n "❯ ${zfg[reset]}"
|
echo -n "❯ $reset"
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_prompt_render_compact() {
|
fs_prompt_render_compact() {
|
||||||
echo -n "${zfg[magenta]}❯ ${zfg[reset]}"
|
echo -n "${_fs_prompt[transient_color]}❯ %{%f%}"
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_prompt_exit_code() {
|
fs_prompt_exit_code() {
|
||||||
((PROMPT_EXIT_CODE == 0)) && return
|
((PROMPT_EXIT_CODE == 0)) && return
|
||||||
|
|
||||||
|
local error_color="$1" signal_color="$2" bold="%{%B%}" no_bold="%{%b%}"
|
||||||
|
|
||||||
if ((PROMPT_EXIT_CODE > 128 && PROMPT_EXIT_CODE < 160)); then
|
if ((PROMPT_EXIT_CODE > 128 && PROMPT_EXIT_CODE < 160)); then
|
||||||
print "%{%B%}${zfg[white]}$(kill -l $PROMPT_EXIT_CODE)%{%b%}"
|
print "${bold}${signal_color}$(kill -l $PROMPT_EXIT_CODE)${no_bold}"
|
||||||
else
|
else
|
||||||
print "%{%B%}${zfg[red]} $PROMPT_EXIT_CODE%{%b%}"
|
print "${bold}${error_color} ${PROMPT_EXIT_CODE}${no_bold}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_prompt_user_and_hostname() {
|
fs_prompt_user_and_hostname() {
|
||||||
|
local root_color="$1" user_color="$2" at_color="${3:-$2}"
|
||||||
local parts=()
|
local parts=()
|
||||||
|
|
||||||
# username in red if root, yellow if otherwise relevant
|
# username in red if root, yellow if otherwise relevant
|
||||||
if [[ $UID == 0 ]]; then
|
if [[ $UID == 0 ]]; then
|
||||||
parts+="${zfg[red]}${icons[user]}%n"
|
parts+="${root_color}${icons[user]}%n"
|
||||||
elif [[ $LOGNAME != $USER ]] || [[ -n $SSH_CONNECTION ]]; then
|
elif [[ $LOGNAME != $USER ]] || [[ -n $SSH_CONNECTION ]]; then
|
||||||
parts+="${zfg[yellow]}${icons[user]}%n"
|
parts+="${user_color}${icons[user]}%n"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# hostname in yellow if relevant
|
# hostname in yellow if relevant
|
||||||
[[ -n $SSH_CONNECTION ]] && parts+="${zfg[yellow]}%m"
|
[[ -n $SSH_CONNECTION ]] && parts+="${user_color}%m"
|
||||||
|
|
||||||
(($#parts)) && {
|
(($#parts)) && {
|
||||||
local separator="${zfg[gray]}@"
|
local at="${at_color}@"
|
||||||
print "${(pj:$separator:)parts}"
|
print "${(pj:$at:)parts}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_prompt_pwd() {
|
fs_prompt_pwd() {
|
||||||
print "${zfg[cyan]}${icons[folder]}%~"
|
local color="$1"
|
||||||
|
print "${color}${icons[folder]}%~"
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_prompt_git() {
|
fs_prompt_git() {
|
||||||
|
local branch_color="$1"
|
||||||
|
local ahead_color="$2"
|
||||||
|
local behind_color="$3"
|
||||||
|
local untracked_color="$4"
|
||||||
|
local staged_color="$5"
|
||||||
|
local dirty_color="$6"
|
||||||
|
local conflict_color="$7"
|
||||||
|
local sep_color="$8"
|
||||||
|
|
||||||
local gitstatus # local swallows git's exit code if not on its own line
|
local gitstatus # local swallows git's exit code if not on its own line
|
||||||
gitstatus=$(command git status --porcelain -b 2>/dev/null) || return
|
# gitstatus=$(command git status --porcelain -b 2>/dev/null) || return
|
||||||
|
|
||||||
|
gitstatus="## some-longer-name...origin/tracking [ahead 5, behind 12]
|
||||||
|
M staged_1
|
||||||
|
M staged_2
|
||||||
|
M dirty_1
|
||||||
|
M dirty_2
|
||||||
|
M dirty_3
|
||||||
|
DD conflict
|
||||||
|
?? untracked
|
||||||
|
"
|
||||||
|
|
||||||
# Sort through the status of files.
|
# Sort through the status of files.
|
||||||
local untracked=0 dirty=0 staged=0 conflicts=0 branch_line=''
|
local untracked=0 dirty=0 staged=0 conflicts=0 branch_line=''
|
||||||
|
@ -150,42 +169,50 @@ fs_prompt_git() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
local track_parts=()
|
local result=()
|
||||||
(($ahead > 0 )) && track_parts+="${zfg[blue]}↑${ahead}"
|
{
|
||||||
(($behind > 0 )) && track_parts+="${zfg[cyan]}${behind}↓"
|
local sep="${sep_color}"
|
||||||
|
local tracking=()
|
||||||
|
(($ahead)) && tracking+="${ahead_color}${ahead}" # ↑
|
||||||
|
(($behind)) && tracking+="${behind_color}${behind}" # ↓
|
||||||
|
(($#tracking)) && result+="${(pj:$sep:)tracking} "
|
||||||
|
|
||||||
local state_parts=()
|
(($conflicts)) && result+="${conflict_color} %{%B%}${conflicts}%{%b%}"
|
||||||
(($staged > 0)) && state_parts+="${zfg[green]}+${staged}"
|
|
||||||
(($dirty > 0 )) && state_parts+="${zfg[red]}${dirty}✶"
|
|
||||||
|
|
||||||
local separator="${zfg[gray]}"
|
local state=()
|
||||||
local gitinfo=("${zfg[blue]}${branch}")
|
(($staged)) && state+="${staged_color}+${staged}"
|
||||||
(($#track_parts > 0)) && gitinfo+="${(pj:$separator:)track_parts}"
|
(($dirty)) && state+="${dirty_color}${dirty}✶"
|
||||||
(($conflicts > 0 )) && gitinfo+="${zfg[red]}${conflicts} "
|
(($#state)) && result+="${(pj:$sep:)state}"
|
||||||
(($untracked > 0 )) && gitinfo+="${zfg[white]}${untracked}?"
|
|
||||||
(($#state_parts)) && gitinfo+="${(pj:$separator:)state_parts}"
|
|
||||||
|
|
||||||
print "${(j: :)gitinfo}"
|
(($untracked)) && result+="${untracked_color}${untracked}?"
|
||||||
|
}
|
||||||
|
print "${branch_color}${branch} ${(j: :)result}"
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_prompt_virtualenv() {
|
fs_prompt_virtualenv() {
|
||||||
[[ -n "$VIRTUAL_ENV" ]] && print "${zfg[green]}${icons[python]}${VIRTUAL_ENV:t}"
|
[[ -n "$VIRTUAL_ENV" ]] || return
|
||||||
|
local color="$1"
|
||||||
|
print "${color}${icons[python]}${VIRTUAL_ENV:t}"
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_prompt_jobs() {
|
fs_prompt_jobs() {
|
||||||
(($PROMPT_JOB_COUNT > 0)) && print "${zfg[magenta]}${icons[background]}%j"
|
(($PROMPT_JOB_COUNT)) || return
|
||||||
|
local color="$1"
|
||||||
|
print "${color}${icons[background]}%j"
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_prompt_exec_time() {
|
fs_prompt_exec_time() {
|
||||||
(($PROMPT_EXEC_TIME <= 3)) && return # don't print time if under 3s
|
(($PROMPT_EXEC_TIME <= 3)) && return # don't print time if under 3s
|
||||||
|
|
||||||
|
local color="$1"
|
||||||
local parts=(
|
local parts=(
|
||||||
"$((PROMPT_EXEC_TIME / 60 / 60 / 24))d" # days
|
"$((PROMPT_EXEC_TIME / 60 / 60 / 24))d" # days
|
||||||
"$((PROMPT_EXEC_TIME / 60 / 60 % 24))h" # hours
|
"$((PROMPT_EXEC_TIME / 60 / 60 % 24))h" # hours
|
||||||
"$((PROMPT_EXEC_TIME / 60 % 60))m" # minutes
|
"$((PROMPT_EXEC_TIME / 60 % 60))m" # minutes
|
||||||
"$((PROMPT_EXEC_TIME % 60))s" # seconds
|
"$((PROMPT_EXEC_TIME % 60))s" # seconds
|
||||||
)
|
)
|
||||||
print ${zfg[gray]}${icons[clock]}${parts:#0*} # only keep non-zero parts
|
local exec_time="${(@)parts:#0*}" # only keep non-zero parts
|
||||||
|
[[ -n "$exec_time" ]] && print "${color}${icons[clock]}${exec_time}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Hook triggered when a command is about to be executed.
|
# Hook triggered when a command is about to be executed.
|
||||||
|
@ -224,12 +251,12 @@ fs_setup_prompt() {
|
||||||
add-zsh-hook preexec fs_prompt_preexec
|
add-zsh-hook preexec fs_prompt_preexec
|
||||||
add-zsh-hook precmd fs_prompt_precmd
|
add-zsh-hook precmd fs_prompt_precmd
|
||||||
|
|
||||||
# Change to false to disable transient prompt.
|
if ${_fs_prompt[is_transient]}; then
|
||||||
local use_transient_prompt=true
|
|
||||||
if $use_transient_prompt; then
|
|
||||||
autoload -Uz add-zle-hook-widget
|
autoload -Uz add-zle-hook-widget
|
||||||
add-zle-hook-widget line-finish fs_prompt_zle_line_finish
|
add-zle-hook-widget line-finish fs_prompt_zle_line_finish
|
||||||
PS2="${zfg[magenta]}%_❯${zfg[reset]} "
|
PS2="${_fs_prompt[transient_color]}%_❯%{%f%} "
|
||||||
|
else
|
||||||
|
add-zle-hook-widget -d line-finish fs_prompt_zle_line_finish
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue