diff --git a/home/.config/shell/prompt b/home/.config/shell/prompt index aa81208..3350630 100755 --- a/home/.config/shell/prompt +++ b/home/.config/shell/prompt @@ -1,5 +1,16 @@ #!/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 +SHOW_CMD_TIME=1 + + # hide EOL sign ('%') export PROMPT_EOL_MARK="" @@ -24,11 +35,6 @@ else fi RESET="%f" -# 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 - # 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 @@ -64,13 +70,58 @@ working_directory() { 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) +} +exec_time_precmd_hook() { + [[ $SHOW_CMD_TIME == 0 ]] && return + [[ -z $PROMPT_EXEC_TIME_START ]] && return + local PROMPT_EXEC_TIME_STOP=$(date +%s) + PROMPT_EXEC_TIME_DURATION=$(( $PROMPT_EXEC_TIME_STOP - $PROMPT_EXEC_TIME_START )) + unset PROMPT_EXEC_TIME_START +} +format_time() { + # Do some formatting to get nice time (e.g. 2m 12s) + # from seconds only + local T=$1 + local D=$((T/60/60/24)) + local H=$((T/60/60%24)) + local M=$((T/60%60)) + local S=$((T%60)) + [[ $D > 0 ]] && printf '%dd ' $D + [[ $H > 0 ]] && printf '%dh ' $H + [[ $M > 0 ]] && printf '%dm ' $M + printf '%ds' $S +} +display_cmd_time() { + [[ $SHOW_CMD_TIME == 0 ]] && return + [[ -z $PROMPT_EXEC_TIME_DURATION ]] && return + # Don't display the time, if it's 0 seconds + [[ $PROMPT_EXEC_TIME_DURATION == 0 ]] && return + echo -n " ${LBLUE}took $(format_time $PROMPT_EXEC_TIME_DURATION)" +} + 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 @@ -78,8 +129,8 @@ PS2="$RED\ $RESET" # Right side prompt (on error) if [ $TERM = "linux" ]; then - RPS1="%(?..${RED}%? X$RESET)" + RPS1="\$(display_cmd_time)%(?..${RED}%? X$RESET)" else - RPS1="%(?..${RED}%? ↵$RESET)" + RPS1="\$(display_cmd_time)%(?..${RED}%? ↵$RESET)" fi