zsh: more git info in prompt + refactor prompt init

This commit is contained in:
Henrik Lissner 2015-12-12 16:58:40 -05:00
parent 841e06ec39
commit 3b118afb92

View file

@ -1,18 +1,5 @@
# Based off Pure <https://github.com/sindresorhus/pure> # Based off Pure <https://github.com/sindresorhus/pure>
# For my own and others sanity
# git:
# %b => current branch
# %a => current action (rebase/merge)
# prompt:
# %F => color dict
# %f => reset color
# %~ => current path
# %* => time
# %n => username
# %m => shortname host
# %(?..) => prompt conditional - %(condition.true.false)
# turns seconds into human readable time # turns seconds into human readable time
# 165392 => 1d 21h 56m 32s # 165392 => 1d 21h 56m 32s
_human_time() { _human_time() {
@ -36,13 +23,21 @@ _string_length() {
# fastest possible way to check if repo is dirty # fastest possible way to check if repo is dirty
prompt_git_dirty() { prompt_git_dirty() {
# disable auth prompting on git 2.3+
GIT_TERMINAL_PROMPT=0
# check if we're in a git repo # check if we're in a git repo
[[ "$(command git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]] || return [[ "$(command git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]] || return
# check if it's dirty # check if it's dirty
[[ "$PURE_GIT_UNTRACKED_DIRTY" == 0 ]] && local umode="-uno" || local umode="-unormal" [[ "$(git status --porcelain --ignore-submodules -unormal)" ]] || return
command test -n "$(git status --porcelain --ignore-submodules ${umode})"
(($? == 0)) && echo '*' echo -n "%F{red}[+]"
local r=$(command git rev-list --right-only --count HEAD...@'{u}' 2>/dev/null)
local l=$(command git rev-list --left-only --count HEAD...@'{u}' 2>/dev/null)
(( ${r:-0} > 0 )) && echo -n " %F{green}$r"
(( ${l:-0} > 0 )) && echo -n " %F{yellow}$l"
echo -n '%f'
} }
# displays the exec time of the last command if set threshold was exceeded # displays the exec time of the last command if set threshold was exceeded
@ -50,67 +45,34 @@ prompt_cmd_exec_time() {
local stop=$EPOCHSECONDS local stop=$EPOCHSECONDS
local start=${cmd_timestamp:-$stop} local start=${cmd_timestamp:-$stop}
integer elapsed=$stop-$start integer elapsed=$stop-$start
(($elapsed > ${PURE_CMD_MAX_EXEC_TIME:=5})) && _human_time $elapsed (($elapsed > 2)) && _human_time $elapsed
} }
## Hooks ############################### ## Hooks ###############################
prompt_hook_preexec() { prompt_hook_preexec() {
cmd_timestamp=$EPOCHSECONDS cmd_timestamp=$EPOCHSECONDS
# shows the current dir and executed command in the title when a process is active
print -Pn "\e]0;"
echo -nE "$PWD:t: $2"
print -Pn "\a"
} }
prompt_hook_precmd() { prompt_hook_precmd() {
# shows the full path in the title # shows the full path in the title
print -Pn '\e]0;%~\a' print -Pn '\e]0;%~\a'
# git info # git info
vcs_info vcs_info
local prompt_preprompt="%F{blue}%~%F{242}$vcs_info_msg_0_`prompt_git_dirty`%f%F{yellow}`prompt_cmd_exec_time`%f"''
# print -P $prompt_preprompt
RPROMPT=$prompt_preprompt
# check async if there is anything to pull
(( ${PURE_GIT_PULL:-1} )) && {
# check if we're in a git repo
[[ "$(command git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]] &&
# make sure working tree is not $HOME
[[ "$(command git rev-parse --show-toplevel)" != "$HOME" ]] &&
# check check if there is anything to pull
command git -c gc.auto=0 fetch &>/dev/null &&
# check if there is an upstream configured for this branch
command git rev-parse --abbrev-ref @'{u}' &>/dev/null && {
local arrows=''
(( $(command git rev-list --right-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows='⇣'
(( $(command git rev-list --left-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows+='⇡'
RPROMPT+="\e7\e[A\e[1G\e[`_string_length $prompt_preprompt`C%F{cyan}${arrows}%f\e8"
}
} &!
# reset value since `preexec` isn't always triggered
unset cmd_timestamp
} }
# Updates cursor shape and prompt symbol based on vim mode
prompt_hook_update_vim_mode() { prompt_hook_update_vim_mode() {
# change cursor shape in iTerm2
case $KEYMAP in case $KEYMAP in
vicmd) print -n -- "\E]50;CursorShape=0\C-G"; vicmd) print -n -- "\E]50;CursorShape=0\C-G";
CUR_MODE=$N_MODE; PROMPT_SYMBOL=$N_MODE;
;; # block cursor ;; # block cursor
main|viins) print -n -- "\E]50;CursorShape=1\C-G"; main|viins) print -n -- "\E]50;CursorShape=1\C-G";
CUR_MODE=$I_MODE; PROMPT_SYMBOL=$I_MODE;
;; # line cursor ;; # line cursor
esac esac
zle reset-prompt zle reset-prompt
zle -R zle -R
} }
prompt_hook_restore_cursor() { prompt_hook_restore_cursor() {
print -n -- "\E]50;CursorShape=0\C-G" # block cursor print -n -- "\E]50;CursorShape=0\C-G" # block cursor
} }
@ -120,8 +82,6 @@ prompt_init() {
# prevent percentage showing up # prevent percentage showing up
# if output doesn't end with a newline # if output doesn't end with a newline
export PROMPT_EOL_MARK='' export PROMPT_EOL_MARK=''
# disable auth prompting on git 2.3+
export GIT_TERMINAL_PROMPT=0
prompt_opts=(cr subst percent) prompt_opts=(cr subst percent)
@ -133,21 +93,16 @@ prompt_init() {
add-zsh-hook precmd prompt_hook_precmd add-zsh-hook precmd prompt_hook_precmd
add-zsh-hook preexec prompt_hook_preexec add-zsh-hook preexec prompt_hook_preexec
zstyle ':vcs_info:*' enable git # Show $N-MODE if in normal mode and Change cursor depending on vim mode
zstyle ':vcs_info:*' use-simple true
zstyle ':vcs_info:git*' formats ' %b'
zstyle ':vcs_info:git*' actionformats ' %b|%a'
## Vim setup
N_MODE="%F{blue}# "
I_MODE=" "
# Show $N-MODE if in normal mode
# Change cursor depending on vim mode
hooks-add-hook zle_keymap_select_hook prompt_hook_update_vim_mode hooks-add-hook zle_keymap_select_hook prompt_hook_update_vim_mode
hooks-add-hook zle_line_init_hook prompt_hook_update_vim_mode hooks-add-hook zle_line_init_hook prompt_hook_update_vim_mode
hooks-add-hook zle_line_finish_hook prompt_hook_restore_cursor hooks-add-hook zle_line_finish_hook prompt_hook_restore_cursor
zstyle ':vcs_info:*' enable git
zstyle ':vcs_info:*' use-simple true
zstyle ':vcs_info:*' max-exports 2
zstyle ':vcs_info:git*' formats ':%b'
zstyle ':vcs_info:git*' actionformats ':%b (%a)'
# show username@host if logged in through SSH # show username@host if logged in through SSH
[[ "$SSH_CONNECTION" != '' ]] && prompt_username='%n@%m ' [[ "$SSH_CONNECTION" != '' ]] && prompt_username='%n@%m '
@ -155,8 +110,18 @@ prompt_init() {
# show username@host if root, with username in white # show username@host if root, with username in white
[[ $UID -eq 0 ]] && prompt_username='%F{white}%n%F{242}@%m ' [[ $UID -eq 0 ]] && prompt_username='%F{white}%n%F{242}@%m '
# prompt turns red if the previous command didn't exit with 0 ## Vim cursors
PROMPT='$prompt_username%(?.%F{yellow}.%F{red})$CUR_MODE%f' N_MODE="%F{blue}## "
I_MODE=">> "
RPROMPT='%F{blue}%~' # PWD
RPROMPT+='%F{242}${vcs_info_msg_0_}$(prompt_git_dirty)' # Branch + dirty indicator
RPROMPT+='%F{yellow}$(prompt_cmd_exec_time)' # Exec time
RPROMPT+='%f' # end
PROMPT='$prompt_username' # username
PROMPT+='%(?.%F{yellow}.%F{red})${PROMPT_SYMBOL}' # Prompt (red if $? == 0)
PROMPT+='%f' #end
} }
prompt_init "$@" prompt_init "$@"