diff --git a/pure.bash b/pure.bash new file mode 100644 index 00000000..3d93d00a --- /dev/null +++ b/pure.bash @@ -0,0 +1,111 @@ +# Pure +# by Sindre Sorhus +# https://github.com/sindresorhus/pure +# MIT License + +# turns seconds into human readable time +# 165392 => 1d 21h 56m 32s +prompt_pure_human_time() { + local tmp=$1 + local days=$(( tmp / 60 / 60 / 24 )) + local hours=$(( tmp / 60 / 60 % 24 )) + local minutes=$(( tmp / 60 % 60 )) + local seconds=$(( tmp % 60 )) + (( $days > 0 )) && echo -n "${days}d " + (( $hours > 0 )) && echo -n "${hours}h " + (( $minutes > 0 )) && echo -n "${minutes}m " + echo "${seconds}s" +} + +# fastest possible way to check if repo is dirty +prompt_pure_git_dirty() { + # check if we're in a git repo + command git rev-parse --is-inside-work-tree &>/dev/null || return + # check if it's dirty + [[ "$PURE_GIT_UNTRACKED_DIRTY" == 0 ]] && local umode="-uno" || local umode="-unormal" + command test -n "$(git status --porcelain --ignore-submodules ${umode})" + + (($? == 0)) && echo '*' +} + +# displays the exec time of the last command if set threshold was exceeded +prompt_pure_cmd_exec_time() { + local stop=$SECONDS + local start=${cmd_timestamp:-$stop} + local elapsed=$(($stop-$start)) + (($elapsed > ${PURE_CMD_MAX_EXEC_TIME:=5})) && prompt_pure_human_time $elapsed +} + +prompt_pure_preexec() { + cmd_timestamp=${cmd_timestamp:-$SECONDS} + + local cwd=$(pwd | sed "s|^${HOME}|~|") + + local hist_ent="$(history 1)"; + local prev_hist_ent="${last_hist_ent}"; + local last_hist_ent="${hist_ent}"; + if [[ "${prev_hist_ent}" != "${hist_ent}" ]]; then + local this_command="$(echo "${hist_ent}" | sed -e "s/^[ ]*[0-9]*[ ]*//g")"; + else + local this_command=""; + fi; + + # shows the current dir and executed command in the title when a process is active + echo -en "\e]0;" + echo -nE "${cwd}: ${this_command}" + echo -en "\a" +} + +# string length ignoring ansi escapes +prompt_pure_string_length() { + echo ${#1} +} + +prompt_pure_precmd() { + local cwd=$(pwd | sed "s|^${HOME}|~|") + + # shows the full path in the title + echo -en "\e]0;${cwd}\a" + + local prompt_pure_preprompt="\n\033[0;34m${cwd} \033[0;37m$(__git_ps1 "%s")$(prompt_pure_git_dirty) $prompt_pure_username\033[0m \033[0;33m$(prompt_pure_cmd_exec_time)\033[0m" + echo -e $prompt_pure_preprompt + + # check async if there is anything to pull + (( ${PURE_GIT_PULL:-1} )) && ({ + # check if we're in a git repo + command git rev-parse --is-inside-work-tree &>/dev/null && + # check check if there is anything to pull + command git fetch &>/dev/null && + # check if there is an upstream configured for this branch + command git rev-parse --abbrev-ref @'{u}' &>/dev/null && { + local arrows='' + (( $(command git rev-list --right-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows='⇣' + (( $(command git rev-list --left-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows+='⇡' + echo -en "\e7\e[A\e[1G\e[$(prompt_pure_string_length $prompt_pure_preprompt)C\033[0;36m${arrows}\033[0m\e8" + } + } &) + + # reset value since `preexec` isn't always triggered + unset cmd_timestamp +} + +prompt_pure_exit_color() { + [[ "$?" = '0' ]] && echo -e "\033[0;37m" || echo -e "\033[0;31m" +} + +prompt_pure_setup() { + # prevent percentage showing up + # if output doesn't end with a newline + export PS2='' + + export PROMPT_COMMAND='prompt_pure_precmd' + trap 'prompt_pure_preexec' DEBUG + + # show username@host if logged in through SSH + [[ "$SSH_CONNECTION" != '' ]] && prompt_pure_username="${USER}@${HOSTNAME} " + + # prompt turns red if the previous command didn't exit with 0 + PS1='\[$(prompt_pure_exit_color)\]❯\[\033[0m\] ' +} + +prompt_pure_setup "$@" diff --git a/readme.md b/readme.md index 277a957c..311dc714 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # Pure -> Pretty, minimal and fast ZSH prompt +> Pretty, minimal and fast ZSH/Bash prompt ![screenshot](screenshot.png) @@ -11,7 +11,7 @@ Most prompts are cluttered, ugly and slow. I wanted something visually pleasing ### Why? -- Comes with the perfect prompt character. +- Comes with the perfect prompt character. Author went through the whole Unicode range to find it. - Shows `git` branch and whether it's dirty (with a `*`). - Indicates when you have unpushed/unpulled `git` commits with up/down arrows. @@ -36,6 +36,8 @@ That's it. Skip to [Getting started](#getting-started). ### Manually +### For zsh + 1. Either… - Clone this repo - add it as a submodule, or @@ -63,6 +65,14 @@ Then install the theme there: $ ln -s "$PWD/pure.zsh" "$HOME/.zfunctions/prompt_pure_setup" ``` +### For bash + +1. Either… + - Clone this repo + - add it as a submodule, or + - just download `pure.bash` + +2. Put it on anywhere you like. ## Getting started @@ -74,6 +84,10 @@ autoload -U promptinit && promptinit prompt pure ``` +```sh +# .bashrc +source "pure.bash" +``` ## Options @@ -102,6 +116,15 @@ PURE_CMD_MAX_EXEC_TIME=10 prompt pure ``` +```sh +# .bashrc + +# optionally define some options +PURE_CMD_MAX_EXEC_TIME=10 + +source "pure.bash" +``` + ## Tips