Подтвердить что ты не робот

Zsh: обновить приглашение с текущим временем при запуске команды

У меня есть приглашение zsh, которое мне нравится: оно оценивает текущее время в precmd и отображает, что в правой части подсказки:

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

Однако это не совсем то, что я хочу: как вы можете видеть ниже, на этот раз на самом деле это время, когда вышла предыдущая команда, а не время запуска команды:

[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]

Есть ли крючок в zsh для запуска команды непосредственно перед запуском оболочки новой командой, поэтому я могу обновить временную метку приглашения? (Я видел Постоянно обновляемые часы в zsh prompt?, но я не нуждаюсь в нем постоянно обновляемый, просто обновляющийся, когда я нажимаю enter.)

(^_^ основан на предыдущем коде возврата команды. Он показывает ;_; красным цветом, когда есть ненулевой статус выхода.)

4b9b3361

Ответ 1

У меня была борьба, чтобы сделать это:

Он отображает дату с правой стороны, когда команда выполнена. Он не перезаписывает показанную команду. Предупреждение: он может перезаписать текущий 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 "[email protected]" )
    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

}

Источники:

Ответ 2

Это действительно возможно, не прибегая к странным хакам. У меня это есть в моем .zshrc

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

TMOUT=1

TRAPALRM() {
    zle reset-prompt
}

Функция TRAPALRM вызывается каждые TMOUT секунд (в этом случае 1), и здесь она выполняет быстрое обновление и делает это до тех пор, пока команда не начнет выполнение (и она не будет мешать чему-либо, что вы набираете в подсказке перед ударом войти). Я знаю, что вам не нужно постоянно его обновлять, но он все равно выполняет свою работу, не требуя для себя линии!

Источник: http://www.zsh.org/mla/users/2007/msg00944.html (Это от 2007!)

Ответ 3

zsh будет запускать функцию preexec непосредственно перед выполнением строки. Было бы просто получить, что вывести текущее время, простая версия будет просто:

preexec() { date }

Изменение существующего запроса было бы намного сложнее.

Ответ 4

Строительство @vitaŭt-bajaryn классный стиль ZSH answer:

Я думаю, что переопределение функции 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

Ответ 5

Вы можете использовать ANSI escape-последовательности для записи по предыдущей строке, например:

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

Ответ 6

Вы можете переназначить клавишу Return на reset приглашение до принятия строки:

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