188 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			188 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| prompt_fresh_help() {
 | |
|   echo "\
 | |
| options:
 | |
|         -a      enable almostontop like behaviour
 | |
|         -r      recompile git-prompt executable"
 | |
| }
 | |
| 
 | |
| prompt_fresh_setup() {
 | |
|   # Parse options
 | |
|   local almostontop=0
 | |
|   local recompile=0
 | |
|   while getopts 'ar' opt; do
 | |
|     case $opt in
 | |
|       a) local almostontop=1 ;;
 | |
|       r) local recompile=1 ;;
 | |
|       *) prompt -h fresh; return 1 ;;
 | |
|     esac
 | |
|   done
 | |
| 
 | |
|   autoload -U add-zsh-hook
 | |
| 
 | |
|   # Hook to print the first line of the "two line" prompt, this line is not
 | |
|   # actually part of the prompt so does not get redrawn, this is preferable
 | |
|   # since sometimes lines before the prompt can disappear.
 | |
|   add-zsh-hook precmd fresh_line_one
 | |
| 
 | |
|   if [ $almostontop -eq 1 ]; then
 | |
|     # Hook to clear the screen then prints the prompt with previous command at
 | |
|     # the top of the screen.
 | |
|     add-zsh-hook precmd fresh_almostontop_precmd
 | |
|     add-zsh-hook preexec fresh_almostontop_preexec
 | |
|   else
 | |
|     add-zsh-hook -d preexec fresh_almostontop_preexec
 | |
|     add-zsh-hook -d precmd fresh_almostontop_precmd
 | |
|   fi
 | |
| 
 | |
|   [ $recompile -eq 1 ] && prompt_cleanup
 | |
|   fresh_compile_git_prompt
 | |
| 
 | |
|   if [ "$USER" = "root" ]; then
 | |
|     local user="%{%F{1}%}%n%{%f%}"
 | |
|   else
 | |
|     local user="%{%F{35}%}%n%{%f%}"
 | |
|   fi
 | |
| 
 | |
|   local userhost=$USER
 | |
|   if [ "$SSH_CONNECTION" != "" ] || [ "$DISTROBOX_ENTER_PATH" != "" ]; then
 | |
|     local user="$user@%{%F{244}%}%M%{%f%}"
 | |
|     local userhost="$userhost@`hostname`"
 | |
|   fi
 | |
| 
 | |
|   PS1="«$user» "
 | |
|   PS2="«${(l:${#userhost}:: :)}» "
 | |
| 
 | |
|   prompt_opts=(percent sp subst)
 | |
| }
 | |
| 
 | |
| prompt_cleanup() {
 | |
|   [ -f ~/.cache/zsh/git-prompt ] && rm ~/.cache/zsh/git-prompt
 | |
| }
 | |
| 
 | |
| fresh_line_one() {
 | |
|   # First get the last commands exit code before doing anything
 | |
|   local exit_code=$?
 | |
| 
 | |
|   # Construct the time and directory portions of the prompt
 | |
|   local time_stamp="%{%F{244}%}%D{%H:%M:%S}%{%f%}"
 | |
|   [[ -n $SANDBOX_HOME ]] && \
 | |
|     local directory="%{%F{3}%}$SANDBOX_NAME${PWD#$SANDBOX_HOME}%{%f%}" || \
 | |
|     local directory="%{%F{37}%}%~%{%f%}"
 | |
| 
 | |
|   # Check we are in a git repository
 | |
|   local git=`~/.cache/zsh/git-prompt`
 | |
| 
 | |
|   # If the last command failed, display its error code at the right
 | |
|   if [[ $exit_code -ne 0 ]]; then
 | |
|     case $exit_code in
 | |
|       129) exit_code="SIGHUP"     ;;  # 128 + 1
 | |
|       130) exit_code="SIGINT"     ;;  # 128 + 2
 | |
|       131) exit_code="SIGQUIT"    ;;  # 128 + 3
 | |
|       132) exit_code="SIGILL"     ;;  # 128 + 4
 | |
|       133) exit_code="SIGTRAP"    ;;  # 128 + 5
 | |
|       134) exit_code="SIGABRT"    ;;  # 128 + 6
 | |
|       134) exit_code="SIGIOT"     ;;  # 128 + 6
 | |
|       135) exit_code="SIGBUS"     ;;  # 128 + 7
 | |
|       136) exit_code="SIGFPE"     ;;  # 128 + 8
 | |
|       137) exit_code="SIGKILL"    ;;  # 128 + 9
 | |
|       138) exit_code="SIGUSR1"    ;;  # 128 + 10
 | |
|       139) exit_code="SIGSEGV"    ;;  # 128 + 11
 | |
|       140) exit_code="SIGUSR2"    ;;  # 128 + 12
 | |
|       141) exit_code="SIGPIPE"    ;;  # 128 + 13
 | |
|       142) exit_code="SIGALRM"    ;;  # 128 + 14
 | |
|       143) exit_code="SIGTERM"    ;;  # 128 + 15
 | |
|       144) exit_code="SIGSTKFLT"  ;;  # 128 + 16
 | |
|       145) exit_code="SIGCHLD"    ;;  # 128 + 17
 | |
|       146) exit_code="SIGCONT"    ;;  # 128 + 18
 | |
