From: Samir Benmendil Date: Mon, 15 Jun 2015 01:51:26 +0000 (+0100) Subject: zsh: vi-mode and new prompt X-Git-Url: https://git.rmz.io/dotfiles.git/commitdiff_plain/2bb3c600f31aa7e1af1fbef3656ab6947a7585e3?ds=inline zsh: vi-mode and new prompt --- diff --git a/zsh/lib/00-key-bindings.zsh b/zsh/lib/00-key-bindings.zsh index 803ec37..7fd00e5 100644 --- a/zsh/lib/00-key-bindings.zsh +++ b/zsh/lib/00-key-bindings.zsh @@ -1,33 +1,59 @@ -# TODO: Explain what some of this does.. +bindkey -v -bindkey -e -bindkey -s '\el' "ls\n" -bindkey '\ew' kill-region -bindkey '^r' history-incremental-search-backward -bindkey "^[[5~" up-line-or-history -bindkey "^[[6~" down-line-or-history +bindkey '^N' history-search-forward +bindkey '^P' history-search-backward +bindkey ' ' magic-space # also do history expansion on space -# make search up and down work, so partially type and hit up/down to find relevant stuff -bindkey '^[[A' up-line-or-search # up arrow -bindkey '^[[B' down-line-or-search # down arrow - -bindkey "^[[H" beginning-of-line -bindkey "^[[1~" beginning-of-line -bindkey "^[OH" beginning-of-line -bindkey "[7~" beginning-of-line -bindkey "^[[F" end-of-line -bindkey "^[[4~" end-of-line -bindkey "[8~" end-of-line -bindkey "^[OF" end-of-line -bindkey ' ' magic-space # also do history expansion on space - -bindkey "^[[1;5C" forward-word -bindkey "^[[1;5D" backward-word +bindkey -s '^[l' 'ls ' # show dir content bindkey '^[[Z' reverse-menu-complete +bindkey -M vicmd 'v' edit-command-line + +# delay after ESC (in 0.01s) +export KEYTIMEOUT=40 + +# emacs bindings +bindkey '^A' beginning-of-line +bindkey '^B' backward-char +bindkey '^E' end-of-line +bindkey '^F' edit-command-line +bindkey '^G' list-expand +bindkey '^O' accept-line-and-down-history +bindkey '^Q' push-input +bindkey '^?' backward-delete-char +bindkey '^H' backward-delete-char +bindkey '^W' backward-kill-word +bindkey '^X=' what-cursor-position +bindkey '^[.' insert-last-word +bindkey '^[?' which-command +bindkey '^[A' accept-and-hold +bindkey '^[a' accept-and-hold +bindkey '^[C' capitalize-word +bindkey '^[c' capitalize-word +bindkey '^[H' run-help +bindkey '^[h' run-help +bindkey '^[T' transpose-words +bindkey '^[t' transpose-words + +# make search up and down work, so partially type and hit up/down to find relevant stuff +bindkey '^[[A' up-line-or-search # up arrow +bindkey '^[[B' down-line-or-search # down arrow +bindkey '^[[5~' up-line-or-history # PgUp +bindkey '^[[6~' down-line-or-history # PgDown + +bindkey '^[OA' up-line-or-history +bindkey '^[OB' down-line-or-history +bindkey '^[OC' forward-char +bindkey '^[OD' backward-char +bindkey '^[OF' end-of-line +bindkey '^[OH' beginning-of-line + +bindkey '' forward-word +bindkey '' backward-word + # Make the delete key (or Fn + Delete on the Mac) work instead of outputting a ~ bindkey '^?' backward-delete-char -bindkey "^[[3~" delete-char -bindkey "^[3;5~" delete-char -bindkey "\e[3~" delete-char +bindkey '^[[3~' delete-char +bindkey '^[3;5~' delete-char +bindkey '\e[3~' delete-char diff --git a/zsh/lib/git.zsh b/zsh/lib/git.zsh deleted file mode 100644 index bffd284..0000000 --- a/zsh/lib/git.zsh +++ /dev/null @@ -1,100 +0,0 @@ -# get the name of the branch we are on -function git_prompt_info() { - ref=$(git symbolic-ref HEAD 2> /dev/null) || \ - ref=$(git rev-parse --short HEAD 2> /dev/null) || return - echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_SUFFIX" -} - - -# Checks if working tree is dirty -parse_git_dirty() { - if [[ -n $(git status -s 2> /dev/null) ]]; then - echo "$ZSH_THEME_GIT_PROMPT_DIRTY" - else - echo "$ZSH_THEME_GIT_PROMPT_CLEAN" - fi -} - -# get the difference between the local and remote branches -git_remote_status() { - remote=${$(git rev-parse --verify ${hook_com[branch]}@{upstream} --symbolic-full-name 2>/dev/null)/refs\/remotes\/} - if [[ -n ${remote} ]] ; then - ahead=$(git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l) - behind=$(git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l) - - if [ $ahead -eq 0 ] && [ $behind -gt 0 ] - then - echo "$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE" - elif [ $ahead -gt 0 ] && [ $behind -eq 0 ] - then - echo "$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE" - elif [ $ahead -gt 0 ] && [ $behind -gt 0 ] - then - echo "$ZSH_THEME_GIT_PROMPT_DIVERGED_REMOTE" - fi - fi -} - -# Checks if there are commits ahead from remote -function git_prompt_ahead() { - if $(echo "$(git log origin/$(current_branch)..HEAD 2> /dev/null)" | grep '^commit' &> /dev/null); then - echo "$ZSH_THEME_GIT_PROMPT_AHEAD" - fi -} - -# Formats prompt string for current git commit short SHA -function git_prompt_short_sha() { - SHA=$(git rev-parse --short HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER" -} - -# Formats prompt string for current git commit long SHA -function git_prompt_long_sha() { - SHA=$(git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER" -} - -# Get the status of the working tree -git_prompt_status() { - INDEX=$(git status --porcelain -b 2> /dev/null) - STATUS="" - if $(echo "$INDEX" | grep '^?? ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_UNTRACKED$STATUS" - fi - if $(echo "$INDEX" | grep '^A ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS" - elif $(echo "$INDEX" | grep '^M ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS" - fi - if $(echo "$INDEX" | grep '^ M ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS" - elif $(echo "$INDEX" | grep '^AM ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS" - elif $(echo "$INDEX" | grep '^ T ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS" - fi - if $(echo "$INDEX" | grep '^R ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_RENAMED$STATUS" - fi - if $(echo "$INDEX" | grep '^ D ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS" - elif $(echo "$INDEX" | grep '^D ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS" - elif $(echo "$INDEX" | grep '^AD ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS" - fi - if $(git rev-parse --verify refs/stash >/dev/null 2>&1); then - STATUS="$ZSH_THEME_GIT_PROMPT_STASHED$STATUS" - fi - if $(echo "$INDEX" | grep '^UU ' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_UNMERGED$STATUS" - fi - if $(echo "$INDEX" | grep '^## .*ahead' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_AHEAD$STATUS" - fi - if $(echo "$INDEX" | grep '^## .*behind' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_BEHIND$STATUS" - fi - if $(echo "$INDEX" | grep '^## .*diverged' &> /dev/null); then - STATUS="$ZSH_THEME_GIT_PROMPT_DIVERGED$STATUS" - fi - echo $STATUS -} diff --git a/zsh/lib/prompt.zsh b/zsh/lib/prompt.zsh new file mode 100644 index 0000000..4f31348 --- /dev/null +++ b/zsh/lib/prompt.zsh @@ -0,0 +1,112 @@ +hostcolor=green +[[ $(hostname) == "tardis" ]] && hostcolor=red + +precmd() { + PROMPT='%T %n@%{$fg[$hostcolor]%}%m%{$reset_color%}%-0>..>$(git_prompt_status)%>> +%(?..%{$fg_bold[white]%}%?%{$reset_color%})$(vi_prompt_info)%{%(!.$fg[red]❰.$fg[green]❱)%1G%} ' + RPROMPT='%{$fg[green]%}%~%{$reset_color%}' +} + +vi_prompt_info() { + local vicmd="$fg_bold[green]❰$reset_color%1G" + local viins="$fg_bold[blue]❱$reset_color%1G" + printf '%s' "%{${${KEYMAP/vicmd/$vicmd}/(main|viins)/$viins}%}" +} + +function zle-line-init zle-line-finish zle-keymap-select { + zle reset-prompt + zle -R +} + +zle -N zle-line-init +zle -N zle-line-finish +zle -N zle-keymap-select + +# reset zle on resize +TRAPWINCH() { + zle && { zle reset-prompt; zle -R } +} + +# Get the status of the working tree +git_prompt_status() { + local branch ahead behind + local added deleted modified renamed unmerged untracked dirty + # Use porcelain status for easy parsing. + local status_cmd="git status --porcelain -b" + + # Get current status. + while IFS=$'\n' read line; do + if [[ "$line" == \#\#\ * ]]; then + [[ "$line" =~ '## ([^.]*)\.\.\.(.*)' ]] && branch=$match[1] + [[ "$line" =~ 'ahead ([0-9]+)' ]] && ahead=$match[1] + [[ "$line" =~ 'behind ([0-9]+)' ]] && behind=$match[1] + else + # Count added, deleted, modified, renamed, unmerged, untracked, dirty. + # T (type change) is undocumented, see http://git.io/FnpMGw. + # index + [[ "$line" == M[\ MTD]\ * ]] && (( updated++ )) + [[ "$line" == [AC][\ MTD]\ * ]] && (( added++ )) + [[ "$line" == D[\ MT]\ * ]] && (( deleted++ )) + [[ "$line" == R[\ MTD]\ * ]] && (( renamed++ )) + + # work tree + [[ "$line" == [\ MARCT]M\ * ]] && (( modified++ )) + [[ "$line" == [\ MARCT]D\ * ]] && (( deleted_wt++ )) + [[ "$line" == \?\?\ * ]] && (( untracked++ )) + + # morge conflicts + [[ "$line" == (AA|DD|U?|?U)\ * ]] && (( unmerged++ )) + fi + done < <(${(z)status_cmd} 2> /dev/null) + + local git_status=" %{$fg[yellow]%}" + + # Format branch + if [[ -n $branch ]]; then + git_status+="$branch" + else + git_status+="$(git rev-parse --short HEAD 2> /dev/null)" + [[ $? -ne 0 ]] && return + fi + + # Format upstream + local upstream_str + (( ahead > 0 )) && upstream_str+="%{$fg[blue]%} >$ahead" + (( behind > 0 )) && upstream_str+="%{$fg[blue]%} <$behind" + git_status+="$upstream_str" + + # Format stashed + stashed=$(git stash list | wc -l) + if (( stashed > 0 )) then + stashed_str+="%{$fg_bold[cyan]%} ⋎$stashed%{$reset_color%}" + fi + git_status+="$stashed_str" + + # Format index + local index_str + (( updated > 0 )) && index_str+="%{$fg[green]%} *$updated" + (( added > 0 )) && index_str+="%{$fg[green]%} +$added" + (( deleted > 0 )) && index_str+="%{$fg[green]%} -$deleted" + (( renamed > 0 )) && index_str+="%{$fg[green]%} ≈$renamed" + git_status+="$index_str" + + # Format working tree + local wt_str + (( modified > 0 )) && wt_str+="%{$fg[red]%} *$modified" + (( deleted_wt > 0 )) && wt_str+="%{$fg[red]%} -$deleted_wt" + (( untracked > 0 )) && wt_str+="%{$fg[red]%} +$untracked" + (( unmerged > 0 )) && wt_str+="%{$fg[magenta]%} ♒$unmerged" + git_status+="$wt_str" + + git_status+="%{$reset_color%}" + + echo $git_status +} + +function print_if_fits() { + local zero length + + zero='%([BSUbfksu]|([FB]|){*})' + length=${#${(S%%)1//$~zero/}} + echo "%-$length(l.$1.)" +} diff --git a/zsh/themes/ramsi.zsh-theme b/zsh/themes/ramsi.zsh-theme deleted file mode 100644 index 8964a07..0000000 --- a/zsh/themes/ramsi.zsh-theme +++ /dev/null @@ -1,9 +0,0 @@ -[[ $(hostname) == "tardis" ]] && hostcolor=red -[[ $(hostname) == "shada" ]] && hostcolor=green -PROMPT='%(?..%{$fg_bold[white]%}[%?])%{$reset_color%}[%D{%k:%M} %n@%{$fg[$hostcolor]%}%m%{$reset_color%}$(git_prompt_info)]%# ' -RPROMPT='%{$fg[green]%}%~%{$reset_color%}' - -ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[yellow]%}<" -ZSH_THEME_GIT_PROMPT_SUFFIX=">%{$reset_color%}" -ZSH_THEME_GIT_PROMPT_DIRTY="*" -ZSH_THEME_GIT_PROMPT_CLEAN=""