فهرست منبع

fix vi-mode overwriting historical lines and add repo name to git info

Weiyi Lou 13 سال پیش
والد
کامیت
4959383a09
2فایلهای تغییر یافته به همراه66 افزوده شده و 17 حذف شده
  1. 39 17
      zsh/oh-my-zsh-custom/cinaeco.zsh-theme
  2. 27 0
      zsh/oh-my-zsh-custom/plugins/vi-mode/vi-mode.plugin.zsh

+ 39 - 17
zsh/oh-my-zsh-custom/cinaeco.zsh-theme

@@ -1,11 +1,32 @@
 ## Override the default `git_prompt_info` function
+## We decide if we show nothing, status with no branch (like in submodules) or
+## with a branch using regex comparisons. Is there a better way?
 function git_prompt_info() {
-  ref=$(git symbolic-ref HEAD 2> /dev/null) || return
-  echo "$(git_prompt_status) $(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_PREFIX$(current_branch)$ZSH_THEME_GIT_PROMPT_SUFFIX"
+  ref=$(git symbolic-ref HEAD 2>&1)
+  [[ $ref =~ "Not a git" ]] && return
+  [[ $ref =~ "not a symbolic" ]] && echo "$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_PREFIX$(current_repository):%{$fg[red]%}no branch$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_SUFFIX $(git_prompt_status)" && return
+  echo "$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_PREFIX$(current_repository):$(current_branch)$ZSH_THEME_GIT_PROMPT_SUFFIX $(git_prompt_status)"
+}
 
+## Override the default `current_repository` function
+## We don't need to test if HEAD is a symbolic ref - that gets controlled in
+## git_prompt_info(). Unlike `current_branch` there are no oh-my-zsh shortcuts
+## that will be broken if we don't test for this.
+##
+## also, the built-in function cannot cope with non-ssh repos because it relies
+## on there being a ':' before the repo name
+function current_repository() {
+  echo $(git remote -v | head -1 | grep -o '[^/]*\.git' | sed 's/.git//')
 }
 
+ZSH_THEME_GIT_PROMPT_PREFIX="[git:"
+ZSH_THEME_GIT_PROMPT_SUFFIX="]%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}"
+
 ## Override the default `git_prompt_status` function
+## This one will try to print a symbol for each change listed in git status.
+## The old version only listed if each type existed or not.
 git_prompt_status() {
   INDEX=$(git status -s 2> /dev/null)
   STATUS=""
@@ -40,6 +61,13 @@ git_prompt_status() {
   echo $STATUS
 }
 
+ZSH_THEME_GIT_PROMPT_ADDED="%{$FG[082]%}+%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$FG[160]%}+%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$FG[160]%}x%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$FG[220]%}>%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$FG[082]%}u%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$FG[160]%}?%{$reset_color%}"
+
 # Using precmd instead of having a multiline prompt reduces the number of 
 # `%{` and `%}` escape sequences needed. Actions like changing mode in vi-mode
 # and using tab completion need the escapes to know the right number of printed
@@ -50,25 +78,19 @@ git_prompt_status() {
 # new prompt not based on precmd, found that prompt renders half a second faster
 # which is much less annoying over prolonged usage. Have moved git status to the
 # right prompt. Less exciting, but more functional. Drats.
+#
+# UPDATE2: have found a modification to the vi-mode plugin that allows for
+# better catering for multiline prompts, without overwriting history lines.
+# Refer to custom directory for more details
 #function precmd() {}
 
 ## Set tab title to hostname
 print -Pn "\e]1;`hostname | cut -d. -f1`\a"
 
-PROMPT='%{$fg[cyan]%}[%n@%m] %{$fg[yellow]%}%3~ %{$fg[magenta]%}→ %{$reset_color%}'
-RPROMPT='$(vi_mode_prompt_info) $(git_prompt_info) %{$reset_color%}%T %{$fg[white]%}%h%{$reset_color%}'
-
-MODE_INDICATOR="%{$fg[green]%}vi-mode%{$reset_color%}"
-
-ZSH_THEME_GIT_PROMPT_PREFIX="[git:"
-ZSH_THEME_GIT_PROMPT_SUFFIX="]%{$reset_color%}"
-ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[green]%}"
-ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}"
+PROMPT='
+%{$fg[cyan]%}[%m]  %{$fg[yellow]%}%3~  $(git_prompt_info) 
+%{$fg[magenta]%}%n %{$fg[magenta]%}→ %{$reset_color%}'
 
+RPROMPT='$(vi_mode_prompt_info) %{$reset_color%}%T %{$fg[white]%}%h%{$reset_color%}'
 
-ZSH_THEME_GIT_PROMPT_ADDED="%{$FG[082]%}+%{$reset_color%}"
-ZSH_THEME_GIT_PROMPT_MODIFIED="%{$FG[160]%}+%{$reset_color%}"
-ZSH_THEME_GIT_PROMPT_DELETED="%{$FG[160]%}x%{$reset_color%}"
-ZSH_THEME_GIT_PROMPT_RENAMED="%{$FG[220]%}>%{$reset_color%}"
-ZSH_THEME_GIT_PROMPT_UNMERGED="%{$FG[082]%}u%{$reset_color%}"
-ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$FG[160]%}?%{$reset_color%}"
+MODE_INDICATOR="%{$fg[green]%}vi-mode%{$reset_color%}"

+ 27 - 0
zsh/oh-my-zsh-custom/plugins/vi-mode/vi-mode.plugin.zsh

@@ -0,0 +1,27 @@
+#
+# This plugin is modified to work better with multiline prompts. The problem
+# and solutions are described in
+# https://github.com/robbyrussell/oh-my-zsh/pull/597
+# (basically, zle-line-init is taken out)
+#
+function zle-keymap-select {
+  zle reset-prompt
+}
+
+zle -N zle-keymap-select
+
+bindkey -v
+
+# if mode indicator wasn't setup by theme, define default
+if [[ "$MODE_INDICATOR" == "" ]]; then
+  MODE_INDICATOR="%{$fg_bold[red]%}<%{$fg[red]%}<<%{$reset_color%}"
+fi
+
+function vi_mode_prompt_info() {
+  echo "${${KEYMAP/vicmd/$MODE_INDICATOR}/(main|viins)/}"
+}
+
+# define right prompt, if it wasn't defined by a theme
+if [[ "$RPS1" == "" && "$RPROMPT" == "" ]]; then
+  RPS1='$(vi_mode_prompt_info)'
+fi