mirror of
https://github.com/ItsDrike/dotfiles.git
synced 2024-12-28 14:14:33 +00:00
ItsDrike
02237fd0b1
- Re-reunning work_directory every time we redraw the prompt isn't necessary, since the function is here to generate the zsh supported syntax for the prompt that will get expanded into a work directory automatically. - The function is only here to determine whether we're in TTY and use ASCII compatible symbols if we are, however it is enough to only check this once initially, since we can't leave TTY in favor of a graphical instance without reloading the rc file and neither can we leave. - However, this function also checks for `USE_SHORTENED_WORKDIR` variable and decides which prompt to show based on it. This means that it someone was setting this variable in their profile file it would now no longer be respected, however this was never the intention of that variable, if a change is desired, the variable should simply be edited in the prompt file directly. - Removing continual calls to this function each time prompt is redrawn is worth the very minor inconvenience of no longer supporting shortened workdirs from externally set variable due to the speed benefit it gives us, though not that noticeable, it is pretty significant. Not to mention that this wasn't intended/recommended usage anyway.
187 lines
6.9 KiB
Bash
Executable file
187 lines
6.9 KiB
Bash
Executable file
#!/usr/bin/env zsh
|
|
|
|
# Configuration variables:
|
|
|
|
# Once we are too deep in the filestructure, we can usually afford to shorten
|
|
# the whole working directory and only print something like ~/.../dir3/dir4/dir5
|
|
# instead of ~/dir1/dir2/dir3/dir4/dir5. If this isn't desired, set this to 0
|
|
USE_SHORTENED_WORKDIR=1
|
|
|
|
# Show how much time it took to run a command
|
|
CMD_TIME_SHOW=1
|
|
# Minimum units to show the time precision, if
|
|
# we use "s" (seconds), and the output took 0s,
|
|
# we don't print the output at all to avoid clutter.
|
|
# Same goes for any other units, however with "ms"
|
|
# (miliseconds), this is very unlikely
|
|
# Valid options: ms/s/m/h/d
|
|
CMD_TIME_PRECISION="s"
|
|
# Minimum time in miliseconds, to print the time took,
|
|
# if the command takes less than this amount of miliseconds,
|
|
# don't bother printing the time took, this is nice if you
|
|
# don't need to see how long commands like 'echo' took
|
|
# Setting this to 0 will always print the time taken
|
|
CMD_TIME_MINIMUM=100
|
|
|
|
# hide EOL sign ('%')
|
|
export PROMPT_EOL_MARK=""
|
|
|
|
# TTY (pure linux) terminal only has 8-bit color support
|
|
# (unless you change it in kernel), respect this and downgrade
|
|
# the color scheme accordingly (it won't look best, but it's
|
|
# still better than no colors)
|
|
if [ $TERM = "linux" ]; then
|
|
GREEN="%F{002}"
|
|
RED="%F{001}"
|
|
ORANGE="%F{003}"
|
|
BLUE="%F{004}"
|
|
LBLUE="%F{006}"
|
|
PURPLE="%F{005}"
|
|
else
|
|
GREEN="%F{047}"
|
|
RED="%F{196}"
|
|
ORANGE="%F{214}"
|
|
BLUE="%F{027}"
|
|
LBLUE="%F{075}"
|
|
PURPLE="%F{105}"
|
|
fi
|
|
RESET="%f"
|
|
|
|
# Signals git status of CWD repository (if any)
|
|
git_prompt() {
|
|
ref=$(command git symbolic-ref HEAD 2> /dev/null) || ref=$(command git rev-parse --short HEAD 2> /dev/null) || return 0
|
|
echo -n " $ORANGE${ref#refs/heads/}"
|
|
|
|
if [ ! -z "$(git status --short 2>/dev/null)" ]; then
|
|
echo "$RED+"
|
|
fi
|
|
}
|
|
|
|
# Adds @chroot or @ssh
|
|
foreign_prompt() {
|
|
if [ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]; then
|
|
echo -n "@${ORANGE}chroot"
|
|
elif [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
|
|
echo -n "@${ORANGE}ssh"
|
|
fi
|
|
}
|
|
|
|
#nd Prints appropriate working directory
|
|
working_directory() {
|
|
# By default up to 5 directories will be tolerated before shortening
|
|
# After we surpass that, first directory (or ~) will be printed together with last 3
|
|
# This feature uses special symbol '…', but this isn't aviable when in TTY. Because
|
|
# of this, when we are in TTY, we fall back to longer '...'
|
|
|
|
if [ $USE_SHORTENED_WORKDIR != 1 ]; then
|
|
echo -n " $BLUE$~"
|
|
elif [ $TERM = "linux" ]; then
|
|
echo -n " $BLUE%(5~|%-1~/.../%3~|%4~)"
|
|
else
|
|
echo -n " $BLUE%(5~|%-1~/…/%3~|%4~)"
|
|
fi
|
|
}
|
|
|
|
# Execution time tracking hooks, this is unique to zsh, as it can add
|
|
# preexec and precmd hooks. We can utilize this to keep track of the
|
|
# amount of time it took to run certain command. We store the start time
|
|
# within a variable: PROMPT_EXEC_TIME_START, which we then compare and
|
|
# unset after the command was finished. In here, we simply set the
|
|
# PROMPT_EXEC_TIME_DURATION, which is then used in the actual prompt
|
|
# This will only be enabled if SHOW_CMD_TIME is 1.
|
|
exec_time_preexec_hook() {
|
|
[[ $SHOW_CMD_TIME == 0 ]] && return
|
|
PROMPT_EXEC_TIME_START=$(date +%s.%N)
|
|
}
|
|
exec_time_precmd_hook() {
|
|
[[ $SHOW_CMD_TIME == 0 ]] && return
|
|
[[ -z $PROMPT_EXEC_TIME_START ]] && return
|
|
local PROMPT_EXEC_TIME_STOP=$(date +%s.%N)
|
|
PROMPT_EXEC_TIME_DURATION=$(echo "($PROMPT_EXEC_TIME_STOP - $PROMPT_EXEC_TIME_START) * 1000" | bc -l)
|
|
unset PROMPT_EXEC_TIME_START
|
|
}
|
|
format_time() {
|
|
# Do some formatting to get nice time (e.g. 2m 12s) from miliseconds
|
|
# $1 is the milisecond amount (int or float)
|
|
# $2 is the precision (ms/s/m/h/d)
|
|
local T=$1
|
|
local D=$(echo "scale=0;$T/1000/60/60/24" | bc -l)
|
|
local H=$(echo "scale=0;$T/1000/60/60%24" | bc -l)
|
|
local M=$(echo "scale=0;$T/1000/60%60" | bc -l)
|
|
local S=$(echo "scale=0;$T/1000%60" | bc -l)
|
|
local MS=$(echo "scale=0;$T%1000" | bc -l)
|
|
|
|
local precision=$2
|
|
local out=""
|
|
case "$precision" in
|
|
"ms") [[ $MS > 0 ]] && out="$(printf "%dms" $MS) ${out}"; precision="s" ;&
|
|
"s") [[ $S > 0 ]] && out="$(printf "%ds" $S) ${out}"; precision="m" ;&
|
|
"m") [[ $M > 0 ]] && out="$(printf "%dm" $M) ${out}"; precision="h" ;&
|
|
"h") [[ $H > 0 ]] && out="$(printf "%dh" $H) ${out}"; precision="d" ;&
|
|
"d") [[ $D > 0 ]] && out="$(printf "%dd" $D) ${out}" ;;
|
|
*) out="$T" ;; # Return $1 ($T) if precision wasn't specified/valid
|
|
esac
|
|
printf "$out"
|
|
}
|
|
display_cmd_time() {
|
|
[[ $CMD_TIME_SHOW == 0 ]] && return
|
|
[[ -z $PROMPT_EXEC_TIME_DURATION ]] && return
|
|
# If the time duration is less than minimum time,
|
|
# don't print the time taken
|
|
[[ $PROMPT_EXEC_TIME_DURATION -lt $CMD_TIME_MINIMUM ]] && return
|
|
local time_took="$(format_time "$PROMPT_EXEC_TIME_DURATION" "$CMD_TIME_PRECISION")"
|
|
# Don't display if the time didn't give us output
|
|
# this happens when all fields (seconds/minutes/...) are 0,
|
|
# if we use milisecond precision, this will likely never happen
|
|
# but with other precisions, it could
|
|
[[ "$(expr length "$time_took")" == 0 ]] && return
|
|
echo -n " ${LBLUE}took ${time_took}"
|
|
}
|
|
|
|
setopt promptsubst # enable command substitution in prompt
|
|
|
|
# Setup ZSH hooks to display the running time of commands
|
|
autoload -Uz add-zsh-hook
|
|
add-zsh-hook preexec exec_time_preexec_hook
|
|
add-zsh-hook precmd exec_time_precmd_hook
|
|
|
|
# Primary Prompt
|
|
[ "$EUID" -eq 0 ] && PS1="$RED%n$RESET" || PS1="$GREEN%n$RESET" # user
|
|
PS1+="$(foreign_prompt)"
|
|
PS1+="$(working_directory)"
|
|
PS1+="\$(git_prompt)"
|
|
PS1+="\$(display_cmd_time)"
|
|
PS1+=" $PURPLE%(!.#.$)$RESET " # Final symbol (# or $)
|
|
|
|
# Next line prompt
|
|
PS2="$RED\ $RESET"
|
|
|
|
# Right side prompt
|
|
RPS1=""
|
|
if [ $TERM = "linux" ]; then
|
|
# Displaying cmd time here works, but often causes issues when we
|
|
# resize the terminal, since right prompts can be annoying to deal
|
|
# with when resizing. This would run relatively often so it makes
|
|
# more sense to only use it in PS1 (left prompt), but if desired,
|
|
# this can be uncommented
|
|
#RPS1+="\$(display_cmd_time)"
|
|
|
|
# If we find a non-zero return code, print it in the right prompt,
|
|
# use X here, to avoid issues with TTY not having support for
|
|
# a nicer unicode character that we use otherwise ("↵")
|
|
RPS1+="%(?..${RED}%? X$RESET)"
|
|
else
|
|
# Read comments for the section above.
|
|
#RPS1+="\$(display_cmd_time)"
|
|
|
|
# NOTE: "↵" symbol could cause issues with on some terminals/machines that
|
|
# don't handle unicode well, this issue could be very confusing to debug,
|
|
# and it would not be apparent what's wrong since the symbol itself will
|
|
# be drawn, however when it is drawn, it will also move the cursor line
|
|
# 2 places back since this symbol is made up of 3 bytes (in unicode) and
|
|
# regular ASCII characters only take up 1 byte, this means that whenever
|
|
# the right-side prompt appears (on error), the prompt would have this issue.
|
|
RPS1="%(?..${RED}%? ↵$RESET)"
|
|
fi
|
|
|