Zsh update prompt with time
Asked Answered
zsh
P

2

6

I'm trying to update the previous command prompt with the time when the command was written.

With the code I wrote, typing the following command

[--:--] costam:~ $ echo "Wrote this at 10:20"

and launching it after five minutes, results in this output:

[10:25] costam:~ $ echo "Wrote this at 10:20"
Wrote this at 10:20




The code in the zsh-theme to achieve this, is the following

PROMPT='[--:--] %{$fg[red]%}$USER:%{$reset_color%}%{$fg[green]%}%c%{$reset_color%}$(git_prompt_info) %(!.#.$) '

preexec () {
    DATE=`date +"%H:%M"`
    echo -e "\r\033[1A[${DATE}]"
}




The problem is when the command exceed one line or there's an activated virtual env. In such cases, the prompt is not overridden where it should, and results in this:

# Multiline
[--:--] costam:~ (master) $ cat ~/.oh-my-zsh/custom/themes/davever
[10:20]-theme

# Virtualenv
[10:20]env) [--:--] costam:~ (master) $ echo "Broken"
Broken

A solution I was thinking of, was of finding the current prompt in preexec() and then replace [--:--] with the current time, but I don't know how or if is even possible to get the current prompt.

Any other solution is welcome, as long as the time is printed in the same way (or very similar) and not, for example, printing on the right side using RPROMT or printing in the new prompt.

Thank you!

Posit answered 24/4, 2020 at 9:22 Comment(1)
I was going to recommend \e[s at the beginning of PROMPT to save the current terminal position, then use \e[u instead of \r to move the cursor to the saved position. However preexec executes after the newline to terminate the command is printed to the screen, which means the location of the prompt has changed by the time preexec writes the date. I'm not sure there is a good solution to this.Yusem
S
1

You can just use %T to get the current time in your prompt sequence.

Additionally, rather than put raw escape codes in your prompt, you can simplify your prompt string by using %F{<color>} and %f instead.

So, remove that preexec function and use this as your prompt:

PROMPT='[%T] %F{red}$USER:%F{green}%c%f$(git_prompt_info) %(!.#.$) '
Scutate answered 29/6, 2020 at 19:59 Comment(6)
That shows the current time on the next prompt, not the current prompt.Yusem
It shows for each prompt what was the current time when it got drawn. So, on your current prompt, it shows at what time your last command finished.Scutate
That's not what the OP is doing. They are replacing the [--:--] in the prompt where the command was typed with the time at which they pressed Enter.Yusem
Yeah, I know that, but there's no good reason for it. This is way simpler and gets the info that the OP wants, too.Scutate
@Posit Does this answer fulfill your needs?Scutate
Sorry, I did not notice the discussion. I already managed to do something like what you are suggesting (don't remember exactly after all these months), but as chepner said, I was trying to replace the previous [--:--]. I still using the buggy implementation.Posit
B
0

What if you asked ZSH to refresh the terminal prompt with the current time periodically?:

PROMPT='[%D{%L:%M}] %{$fg[red]%}$USER:%{$reset_color%}%{$fg[green]%}%c%{$reset_color%}$(git_prompt_info) %(!.#.$) '

TMOUT=1

TRAPALRM() {
    zle reset-prompt
}

Sample output which tracks the current time on the computer, down to the second:

[11:41] costam:~ $ 

%D{%L:%M} will have the same effect as your use of date +"%H:%M". TMOUT suggestion found here. Since you only want the hour and minute, you might be able to increase the TMOUT value to 10 seconds or more.

Brod answered 12/1, 2023 at 17:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.