Up till now setting the `-a` flag of the `prompt_fresh_setup` theme resulted in duplicate prompts being printed to the terminal. The first, the interactive prompt with syntax highlighting, and a second after a call to the `clear` command without syntax highlighting. This patch replaces the old implementation with one which does not use `clear`. Instead it queries the terminal for the current cursor position, then uses this to move to the bottom of the terminal, print a number of new lines to move the stale command output off screen, and finally move almost back to the top ready for the invoked command to print it's output.
171 lines
5.4 KiB
Bash
171 lines
5.4 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 preexec fresh_almostontop
|
|
else
|
|
add-zsh-hook -d preexec fresh_almostontop
|
|
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" != "" ]; 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"
|
|
}
|
|
|
|
fresh_almostontop() {
|
|
# 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"
|
|
# Print new lines to push the old command out of view
|
|
let "new = $row - 3"
|
|
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 - 3"
|
|
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
|