web-dev-qa-db-ja.com

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に、コマンドを実行するフックがありますかbeforeシェルが新しいコマンドを開始するので、プロンプトのタイムスタンプを更新できますか? (私は zshプロンプトで常に更新された時計? を見ましたが、私はそれを必要としません常に更新されました。 Enterキーを押します。)

^_^は、前のコマンドの戻りコードに基づいています。それが示している ;_;終了ステータスがゼロ以外の場合は赤で表示されます。)

35
cbowns

私はこれを作るのに苦労しました:

コマンドが実行された日付が右側に表示されます。表示されているコマンドは上書きされません。警告:現在の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

}

出典:

17
SamK

これは実際、奇妙なハッキングに頼ることなく可能です。私はこれを私の.zshrcに持っています

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

TMOUT=1

TRAPALRM() {
    zle reset-Prompt
}

TRAPALRM関数はTMOUT秒(この場合は1)ごとに呼び出され、ここではプロンプトリフレッシュを実行し、コマンドが実行を開始するまで実行します(Enterキーを押す前にプロンプ​​トに入力した内容に干渉しません)。常に更新する必要はありませんが、それでも行を必要とせずに作業を完了できます。

出典: http://www.zsh.org/mla/users/2007/msg00944.html (2007年からです!)

35
nitarshan

zshは、行を実行する直前にpreexec関数を実行します。その出力を現在の時刻にするのは簡単です。単純なバージョンは次のようになります。

preexec() { date }

既存のプロンプトを変更することは、はるかに困難です。

12
qqx

次の行を受け入れる前に、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
10
Vitaŭt Bajaryn

@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
9
NHDaly

ANSIエスケープシーケンス を使用して、次のように前の行を上書きできます。

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