|       147) exit_code="SIGSTOP"    ;;  # 128 + 19
 | |
|       148) exit_code="SIGTSTP"    ;;  # 128 + 20
 | |
|       149) exit_code="SIGTTIN"    ;;  # 128 + 21
 | |
|       150) exit_code="SIGTTOU"    ;;  # 128 + 22
 | |
|       151) exit_code="SIGURG"     ;;  # 128 + 23
 | |
|       152) exit_code="SIGXCPU"    ;;  # 128 + 24
 | |
|       153) exit_code="SIGXFSZ"    ;;  # 128 + 25
 | |
|       154) exit_code="SIGVTALRM"  ;;  # 128 + 26
 | |
|       155) exit_code="SIGPROF"    ;;  # 128 + 27
 | |
|       156) exit_code="SIGWINCH"   ;;  # 128 + 28
 | |
|       157) exit_code="SIGIO"      ;;  # 128 + 29
 | |
|       158) exit_code="SIGPWR"     ;;  # 128 + 30
 | |
|       159) exit_code="SIGSYS"     ;;  # 128 + 31
 | |
|     esac
 | |
|     local result=" %{%B%F{1}%}$exit_code%{%f%b%}"
 | |
|   fi
 | |
| 
 | |
|   # Unset vim/tmux navigate flag to handle C-z and multiple vim jobs.
 | |
|   [[ ! -z "$TMUX" ]] && \
 | |
|     [[ "`tmux show-window-options`" = *"@vim$TMUX_PANE"* ]] && \
 | |
|       tmux set-window-option -u @vim$TMUX_PANE
 | |
| 
 | |
|   # If a virtualenv is enabled, display it's basename
 | |
|   if [[ ! -z "$VIRTUAL_ENV" ]]; then
 | |
|     local py=" %{%F{4}%}py%{%f%}%{%F{3}%}$(basename $VIRTUAL_ENV)%{%f%}"
 | |
|   fi
 | |
| 
 | |
|   # If docker-machine env is active, display the machines name
 | |
|   if [[ ! -z "$DOCKER_MACHINE_NAME" ]]; then
 | |
|     local docker=" %{%F{6}%}$DOCKER_MACHINE_NAME%{%f%}"
 | |
|   fi
 | |
| 
 | |
|   # Print the first line of the prompt
 | |
|   print -P "$time_stamp $directory$git$py$docker$result"
 | |
| }
 | |
| 
 | |
| # Executed before each prompt.
 | |
| fresh_almostontop_precmd() {
 | |
|   # CSI ESC[6n gets the cursor position in the form ESC[<row>;<column>R
 | |
|   printf "\033[6n"
 | |
|   # Discard prefix delimited by [
 | |
|   read -s -d [
 | |
|   # Store the <row> delimited by ; in row_before
 | |
|   read -s -d \; row_before
 | |
|   # Discard suffix delimted by R otherwise it is output to the tty
 | |
|   read -s -d R
 | |
| }
 | |
| 
 | |
| # Executed just after a command has been read and is about to be executed.
 | |
| fresh_almostontop_preexec() {
 | |
|   # CSI ESC[6n gets the cursor position in the form ESC[<row>;<column>R
 | |
|   printf "\033[6n"
 | |
|   # Discard prefix delimited by [
 | |
|   read -s -d [
 | |
|   # Store the <row> delimited by ; in row
 | |
|   read -s -d \; row
 | |
|   # Discard suffix delimted by R otherwise it is output to the tty
 | |
|   read -s -d R
 | |
|   # Move the cursor to the bottom of the terminal
 | |
|   # CSI ESC[<num>B moves the cursor down <num> lines
 | |
|   let "down = $LINES - $row"
 | |
|   printf "\033[${down}B"
 | |
|   # Calculate the number of lines in the prompt
 | |
|   let "prompt_lines = ($row - $row_before) + 2"
 | |
|   # Print new lines to push the old command out of view
 | |
|   let "new = $row - $prompt_lines"
 | |
|   for (( i = 0; i < $new; i++ )); do
 | |
|     printf "\n"
 | |
|   done
 | |
|   # Move the cursor to the line below the prompt
 | |
|   # CSI ESC[<num>A moves the cursor up <num> lines
 | |
|   let "up = $LINES - $prompt_lines"
 | |
|   printf "\033[${up}A"
 | |
| }
 | |
| 
 | |
| fresh_compile_git_prompt() {
 | |
|   # Compile a simple C program which parses the output of `git status
 | |
|   # --procelain` to greatly decrease the time taken to draw the prompt
 | |
|   [ ! -d ~/.cache/zsh ] && mkdir -p ~/.cache/zsh
 | |
|   if [ ! -f ~/.cache/zsh/git-prompt ]; then
 | |
|     cc -std=gnu99 -O3 -DNDEBUG -Wno-unused-result \
 | |
|       ~/.config/zsh/git-prompt.c -o ~/.cache/zsh/git-prompt
 | |
|     if [ $? -ne 0 ]; then
 | |
|       echo "git-prompt was not compiled, is a C99 toolchain installed?"
 | |
|     fi
 | |
|   fi
 | |
| }
 | |
| 
 | |
| prompt_fresh_setup "$@"
 | |
| 
 | |
| # vim:ft=zsh
 |