web-dev-qa-db-ja.com

viモードでzshプロンプトを表示モードにする

私が使う bindkey -v(bash-ersの場合set -o viこれはzshでも動作すると思います)またはvi(m)モード。でも、挿入モードなのかコマンドモードなのかを知るための視覚的な手掛かりがないのは不思議です。プロンプトにモードを表示させる方法を誰かが知っていますか?

48
xenoterracide

this[〜#〜] su [〜#〜] で見つかりました。基本的な例を次に示しますが、まだ自分用にカスタマイズしています。

function zle-line-init zle-keymap-select {
    RPS1="${${KEYMAP/vicmd/-- NORMAL --}/(main|viins)/-- INSERT --}"
    RPS2=$RPS1
    zle reset-Prompt
}

zle -N zle-line-init
zle -N zle-keymap-select

まだ分​​からない以外は説明します

25
xenoterracide

モードが変更されるたびに実行されるzle-keymap-selectは既に見つかりました。端末がサポートしているものに応じて(そしてもちろんモードインジケーター表示の好みに応じて)、プロンプト以外のビジュアルインジケーターを設定するために使用できます。

カーソルの形状を変更する標準の terminfo機能 があります。ただし、一部の端末では両方のモードで同じカーソルが表示されます。 Xtermのカーソルがあまり見えないという概念は、カーソルを点滅させることです(これは、-bcコマンドライン引数またはcursorBlinkリソースで有効にする必要があります)。

zle-keymap-select () {
  case $KEYMAP in
    vicmd) print -rn -- $terminfo[cvvis];; # block cursor
    viins|main) print -rn -- $terminfo[cnorm];; # less visible cursor
  esac
}

一部の端末では、print -n '\e]12;pink\a'(色名による)またはprint -n '\e]12;#abcdef\a'(RGB仕様による)でカーソルの色を変更することもできます。これらのシーケンスは、xtermのドキュメントの ctlseqs ファイルで説明されています。最新のターミナルエミュレータは通常、xtermをエミュレートしますが、すべての機能をサポートしているわけではありません。

複数行プロンプトでreset-Promptを使用する際に問題が発生している人にとって、これは私にとってうまくいきました: http://zeitlens.com/posts/2014-06-29-howto-zsh-vi-style.htmlhttps://stackoverflow.com/questions/3622943/zsh-vi-mode-status-line と組み合わせて、最終的に次のようにしました:

terminfo_down_sc=$terminfo[cud1]$terminfo[cuu1]$terminfo[sc]$terminfo[cud1]

function insert-mode () { echo "-- INSERT --" }
function normal-mode () { echo "-- NORMAL --" }

precmd () {
    # yes, I actually like to have a new line, then some stuff and then 
    # the input line
    print -rP "
[%D{%a, %d %b %Y, %H:%M:%S}] %n %{$fg[blue]%}%m%{$reset_color%}"

    # this is required for initial Prompt and a problem I had with Ctrl+C or
    # Enter when in normal mode (a new line would come up in insert mode,
    # but normal mode would be indicated)
    PS1="%{$terminfo_down_sc$(insert-mode)$terminfo[rc]%}%~ $ "
}
function set-Prompt () {
    case ${KEYMAP} in
      (vicmd)      VI_MODE="$(normal-mode)" ;;
      (main|viins) VI_MODE="$(insert-mode)" ;;
      (*)          VI_MODE="$(insert-mode)" ;;
    esac
    PS1="%{$terminfo_down_sc$VI_MODE$terminfo[rc]%}%~ $ "
}

function zle-line-init zle-keymap-select {
    set-Prompt
    zle reset-Prompt
}
preexec () { print -rn -- $terminfo[el]; }

zle -N zle-line-init
zle -N zle-keymap-select
9
Sebastian Blask

これは、zshでカーソルを「ブロック」と「ビーム」の形状の間で変更するために使用するものです。

シロアリgnome-terminalおよびmate-terminalでテスト済み)

# vim mode config
# ---------------

# Activate vim mode.
bindkey -v

# Remove mode switching delay.
KEYTIMEOUT=5

# Change cursor shape for different vi modes.
function zle-keymap-select {
  if [[ ${KEYMAP} == vicmd ]] ||
     [[ $1 = 'block' ]]; then
    echo -ne '\e[1 q'

  Elif [[ ${KEYMAP} == main ]] ||
       [[ ${KEYMAP} == viins ]] ||
       [[ ${KEYMAP} = '' ]] ||
       [[ $1 = 'beam' ]]; then
    echo -ne '\e[5 q'
  fi
}
zle -N zle-keymap-select

