dracula.zsh-theme 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. # -*- mode: sh; -*-
  2. # vim: set ft=sh :
  3. # Dracula Theme v1.2.5
  4. #
  5. # https://github.com/dracula/dracula-theme
  6. #
  7. # Copyright 2019, All rights reserved
  8. #
  9. # Code licensed under the MIT license
  10. # http://zenorocha.mit-license.org
  11. #
  12. # @author Zeno Rocha <hi@zenorocha.com>
  13. # @maintainer Avalon Williams <avalonwilliams@protonmail.com>
  14. # Initialization {{{
  15. source ${0:A:h}/lib/async.zsh
  16. autoload -Uz add-zsh-hook
  17. setopt PROMPT_SUBST
  18. async_init
  19. PROMPT=''
  20. # }}}
  21. # Options {{{
  22. # Set to 0 to disable the git status
  23. DRACULA_DISPLAY_GIT=${DRACULA_DISPLAY_GIT:-1}
  24. # Set to 1 to show the date
  25. DRACULA_DISPLAY_TIME=${DRACULA_DISPLAY_TIME:-0}
  26. # Set to 1 to show the 'context' segment
  27. DRACULA_DISPLAY_CONTEXT=${DRACULA_DISPLAY_CONTEXT:-0}
  28. # Changes the arrow icon
  29. DRACULA_ARROW_ICON=${DRACULA_ARROW_ICON:-➜ }
  30. # Set to 1 to use a new line for commands
  31. DRACULA_DISPLAY_NEW_LINE=${DRACULA_DISPLAY_NEW_LINE:-0}
  32. # Set to 1 to show full path of current working directory
  33. DRACULA_DISPLAY_FULL_CWD=${DRACULA_DISPLAY_FULL_CWD:-0}
  34. # function to detect if git has support for --no-optional-locks
  35. dracula_test_git_optional_lock() {
  36. local git_version=${DEBUG_OVERRIDE_V:-"$(git version | cut -d' ' -f3)"}
  37. local git_version="$(git version | cut -d' ' -f3)"
  38. # test for git versions < 2.14.0
  39. case "$git_version" in
  40. [0-1].*)
  41. echo 0
  42. return 1
  43. ;;
  44. 2.[0-9].*)
  45. echo 0
  46. return 1
  47. ;;
  48. 2.1[0-3].*)
  49. echo 0
  50. return 1
  51. ;;
  52. esac
  53. # if version > 2.14.0 return true
  54. echo 1
  55. }
  56. # use --no-optional-locks flag on git
  57. DRACULA_GIT_NOLOCK=${DRACULA_GIT_NOLOCK:-$(dracula_test_git_optional_lock)}
  58. # time format string
  59. if [[ -z "$DRACULA_TIME_FORMAT" ]]; then
  60. DRACULA_TIME_FORMAT="%-H:%M"
  61. # check if locale uses AM and PM
  62. if locale -ck LC_TIME 2>/dev/null | grep -q '^t_fmt="%r"$'; then
  63. DRACULA_TIME_FORMAT="%-I:%M%p"
  64. fi
  65. fi
  66. # }}}
  67. # Status segment {{{
  68. dracula_arrow() {
  69. if [[ "$1" = "start" ]] && (( ! DRACULA_DISPLAY_NEW_LINE )); then
  70. print -P "$DRACULA_ARROW_ICON"
  71. elif [[ "$1" = "end" ]] && (( DRACULA_DISPLAY_NEW_LINE )); then
  72. print -P "\n$DRACULA_ARROW_ICON"
  73. fi
  74. }
  75. # arrow is green if last command was successful, red if not,
  76. # turns yellow in vi command mode
  77. PROMPT+='%(1V:%F{yellow}:%(?:%F{green}:%F{red}))%B$(dracula_arrow start)'
  78. # }}}
  79. # Time segment {{{
  80. dracula_time_segment() {
  81. if (( DRACULA_DISPLAY_TIME )); then
  82. print -P "%D{$DRACULA_TIME_FORMAT} "
  83. fi
  84. }
  85. PROMPT+='%F{green}%B$(dracula_time_segment)'
  86. # }}}
  87. # User context segment {{{
  88. dracula_context() {
  89. if (( DRACULA_DISPLAY_CONTEXT )); then
  90. if [[ -n "${SSH_CONNECTION-}${SSH_CLIENT-}${SSH_TTY-}" ]] || (( EUID == 0 )); then
  91. echo '%n@%m '
  92. else
  93. echo '%n '
  94. fi
  95. fi
  96. }
  97. PROMPT+='%F{magenta}%B$(dracula_context)'
  98. # }}}
  99. # Directory segment {{{
  100. dracula_directory() {
  101. if (( DRACULA_DISPLAY_FULL_CWD )); then
  102. print -P '%~ '
  103. else
  104. print -P '%c '
  105. fi
  106. }
  107. PROMPT+='%F{blue}%B$(dracula_directory)'
  108. # }}}
  109. # Custom variable {{{
  110. custom_variable_prompt() {
  111. [[ -z "$DRACULA_CUSTOM_VARIABLE" ]] && return
  112. echo "%F{yellow}$DRACULA_CUSTOM_VARIABLE "
  113. }
  114. PROMPT+='$(custom_variable_prompt)'
  115. # }}}
  116. # Async git segment {{{
  117. dracula_git_status() {
  118. (( ! DRACULA_DISPLAY_GIT )) && return
  119. cd "$1"
  120. local ref branch lockflag
  121. (( DRACULA_GIT_NOLOCK )) && lockflag="--no-optional-locks"
  122. ref=$(=git $lockflag symbolic-ref --quiet HEAD 2>/dev/null)
  123. case $? in
  124. 0) ;;
  125. 128) return ;;
  126. *) ref=$(=git $lockflag rev-parse --short HEAD 2>/dev/null) || return ;;
  127. esac
  128. branch=${ref#refs/heads/}
  129. if [[ -n $branch ]]; then
  130. echo -n "${ZSH_THEME_GIT_PROMPT_PREFIX}${branch}"
  131. local git_status icon
  132. git_status="$(LC_ALL=C =git $lockflag status 2>&1)"
  133. if [[ "$git_status" =~ 'new file:|deleted:|modified:|renamed:|Untracked files:' ]]; then
  134. echo -n "$ZSH_THEME_GIT_PROMPT_DIRTY"
  135. else
  136. echo -n "$ZSH_THEME_GIT_PROMPT_CLEAN"
  137. fi
  138. echo -n "$ZSH_THEME_GIT_PROMPT_SUFFIX"
  139. fi
  140. }
  141. dracula_git_callback() {
  142. DRACULA_GIT_STATUS="$3"
  143. zle && zle reset-prompt
  144. async_stop_worker dracula_git_worker dracula_git_status "$(pwd)"
  145. }
  146. dracula_git_async() {
  147. async_start_worker dracula_git_worker -n
  148. async_register_callback dracula_git_worker dracula_git_callback
  149. async_job dracula_git_worker dracula_git_status "$(pwd)"
  150. }
  151. add-zsh-hook precmd dracula_git_async
  152. PROMPT+='$DRACULA_GIT_STATUS'
  153. ZSH_THEME_GIT_PROMPT_CLEAN=") %F{green}%B✔ "
  154. ZSH_THEME_GIT_PROMPT_DIRTY=") %F{yellow}%B✗ "
  155. ZSH_THEME_GIT_PROMPT_PREFIX="%F{cyan}%B("
  156. ZSH_THEME_GIT_PROMPT_SUFFIX="%f%b"
  157. # }}}
  158. # Linebreak {{{
  159. PROMPT+='%(1V:%F{yellow}:%(?:%F{green}:%F{red}))%B$(dracula_arrow end)'
  160. # }}}
  161. # define widget without clobbering old definitions
  162. dracula_defwidget() {
  163. local fname=dracula-wrap-$1
  164. local prev=($(zle -l -L "$1"))
  165. local oldfn=${prev[4]:-$1}
  166. # if no existing zle functions, just define it normally
  167. if [[ -z "$prev" ]]; then
  168. zle -N $1 $2
  169. return
  170. fi
  171. # if already defined, return
  172. [[ "${prev[4]}" = $fname ]] && return
  173. oldfn=${prev[4]:-$1}
  174. zle -N dracula-old-$oldfn $oldfn
  175. eval "$fname() { $2 \"\$@\"; zle dracula-old-$oldfn -- \"\$@\"; }"
  176. zle -N $1 $fname
  177. }
  178. # ensure vi mode is handled by prompt
  179. dracula_zle_update() {
  180. if [[ $KEYMAP = vicmd ]]; then
  181. psvar[1]=vicmd
  182. else
  183. psvar[1]=''
  184. fi
  185. zle reset-prompt
  186. zle -R
  187. }
  188. dracula_defwidget zle-line-init dracula_zle_update
  189. dracula_defwidget zle-keymap-select dracula_zle_update
  190. # Ensure effects are reset
  191. PROMPT+='%f%b'