|
| 1 | +# jovial.zsh-theme |
| 2 | +# ref: http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html |
| 3 | + |
| 4 | +VIRTUAL_ENV_DISABLE_PROMPT=true |
| 5 | +ZSH_THEME_GIT_PROMPT_PREFIX="%{$FG[239]%}on%{$reset_color%} (%{$FG[159]%}" |
| 6 | +ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}" |
| 7 | +ZSH_THEME_GIT_PROMPT_DIRTY="%{$reset_color%})%{$FG[202]%}✘✘✘" |
| 8 | +ZSH_THEME_GIT_PROMPT_CLEAN="%{$reset_color%})%{$FG[040]%}✔" |
| 9 | + |
| 10 | + |
| 11 | +function iscommand { command -v "$1" > /dev/null; } |
| 12 | + |
| 13 | +function is_git { |
| 14 | + command git rev-parse --is-inside-work-tree &>/dev/null |
| 15 | +} |
| 16 | + |
| 17 | +function rev_parse_find { |
| 18 | + local target="$1" |
| 19 | + local current_path="${2:-`pwd`}" |
| 20 | + local whether_output=${3:-false} |
| 21 | + local parent_path="`dirname $current_path`" |
| 22 | + while [[ "$parent_path" != "/" ]]; do |
| 23 | + if [ -e "${current_path}/${target}" ]; then |
| 24 | + if $whether_output; then echo "$current_path"; fi |
| 25 | + return 0; |
| 26 | + fi |
| 27 | + current_path="$parent_path" |
| 28 | + parent_path="`dirname $parent_path`" |
| 29 | + done |
| 30 | + return 1 |
| 31 | +} |
| 32 | + |
| 33 | +function venv_info_prompt { [ $VIRTUAL_ENV ] && echo "$FG[242](%{$FG[159]%}$(basename $VIRTUAL_ENV)$FG[242])%{$reset_color%} "; } |
| 34 | + |
| 35 | +function get_host_name { echo "[%{$FG[157]%}%m%{$reset_color%}]"; } |
| 36 | + |
| 37 | +function get_user_name { |
| 38 | + local name_prefix="%{$reset_color%}" |
| 39 | + if [[ "$USER" == 'root' || "%UID" == "0" ]]; then |
| 40 | + name_prefix="%{$FG[203]%}" |
| 41 | + fi |
| 42 | + echo "${name_prefix}%n%{$reset_color%}" |
| 43 | +} |
| 44 | + |
| 45 | +function type_tip_pointer { |
| 46 | + if is_git; then |
| 47 | + echo '(ノ˚Д˚)ノ' |
| 48 | + else |
| 49 | + echo '─➤' |
| 50 | + fi |
| 51 | +} |
| 52 | + |
| 53 | +function current_dir { |
| 54 | + echo "%{$terminfo[bold]$FG[228]%}%~%{$reset_color%}" |
| 55 | +} |
| 56 | + |
| 57 | +function get_date_time { |
| 58 | + # echo "%{$reset_color%}%D %*" |
| 59 | + date "+%m-%d %H:%M:%S" |
| 60 | +} |
| 61 | + |
| 62 | +function get_space_size { |
| 63 | + # ref: http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion-Flags |
| 64 | + local str="$1" |
| 65 | + local zero_pattern='%([BSUbfksu]|([FB]|){*})' |
| 66 | + local len=${#${(S%%)str//$~zero_pattern/}} |
| 67 | + local size=$(( $COLUMNS - $len )) |
| 68 | + echo $size |
| 69 | +} |
| 70 | + |
| 71 | +function get_fill_space { |
| 72 | + local size=`get_space_size "$1"` |
| 73 | + printf "%${size}s" |
| 74 | +} |
| 75 | + |
| 76 | +function previous_align_right { |
| 77 | + # CSI ref: https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences |
| 78 | + local new_line=' |
| 79 | + ' |
| 80 | + local str="$1" |
| 81 | + local align_site=`get_space_size "$str"` |
| 82 | + local previous_line="\033[1A" |
| 83 | + local cursor_back="\033[${align_site}G" |
| 84 | + echo "${previous_line}${cursor_back}${str}${new_line}" |
| 85 | +} |
| 86 | + |
| 87 | +function align_right { |
| 88 | + local str="$1" |
| 89 | + local align_site=`get_space_size "$str"` |
| 90 | + local cursor_back="\033[${align_site}G" |
| 91 | + local cursor_begin="\033[1G" |
| 92 | + echo "${cursor_back}${str}${cursor_begin}" |
| 93 | +} |
| 94 | + |
| 95 | +function get_return_status { |
| 96 | + local exit_code=$? |
| 97 | + if [[ $exit_code != 0 ]]; then |
| 98 | + local exit_code_warn=" %{$FG[246]%}exit:%{$fg_bold[red]%}${exit_code}%{$reset_color%}" |
| 99 | + previous_align_right "$exit_code_warn" |
| 100 | + fi |
| 101 | +} |
| 102 | + |
| 103 | +function prompt_node_version { |
| 104 | + if rev_parse_find "package.json" || rev_parse_find "node_modules"; then |
| 105 | + if iscommand node; then |
| 106 | + NODE_PROMPT_PREFIX="%{$FG[239]%}using%{$FG[120]%} " |
| 107 | + NODE_PROMPT="node `node -v`" |
| 108 | + else |
| 109 | + NODE_PROMPT_PREFIX="%{$FG[242]%}[%{$FG[009]%}need " |
| 110 | + NODE_PROMPT="Nodejs%{$FG[242]%}]" |
| 111 | + fi |
| 112 | + echo "${NODE_PROMPT_PREFIX}${NODE_PROMPT}" |
| 113 | + fi |
| 114 | +} |
| 115 | + |
| 116 | +function prompt_python_version { |
| 117 | + PYTHON_PROMPT_PREFIX="%{$FG[239]%}using%{$FG[123]%} " |
| 118 | + if rev_parse_find "venv"; then |
| 119 | + PYTHON_PROMPT="`$(rev_parse_find venv '' true)/venv/bin/python --version`" |
| 120 | + echo "${PYTHON_PROMPT_PREFIX}${PYTHON_PROMPT}" |
| 121 | + elif rev_parse_find "requirements.txt"; then |
| 122 | + if iscommand python; then |
| 123 | + PYTHON_PROMPT="`python --version`" |
| 124 | + else |
| 125 | + PYTHON_PROMPT_PREFIX="%{$FG[242]%}[%{$FG[009]%}need " |
| 126 | + PYTHON_PROMPT="Python%{$FG[242]%}]" |
| 127 | + fi |
| 128 | + echo "${PYTHON_PROMPT_PREFIX}${PYTHON_PROMPT}" |
| 129 | + fi |
| 130 | +} |
| 131 | + |
| 132 | +function dev_env_segment { |
| 133 | + local SEGMENT_ELEMENTS=(node python) |
| 134 | + for element in "${SEGMENT_ELEMENTS[@]}"; do |
| 135 | + local segment=`prompt_${element}_version` |
| 136 | + if [ -n "$segment" ]; then |
| 137 | + echo "$segment " |
| 138 | + break |
| 139 | + fi |
| 140 | + done |
| 141 | +} |
| 142 | + |
| 143 | +local JOVIAL_PROMPT_PREVIOUS='`get_return_status`' |
| 144 | +local JOVIAL_PROMPT_HEAD='╭─$(get_host_name) %{$FG[239]%}as $(get_user_name) %{$FG[239]%}in $(current_dir) $(dev_env_segment)$(git_prompt_info) ' |
| 145 | +local JOVIAL_PROMPT_FOOT='╰─$(type_tip_pointer) $(venv_info_prompt) ' |
| 146 | +local JOVIAL_PROMPT_HEAD_RIGHT_TIME='$(align_right " `get_date_time`")' |
| 147 | + |
| 148 | +PROMPT="$JOVIAL_PROMPT_PREVIOUS |
| 149 | +${JOVIAL_PROMPT_HEAD_RIGHT_TIME}${JOVIAL_PROMPT_HEAD} |
| 150 | +$JOVIAL_PROMPT_FOOT" |
| 151 | + |
0 commit comments