diff --git a/.config/zsh/themes/agnoster.zsh-theme b/.config/zsh/themes/agnoster.zsh-theme index 0c882bd..7df5a23 100644 --- a/.config/zsh/themes/agnoster.zsh-theme +++ b/.config/zsh/themes/agnoster.zsh-theme @@ -1,5 +1,3 @@ -#!/bin/bash - # vim:ft=zsh ts=2 sw=2 sts=2 # # agnoster's Theme - https://gist.github.com/3712874 @@ -8,10 +6,7 @@ # # README # # In order for this theme to render correctly, you will need a -# [Powerline-patched font](https://github.com/Lokaltog/powerline-fonts). -# Make sure you have a recent version: the code points that Powerline -# uses changed in 2012, and older versions will display incorrectly, -# in confusing ways. +# [Powerline-patched font](https://gist.github.com/1595572). # # In addition, I recommend the # [Solarized theme](https://github.com/altercation/solarized/) and, if you're @@ -27,27 +22,33 @@ # jobs are running in this shell will all be displayed automatically when # appropriate. +### Segments of the prompt, default order declaration + +typeset -aHg AGNOSTER_PROMPT_SEGMENTS=( + prompt_status + prompt_context + prompt_virtualenv + prompt_dir + prompt_git + prompt_end +) + ### Segment drawing # A few utility functions to make it easy and re-usable to draw segmented prompts CURRENT_BG='NONE' - -# Special Powerline characters - -() { - local LC_ALL="" LC_CTYPE="en_US.UTF-8" - # NOTE: This segment separator character is correct. In 2012, Powerline changed - # the code points they use for their special characters. This is the new code point. - # If this is not working for you, you probably have an old version of the - # Powerline-patched fonts installed. Download and install the new version. - # Do not submit PRs to change this unless you have reviewed the Powerline code point - # history and have new information. - # This is defined using a Unicode escape sequence so it is unambiguously readable, regardless of - # what font the user is viewing this source code in. Do not replace the - # escape sequence with a single literal character. - # Do not change this! Do not make it '\u2b80'; that is the old, wrong code point. - SEGMENT_SEPARATOR=$'\ue0b0' -} +if [[ -z "$PRIMARY_FG" ]]; then + PRIMARY_FG=black +fi + +# Characters +SEGMENT_SEPARATOR="\ue0b0" +PLUSMINUS="\u00b1" +BRANCH="\ue0a0" +DETACHED="\u27a6" +CROSS="\u2718" +LIGHTNING="\u26a1" +GEAR="\u2699" # Begin a segment # Takes two arguments, background and foreground. Both can be omitted, @@ -57,22 +58,22 @@ prompt_segment() { [[ -n $1 ]] && bg="%K{$1}" || bg="%k" [[ -n $2 ]] && fg="%F{$2}" || fg="%f" if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then - echo -n " %{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%} " + print -n "%{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%}" else - echo -n "%{$bg%}%{$fg%} " + print -n "%{$bg%}%{$fg%}" fi CURRENT_BG=$1 - [[ -n $3 ]] && echo -n $3 + [[ -n $3 ]] && print -n $3 } # End the prompt, closing any open segments prompt_end() { if [[ -n $CURRENT_BG ]]; then - echo -n " %{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR" + print -n "%{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR" else - echo -n "%{%k%}" + print -n "%{%k%}" fi - echo -n "%{%f%}" + print -n "%{%f%}" CURRENT_BG='' } @@ -81,123 +82,41 @@ prompt_end() { # Context: user@hostname (who am I and where am I) prompt_context() { - if [[ "$USER" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then - prompt_segment black default "%(!.%{%F{yellow}%}.)$USER" + local user=`whoami` + + if [[ "$user" != "$DEFAULT_USER" || -n "$SSH_CONNECTION" ]]; then + prompt_segment $PRIMARY_FG default " %(!.%{%F{yellow}%}.)$user@%m " fi } # Git: branch/detached head, dirty status prompt_git() { - (( $+commands[git] )) || return - local PL_BRANCH_CHAR - () { - local LC_ALL="" LC_CTYPE="en_US.UTF-8" - PL_BRANCH_CHAR=$'\ue0a0' #  + local color ref + is_dirty() { + test -n "$(git status --porcelain --ignore-submodules)" } - local ref dirty mode repo_path - repo_path=$(git rev-parse --git-dir 2>/dev/null) - - if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then - dirty=$(parse_git_dirty) - ref=$(git symbolic-ref HEAD 2> /dev/null) || ref="➦ $(git rev-parse --short HEAD 2> /dev/null)" - if [[ -n $dirty ]]; then - prompt_segment yellow black + ref="$vcs_info_msg_0_" + if [[ -n "$ref" ]]; then + if is_dirty; then + color=yellow + ref="${ref} $PLUSMINUS" else - prompt_segment green black - fi - - if [[ -e "${repo_path}/BISECT_LOG" ]]; then - mode=" " - elif [[ -e "${repo_path}/MERGE_HEAD" ]]; then - mode=" >M<" - elif [[ -e "${repo_path}/rebase" || -e "${repo_path}/rebase-apply" || -e "${repo_path}/rebase-merge" || -e "${repo_path}/../.dotest" ]]; then - mode=" >R>" + color=green + ref="${ref} " fi - - setopt promptsubst - autoload -Uz vcs_info - - zstyle ':vcs_info:*' enable git - zstyle ':vcs_info:*' get-revision true - zstyle ':vcs_info:*' check-for-changes true - zstyle ':vcs_info:*' stagedstr '✚' - zstyle ':vcs_info:*' unstagedstr '●' - zstyle ':vcs_info:*' formats ' %u%c' - zstyle ':vcs_info:*' actionformats ' %u%c' - vcs_info - echo -n "${ref/refs\/heads\//$PL_BRANCH_CHAR }${vcs_info_msg_0_%% }${mode}" - fi -} - -prompt_bzr() { - (( $+commands[bzr] )) || return - if (bzr status >/dev/null 2>&1); then - status_mod=`bzr status | head -n1 | grep "modified" | wc -m` - status_all=`bzr status | head -n1 | wc -m` - revision=`bzr log | head -n2 | tail -n1 | sed 's/^revno: //'` - if [[ $status_mod -gt 0 ]] ; then - prompt_segment yellow black - echo -n "bzr@"$revision "✚ " - else - if [[ $status_all -gt 0 ]] ; then - prompt_segment yellow black - echo -n "bzr@"$revision - - else - prompt_segment green black - echo -n "bzr@"$revision - fi - fi - fi -} - -prompt_hg() { - (( $+commands[hg] )) || return - local rev status - if $(hg id >/dev/null 2>&1); then - if $(hg prompt >/dev/null 2>&1); then - if [[ $(hg prompt "{status|unknown}") = "?" ]]; then - # if files are not added - prompt_segment red white - st='±' - elif [[ -n $(hg prompt "{status|modified}") ]]; then - # if any modification - prompt_segment yellow black - st='±' - else - # if working copy is clean - prompt_segment green black - fi - echo -n $(hg prompt "☿ {rev}@{branch}") $st + if [[ "${ref/.../}" == "$ref" ]]; then + ref="$BRANCH $ref" else - st="" - rev=$(hg id -n 2>/dev/null | sed 's/[^-0-9]//g') - branch=$(hg id -b 2>/dev/null) - if `hg st | grep -q "^\?"`; then - prompt_segment red black - st='±' - elif `hg st | grep -q "^[MA]"`; then - prompt_segment yellow black - st='±' - else - prompt_segment green black - fi - echo -n "☿ $rev@$branch" $st + ref="$DETACHED ${ref/.../}" fi + prompt_segment $color $PRIMARY_FG + print -n " $ref" fi } # Dir: current working directory prompt_dir() { - prompt_segment blue black '%~' -} - -# Virtualenv: current working virtualenv -prompt_virtualenv() { - local virtualenv_path="$VIRTUAL_ENV" - if [[ -n $virtualenv_path && -n $VIRTUAL_ENV_DISABLE_PROMPT ]]; then - prompt_segment blue black "(`basename $virtualenv_path`)" - fi + prompt_segment blue $PRIMARY_FG ' %~ ' } # Status: @@ -207,25 +126,49 @@ prompt_virtualenv() { prompt_status() { local symbols symbols=() - [[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘" - [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡" - [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙" + [[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}$CROSS" + [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}$LIGHTNING" + [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}$GEAR" - [[ -n "$symbols" ]] && prompt_segment black default "$symbols" + [[ -n "$symbols" ]] && prompt_segment $PRIMARY_FG default " $symbols " +} + +# Display current virtual environment +prompt_virtualenv() { + if [[ -n $VIRTUAL_ENV ]]; then + color=cyan + prompt_segment $color $PRIMARY_FG + print -Pn " $(basename $VIRTUAL_ENV) " + fi } ## Main prompt -build_prompt() { +prompt_agnoster_main() { RETVAL=$? - prompt_status - prompt_virtualenv - prompt_context - prompt_dir - prompt_git - prompt_bzr - prompt_hg - prompt_end + CURRENT_BG='NONE' + for prompt_segment in "${AGNOSTER_PROMPT_SEGMENTS[@]}"; do + [[ -n $prompt_segment ]] && $prompt_segment + done +} + +prompt_agnoster_precmd() { + vcs_info + PROMPT='%{%f%b%k%}$(prompt_agnoster_main) ' +} + +prompt_agnoster_setup() { + autoload -Uz add-zsh-hook + autoload -Uz vcs_info + + prompt_opts=(cr subst percent) + + add-zsh-hook precmd prompt_agnoster_precmd + + zstyle ':vcs_info:*' enable git + zstyle ':vcs_info:*' check-for-changes false + zstyle ':vcs_info:git*' formats '%b' + zstyle ':vcs_info:git*' actionformats '%b (%a)' } -PROMPT='%{%f%b%k%}$(build_prompt) ' +prompt_agnoster_setup "$@"