Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

zsh: update prompt with current time when a command is started

I have a zsh prompt I rather like: it evaluates the current time in precmd and displays that on the right side of the prompt:

[Floatie:~] ^_^  cbowns%                      [9:28:31 on 2012-10-29] 

However, this isn't exactly what I want: as you can see below, this time is actually the time the previous command exited, not the time the command was started:

[Floatie:~] ^_^  cbowns% date                           [9:28:26 on 2012-10-29] Mon Oct 29 09:28:31 PDT 2012 [Floatie:~] ^_^  cbowns% date                           [9:28:31 on 2012-10-29] Mon Oct 29 09:28:37 PDT 2012 [Floatie:~] ^_^  cbowns%                                [9:28:37 on 2012-10-29] 

Is there a hook in zsh to run a command just before the shell starts a new command so I can update the prompt timestamp then? (I saw Constantly updated clock in zsh prompt?, but I don't need it constantly updated, just updated when I hit enter.)

(The ^_^ is based on the previous command's return code. It shows ;_; in red when there's a nonzero exit status.)

like image 836
cbowns Avatar asked Oct 29 '12 16:10

cbowns


People also ask

How do I add time to zsh prompt?

Add the Date and Time to the zsh Prompt If you want to include the system time in the zsh prompt, add %T for the current time in 24-hour format, %t for the time to appear in AM/PM or 12-hour format, or use %* to display the time in the 24-hour format along with seconds.

What is zsh prompt?

The default prompt for zsh is: phoenix% echo $PROMPT %m%# The %m stands for the short form of the current hostname, and the %# stands for a % or a # , depending on whether the shell is running as root or not. zsh supports many other control sequences in the PROMPT variable.


2 Answers

This is in fact possible without resorting to strange hacks. I've got this in my .zshrc

RPROMPT='[%D{%L:%M:%S %p}]'  TMOUT=1  TRAPALRM() {     zle reset-prompt } 

The TRAPALRM function gets called every TMOUT seconds (in this case 1), and here it performs a prompt refresh, and does so until a command starts execution (and it doesn't interfere with anything you type on the prompt before hitting enter). I know you don't need it constantly refreshed but it still gets the job done without needing a line for itself!

Source: http://www.zsh.org/mla/users/2007/msg00944.html (It's from 2007!)

like image 200
nitarshan Avatar answered Oct 07 '22 16:10

nitarshan


I had a struggle to make this:

It displays the date on the right side when the command has been executed. It does not overwrite the command shown. Warning: it may overwrite the current RPROMPT.

strlen () {     FOO=$1     local zero='%([BSUbfksu]|([FB]|){*})'     LEN=${#${(S%%)FOO//$~zero/}}     echo $LEN }  # show right prompt with date ONLY when command is executed preexec () {     DATE=$( date +"[%H:%M:%S]" )     local len_right=$( strlen "$DATE" )     len_right=$(( $len_right+1 ))     local right_start=$(($COLUMNS - $len_right))      local len_cmd=$( strlen "$@" )     local len_prompt=$(strlen "$PROMPT" )     local len_left=$(($len_cmd+$len_prompt))      RDATE="\033[${right_start}C ${DATE}"      if [ $len_left -lt $right_start ]; then         # command does not overwrite right prompt         # ok to move up one line         echo -e "\033[1A${RDATE}"     else         echo -e "${RDATE}"     fi  } 

Sources:

  • http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html
  • https://stackoverflow.com/a/10564427/238913
like image 24
SamK Avatar answered Oct 07 '22 15:10

SamK