# Use beam shape cursor on startup.
echo -ne '\e[5 q'

# Use beam shape cursor for each new Prompt.
preexec() {
   echo -ne '\e[5 q'
}
6
Rotareti

Iビームとブロックの間でカーソルの形状を変更する別の解決策(アンダースコアの場合は\033[4 qを使用)。これを~/.zshrcに追加します。

zle-keymap-select () {
if [ $KEYMAP = vicmd ]; then
    printf "\033[2 q"
else
    printf "\033[6 q"
fi
}
zle -N zle-keymap-select
zle-line-init () {
zle -K viins
printf "\033[6 q"
}
zle -N zle-line-init
bindkey -v

https://bbs.archlinux.org/viewtopic.php?id=95078 から変更。 gnome-terminal 3.22でテストされています。


更新

カーソルの形状を変更するためのさらに別の解決策 ここで見つけることができます 。これは明らかにiTerm2で機能しますが、テストする手段はありませんが、他の人に役立つ場合に備えて、ここに追加します。 ~/.zshrcへの最後の追加は

function zle-keymap-select zle-line-init
{
    # change cursor shape in iTerm2
    case $KEYMAP in
        vicmd)      print -n -- "\E]50;CursorShape=0\C-G";;  # block cursor
        viins|main) print -n -- "\E]50;CursorShape=1\C-G";;  # line cursor
    esac

    zle reset-Prompt
    zle -R
}

function zle-line-finish
{
    print -n -- "\E]50;CursorShape=0\C-G"  # block cursor
}

zle -N zle-line-init
zle -N zle-line-finish
zle -N zle-keymap-select
6
joelostblom

あなたは試すことができます VimMode

5
Hemant

Sebastian Blaskの投稿 に基づくさらに別のバージョンを以下に示します。これは可能な限り邪魔にならないように意図されていました。私が見つけた他のすべてのソリューションは、余分な行、右側のステータス、または追加された文字を使用したためです。

これは、通常モードが有効になっているときに$の色を白から赤に変更するだけです。プロンプトを好みに合わせて編集します

bindkey -v
function zle-line-init zle-keymap-select {
    case ${KEYMAP} in
        (vicmd)      Prompt=$'%{\e[0;32m%}%~%{\e[0m%} %{\e[0;31m%}$%{\e[0m%} ' ;;
        (main|viins) Prompt=$'%{\e[0;32m%}%~%{\e[0m%} $ ' ;;
        (*)          Prompt=$'%{\e[0;32m%}%~%{\e[0m%} $ ' ;;
    esac
    zle reset-Prompt
}

zle -N zle-line-init
zle -N zle-keymap-select
3
sealj553

現在、Zshを Bullet Train テーマで使用しています。 Sebastian Blask's answer の例に従って、私は次のコードで終わりました

bindkey -v
KEYTIMEOUT=1

function zle-line-init zle-keymap-select {
    case ${KEYMAP} in
        (vicmd)      BULLETTRAIN_Prompt_CHAR="N" ;;
        (main|viins) BULLETTRAIN_Prompt_CHAR="I" ;;
        (*)          BULLETTRAIN_Prompt_CHAR="I" ;;
    esac
    zle reset-Prompt
}

zle -N zle-line-init
zle -N zle-keymap-select

これにより、デフォルト$が文字[〜#〜] n [〜#〜]を通常モードに、[〜#〜] i [〜#〜]を挿入モードに。

この画像は、通常モードで私が押す例です Ctrl+C

enter image description here

3
Luciano Almeida

oh-my-zshユーザー向けのバージョン

oh-my-zshと呼ばれるvi-mode用のプラグインがあり、ここで見つけることができます。

robbyrussell/oh-my-zsh/plugins/vi-mode

私はAntigenを使用してプラグインを管理しているので、これを含めることは、これを.zshrcに追加するのと同じくらい簡単でした:

antigen bundle vi-mode
2

zsh-vim-mode プラグインは、挿入、コマンド、検索、置換、およびビジュアルモードのインジケーターを表示できます。他の回答の基本的な手法を使用して、さまざまなZLEフック(zle-keymap-select、zle-isearch-updateなど)にフックします。チェック[[ $ZLE_STATE = *overwrite* ]]置換モード。チェック$REGION_ACTIVEビジュアルモードを識別します。

ロジックは、isearchモードを終了するときにZSHがイベントを起動する方法の癖によって複雑になっています。

このモジュールのもう1つの優れた機能は、モードに基づいてカーソルの形状と色を変更できることです。たとえば、挿入モードでは垂直バーを使用し、検索モードでは点滅する下線を使用できます。

1
Tim Smith