├── README.md ├── agnoster.zsh-theme ├── agnoster_customization.gif ├── characters.png └── screenshot.png /README.md: -------------------------------------------------------------------------------- 1 | # agnoster.zsh-theme 2 | 3 | A ZSH theme optimized for people who use: 4 | 5 | - Solarized 6 | - Git 7 | - Unicode-compatible fonts and terminals (I use iTerm2 + Menlo) 8 | 9 | For Mac users, I highly recommend iTerm 2 + Solarized Dark 10 | 11 | # Compatibility 12 | 13 | **NOTE:** In all likelihood, you will need to install a [Powerline-patched font](https://github.com/Lokaltog/powerline-fonts) for this theme to render correctly. 14 | 15 | To test if your terminal and font support it, check that all the necessary characters are supported by copying the following command to your terminal: `echo "\ue0b0 \u00b1 \ue0a0 \u27a6 \u2718 \u26a1 \u2699"`. The result should look like this: 16 | 17 | ![Character Example](https://gist.githubusercontent.com/agnoster/3712874/raw/characters.png) 18 | 19 | ## What does it show? 20 | 21 | - If the previous command failed (✘) 22 | - User @ Hostname (if user is not DEFAULT_USER, which can then be set in your profile) 23 | - Git status 24 | - Branch () or detached head (➦) 25 | - Current branch / SHA1 in detached head state 26 | - Dirty working directory (±, color change) 27 | - Working directory 28 | - Elevated (root) privileges (⚡) 29 | 30 | ![Screenshot](https://gist.githubusercontent.com/agnoster/3712874/raw/screenshot.png) 31 | 32 | ## Customize your prompt view 33 | 34 | By default prompt has these segments: `prompt_status`, `prompt_context`, `prompt_virtualenv`, `prompt_dir`, `prompt_git`, `prompt_end` in that particular order. 35 | 36 | If you want to add, change the order or remove some segments of the prompt, you can use array environment variable named `AGNOSTER_PROMPT_SEGMENTS`. 37 | 38 | Examples: 39 | - Show all segments of the prompt with indices: 40 | ``` 41 | echo "${(F)AGNOSTER_PROMPT_SEGMENTS[@]}" | cat -n 42 | ``` 43 | - Add the new segment of the prompt to the beginning: 44 | ``` 45 | AGNOSTER_PROMPT_SEGMENTS=("prompt_git" "${AGNOSTER_PROMPT_SEGMENTS[@]}") 46 | ``` 47 | - Add the new segment of the prompt to the end: 48 | ``` 49 | AGNOSTER_PROMPT_SEGMENTS+="prompt_end" 50 | ``` 51 | - Insert the new segment of the prompt = `PROMPT_SEGMENT_NAME` on the particular position = `PROMPT_SEGMENT_POSITION`: 52 | ``` 53 | PROMPT_SEGMENT_POSITION=5 PROMPT_SEGMENT_NAME="prompt_end";\ 54 | AGNOSTER_PROMPT_SEGMENTS=("${AGNOSTER_PROMPT_SEGMENTS[@]:0:$PROMPT_SEGMENT_POSITION-1}" "$PROMPT_SEGMENT_NAME" "${AGNOSTER_PROMPT_SEGMENTS[@]:$PROMPT_SEGMENT_POSITION-1}");\ 55 | unset PROMPT_SEGMENT_POSITION PROMPT_SEGMENT_NAME 56 | ``` 57 | - Swap segments 4th and 5th: 58 | ``` 59 | SWAP_SEGMENTS=(4 5);\ 60 | TMP_VAR="$AGNOSTER_PROMPT_SEGMENTS[$SWAP_SEGMENTS[1]]"; AGNOSTER_PROMPT_SEGMENTS[$SWAP_SEGMENTS[1]]="$AGNOSTER_PROMPT_SEGMENTS[$SWAP_SEGMENTS[2]]"; AGNOSTER_PROMPT_SEGMENTS[$SWAP_SEGMENTS[2]]="$TMP_VAR" 61 | unset SWAP_SEGMENTS TMP_VAR 62 | ``` 63 | - Remove the 5th segment: 64 | ``` 65 | AGNOSTER_PROMPT_SEGMENTS[5]= 66 | ``` 67 | 68 | A small demo of the dummy custom prompt segment, which has been created with help of the built-in `prompt_segment()` function from Agnoster theme: 69 | ``` 70 | # prompt_segment() - Takes two arguments, background and foreground. 71 | # Both can be omitted, rendering default background/foreground. 72 | 73 | customize_agnoster() { 74 | prompt_segment 'red' '' ' ⚙ ⚡⚡⚡ ⚙ ' 75 | } 76 | ``` 77 | ![Customization demo](https://github.com/apodkutin/agnoster-zsh-theme/raw/customize-prompt/agnoster_customization.gif) 78 | 79 | ## Future Work 80 | 81 | I don't want to clutter it up too much, but I am toying with the idea of adding RVM (ruby version) and n (node.js version) display. 82 | 83 | It's currently hideously slow, especially inside a git repo. I guess it's not overly so for comparable themes, but it bugs me, and I'd love to hear ideas about how to improve the performance. 84 | 85 | Would be nice for the code to be a bit more sane and re-usable. Something to easily append a section with a given FG/BG, and add the correct opening and closing. 86 | 87 | Also the dependency on a powerline-patched font is regrettable, but there's really no way to get that effect without it. Ideally there would be a way to check for compatibility, or maybe even fall back to one of the similar unicode glyphs. 88 | -------------------------------------------------------------------------------- /agnoster.zsh-theme: -------------------------------------------------------------------------------- 1 | # vim:ft=zsh ts=2 sw=2 sts=2 2 | # 3 | # agnoster's Theme - https://gist.github.com/3712874 4 | # A Powerline-inspired theme for ZSH 5 | # 6 | # # README 7 | # 8 | # In order for this theme to render correctly, you will need a 9 | # [Powerline-patched font](https://gist.github.com/1595572). 10 | # 11 | # In addition, I recommend the 12 | # [Solarized theme](https://github.com/altercation/solarized/) and, if you're 13 | # using it on Mac OS X, [iTerm 2](http://www.iterm2.com/) over Terminal.app - 14 | # it has significantly better color fidelity. 15 | # 16 | # # Goals 17 | # 18 | # The aim of this theme is to only show you *relevant* information. Like most 19 | # prompts, it will only show git information when in a git working directory. 20 | # However, it goes a step further: everything from the current user and 21 | # hostname to whether the last call exited with an error to whether background 22 | # jobs are running in this shell will all be displayed automatically when 23 | # appropriate. 24 | 25 | ### Segments of the prompt, default order declaration 26 | 27 | typeset -aHg AGNOSTER_PROMPT_SEGMENTS=( 28 | prompt_status 29 | prompt_context 30 | prompt_virtualenv 31 | prompt_dir 32 | prompt_git 33 | prompt_end 34 | ) 35 | 36 | ### Segment drawing 37 | # A few utility functions to make it easy and re-usable to draw segmented prompts 38 | 39 | CURRENT_BG='NONE' 40 | if [[ -z "$PRIMARY_FG" ]]; then 41 | PRIMARY_FG=black 42 | fi 43 | 44 | # Characters 45 | SEGMENT_SEPARATOR="\ue0b0" 46 | PLUSMINUS="\u00b1" 47 | BRANCH="\ue0a0" 48 | DETACHED="\u27a6" 49 | CROSS="\u2718" 50 | LIGHTNING="\u26a1" 51 | GEAR="\u2699" 52 | 53 | # Begin a segment 54 | # Takes two arguments, background and foreground. Both can be omitted, 55 | # rendering default background/foreground. 56 | prompt_segment() { 57 | local bg fg 58 | [[ -n $1 ]] && bg="%K{$1}" || bg="%k" 59 | [[ -n $2 ]] && fg="%F{$2}" || fg="%f" 60 | if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then 61 | print -n "%{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%}" 62 | else 63 | print -n "%{$bg%}%{$fg%}" 64 | fi 65 | CURRENT_BG=$1 66 | [[ -n $3 ]] && print -n $3 67 | } 68 | 69 | # End the prompt, closing any open segments 70 | prompt_end() { 71 | if [[ -n $CURRENT_BG ]]; then 72 | print -n "%{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR" 73 | else 74 | print -n "%{%k%}" 75 | fi 76 | print -n "%{%f%}" 77 | CURRENT_BG='' 78 | } 79 | 80 | ### Prompt components 81 | # Each component will draw itself, and hide itself if no information needs to be shown 82 | 83 | # Context: user@hostname (who am I and where am I) 84 | prompt_context() { 85 | local user=`whoami` 86 | 87 | if [[ "$user" != "$DEFAULT_USER" || -n "$SSH_CONNECTION" ]]; then 88 | prompt_segment $PRIMARY_FG default " %(!.%{%F{yellow}%}.)$user@%m " 89 | fi 90 | } 91 | 92 | # Git: branch/detached head, dirty status 93 | prompt_git() { 94 | local color ref 95 | is_dirty() { 96 | test -n "$(git status --porcelain --ignore-submodules)" 97 | } 98 | ref="$vcs_info_msg_0_" 99 | if [[ -n "$ref" ]]; then 100 | if is_dirty; then 101 | color=yellow 102 | ref="${ref} $PLUSMINUS" 103 | else 104 | color=green 105 | ref="${ref} " 106 | fi 107 | if [[ "${ref/.../}" == "$ref" ]]; then 108 | ref="$BRANCH $ref" 109 | else 110 | ref="$DETACHED ${ref/.../}" 111 | fi 112 | prompt_segment $color $PRIMARY_FG 113 | print -n " $ref" 114 | fi 115 | } 116 | 117 | # Dir: current working directory 118 | prompt_dir() { 119 | prompt_segment blue $PRIMARY_FG ' %~ ' 120 | } 121 | 122 | # Status: 123 | # - was there an error 124 | # - am I root 125 | # - are there background jobs? 126 | prompt_status() { 127 | local symbols 128 | symbols=() 129 | [[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}$CROSS" 130 | [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}$LIGHTNING" 131 | [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}$GEAR" 132 | 133 | [[ -n "$symbols" ]] && prompt_segment $PRIMARY_FG default " $symbols " 134 | } 135 | 136 | # Display current virtual environment 137 | prompt_virtualenv() { 138 | if [[ -n $VIRTUAL_ENV ]]; then 139 | color=cyan 140 | prompt_segment $color $PRIMARY_FG 141 | print -Pn " $(basename $VIRTUAL_ENV) " 142 | fi 143 | } 144 | 145 | ## Main prompt 146 | prompt_agnoster_main() { 147 | RETVAL=$? 148 | CURRENT_BG='NONE' 149 | for prompt_segment in "${AGNOSTER_PROMPT_SEGMENTS[@]}"; do 150 | [[ -n $prompt_segment ]] && $prompt_segment 151 | done 152 | } 153 | 154 | prompt_agnoster_precmd() { 155 | vcs_info 156 | PROMPT='%{%f%b%k%}$(prompt_agnoster_main) ' 157 | } 158 | 159 | prompt_agnoster_setup() { 160 | autoload -Uz add-zsh-hook 161 | autoload -Uz vcs_info 162 | 163 | prompt_opts=(cr subst percent) 164 | 165 | add-zsh-hook precmd prompt_agnoster_precmd 166 | 167 | zstyle ':vcs_info:*' enable git 168 | zstyle ':vcs_info:*' check-for-changes false 169 | zstyle ':vcs_info:git*' formats '%b' 170 | zstyle ':vcs_info:git*' actionformats '%b (%a)' 171 | } 172 | 173 | prompt_agnoster_setup "$@" 174 | -------------------------------------------------------------------------------- /agnoster_customization.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agnoster/agnoster-zsh-theme/6bba672c7812a76defc3efed9b6369eeee2425dc/agnoster_customization.gif -------------------------------------------------------------------------------- /characters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agnoster/agnoster-zsh-theme/6bba672c7812a76defc3efed9b6369eeee2425dc/characters.png -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agnoster/agnoster-zsh-theme/6bba672c7812a76defc3efed9b6369eeee2425dc/screenshot.png --------------------------------------------------------------------------------