zsh:启动命令时使用当前时间更新提示

cbo*_*wns 33 zsh prompt zsh-zle

我有一个zsh提示我更喜欢:它评估当前时间precmd并显示在提示的右侧:

[Floatie:~] ^_^ 
cbowns%                      [9:28:31 on 2012-10-29]
Run Code Online (Sandbox Code Playgroud)

然而,这不是正是我想要的:你可以看到下面,这个时候实际上是将以往的命令退出,而不是命令开始的时间的时间:

[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]
Run Code Online (Sandbox Code Playgroud)

在shell启动新命令之前是否有一个挂钩zsh来运行命令,以便我可以更新提示时间戳呢?(我在zsh提示符中看到了持续更新的时钟?但是我不需要它不断更新,只是在我按下回车时更新.)

(^_^它基于前一个命令的返回代码.;_;当存在非零退出状态时,它显示为红色.)

nit*_*han 34

事实上,这可能不会诉诸于奇怪的黑客.我的.zshrc中有这个

RPROMPT='[%D{%L:%M:%S %p}]'

TMOUT=1

TRAPALRM() {
    zle reset-prompt
}
Run Code Online (Sandbox Code Playgroud)

TRAPALRM函数每TMOUT秒调用一次(在本例中为1),此处执行快速刷新,直到命令开始执行为止(并且它不会干扰您在按Enter键之前在提示符上键入的任何内容).我知道你不需要它不断刷新,但它仍然可以完成工作,而不需要自己的线!

资料来源:http://www.zsh.org/mla/users/2007/msg00944.html(从2007年开始!)


Sam*_*amK 16

我努力做到这一点:

执行命令时,它会在右侧显示日期.它不会覆盖显示的命令.警告:它可能会覆盖当前的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

}
Run Code Online (Sandbox Code Playgroud)

资料来源:


qqx*_*qqx 12

zshpreexec在执行一行之前运行该函数.将输出设置为当前时间很简单,简单版本就是:

preexec() { date }
Run Code Online (Sandbox Code Playgroud)

修改现有提示将更具挑战性.


NHD*_*aly 8

建立@vitaŭt-bajaryn的酷ZSH风格答案:

我认为重写accept-line函数可能是最惯用的zsh解决方案:

function _reset-prompt-and-accept-line {
  zle reset-prompt
  zle .accept-line     # Note the . meaning the built-in accept-line.
}
zle -N accept-line _reset-prompt-and-accept-line
Run Code Online (Sandbox Code Playgroud)


小智 7

Return在接受该行之前,您可以重新映射该键以重置提示:

reset-prompt-and-accept-line() {
    zle reset-prompt
    zle accept-line
}

zle -N reset-prompt-and-accept-line

bindkey '^m' reset-prompt-and-accept-line
Run Code Online (Sandbox Code Playgroud)


Dan*_*dei 5

您可以使用ANSI转义序列来覆盖前一行,如下所示:

preexec () {
  DATE=`date +"%H:%M:%S on %Y-%m-%d"`
  C=$(($COLUMNS-24))
  echo -e "\033[1A\033[${C}C ${DATE} "
}
Run Code Online (Sandbox Code Playgroud)