vim:ft=zsh ts=2 sw=2 sts=2

February 25, 2021 · View on GitHub

agnoster's Theme - https://gist.github.com/3712874

A Powerline-inspired theme for ZSH

# README

In order for this theme to render correctly, you will need a

Powerline-patched font.

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.

In addition, I recommend the

Solarized theme and, if you're

using it on Mac OS X, iTerm 2 over Terminal.app -

it has significantly better color fidelity.

# Goals

The aim of this theme is to only show you relevant information. Like most

prompts, it will only show git information when in a git working directory.

However, it goes a step further: everything from the current user and

hostname to whether the last call exited with an error to whether background

jobs are running in this shell will all be displayed automatically when

appropriate.

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' }

Begin a segment

Takes two arguments, background and foreground. Both can be omitted,

rendering default background/foreground.

prompt_segment() { local bg fg [[ -n $1 ]] && bg="%K{$1}" || bg="%k" [[ -n $2 ]] && fg="%F{$2}" || fg="%f" if [[ CURRENT_BG != 'NONE' && \1 != CURRENTBG]];thenechon"CURRENT_BG ]]; then echo -n " %{bg%F{CURRENT_BG}%}SEGMENT_SEPARATOR%{fgelseechon"fg%} " else echo -n "%{bg%}%{fg%} " fi CURRENT_BG=\1 [[ -n $3 ]] && echo -n $3 }

End the prompt, closing any open segments

prompt_end() { if [[ -n CURRENTBG]];thenechon"CURRENT_BG ]]; then echo -n " %{%k%F{CURRENT_BG}%}$SEGMENT_SEPARATOR" else echo -n "%{%k%}" fi echo -n "%{%f%}" CURRENT_BG='' }

Prompt components

Each component will draw itself, and hide itself if no information needs to be shown

Context: user@hostname (who am I and where am I)

prompt_context() { if [[ "USER"!="USER" != "DEFAULT_USER" || -n "SSHCLIENT"]];thenpromptsegmentblackdefault"SSH_CLIENT" ]]; then prompt_segment black default "%(!.%{%F{yellow}%}.)USER" 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 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=(gitsymbolicrefHEAD2>/dev/null)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 else prompt_segment green black fi

if [[ -e "${repo_path}/BISECT_LOG" ]]; then
  mode=" <B>"
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>"
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
local BRANCH_NAME="${ref/refs\/heads\/}${vcs_info_msg_0_%% }${mode}"
	if [[ "$BRANCH_NAME" =~ ^([A-Z]+-[0-9]+) ]]; then # shorten jira slugs
  echo -n "$PL_BRANCH_CHAR $match[1]\u2026"
		if [[ "$BRANCH_NAME" =~ " (.+)$" ]]; then
			echo -n " $match[1]"
		fi
	else
  echo -n "$PL_BRANCH_CHAR $BRANCH_NAME"
	fi

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""elseif[[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]))returnlocalrevstatusif+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}") stelsest=""rev=st else st="" rev=(hg id -n 2>/dev/null | sed 's/[^-0-9]//g') branch=(hgidb2>/dev/null)ifhgstgrepq"\?";thenpromptsegmentredblackst=±elifhgstgrepq"[MA]";thenpromptsegmentyellowblackst=±elsepromptsegmentgreenblackfiechon"(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"branch" st fi fi }

Dir: current working directory

prompt_dir() { if [[ -v CURRENT_PROJECT_DIR && -v CURRENT_PROJECT_NAME && PWD =~ "^CURRENT_PROJECT_DIR(.*)"]];thenpromptsegmentblueblack"" ]]; then prompt_segment blue black "CURRENT_PROJECT_NAME$match[1]" else prompt_segment blue black '%~' fi }

Virtualenv: current working virtualenv

prompt_virtualenv() { local virtualenv_path="VIRTUALENV"if[[nVIRTUAL_ENV" if [[ -n virtualenv_path && -n VIRTUALENVDISABLEPROMPT]];thenpromptsegmentblueblack"(basenameVIRTUAL_ENV_DISABLE_PROMPT ]]; then prompt_segment blue black "(`basename virtualenv_path`)" fi }

nix-shell: currently running nix-shell

prompt_nix_shell() { if [[ -n "INNIXSHELL"]];thenif[[nIN_NIX_SHELL" ]]; then if [[ -n NIX_SHELL_PACKAGES ]]; then local package_names="" local packages=(NIXSHELLPACKAGES)forpackageinNIX_SHELL_PACKAGES) for package in packages; do package_names+=" {package##*.}" done prompt_segment black yellow "{package_names }" elif [[ -n name]];thenlocalcleanName=name ]]; then local cleanName={name#interactive-} cleanName={cleanName#lorri-keep-env-hack-} cleanName={cleanName%-environment} prompt_segment black yellow "{ $cleanName }" else # This case is only reached if the nix-shell plugin isn't installed or failed in some way prompt_segment black yellow "nix-shell {}" fi fi }

Status:

- was there an error

- am I root

- are there background jobs?

prompt_status() { local symbols symbols=() [[ RETVAL -ne 0 && RETVAL -ne 1 ]] && symbols+="%{%F{red}%}RETVAL"[[RETVAL" [[ RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘" [[ UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡" [[ (jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙"

if [ {#symbols[@]} -ne 0 ]; then prompt_segment black default "symbols" fi }

Main prompt

build_prompt() { RETVAL=$? prompt_status prompt_nix_shell prompt_virtualenv prompt_context prompt_dir prompt_git prompt_bzr prompt_hg prompt_end }

PROMPT='%{%f%b%k%}$(build_prompt) '