web-dev-qa-db-ja.com

viモードの文字列をbashプロンプトの最後に移動します

Bashでvi編集モードを使用しています。 〜/ .inputrcで「show-mode-in-Prompt」を「on」に設定しています。

show-mode-in-Prompt(オフ)

Onに設定されている場合は、プロンプトの先頭に編集モードを示す文字列(emacs、viコマンド、またはvi挿入)を追加します。モード文字列はユーザ​​ーが設定できます(例:emacs-mode-string)。

これで、プロンプトの最初に編集モードが表示されます。

i:$ # This is ins mode
c?$ # This is cmd mode
i:$ cat ~/.inputrc
set editing-mode vi
set show-mode-in-Prompt on
set vi-ins-mode-string "\1\e[1;32m\2i:\1\e[0m\2"
set vi-cmd-mode-string "\1\e[1;31m\2c?\1\e[0m\2"
set colored-stats on
i:$ echo $PS1
$

ただし、プロンプトの最後にこれが本当に必要であり、現在のディレクトリの前に追加します。

/current/dir/here $ i:

しかし、これが達成可能かどうかはわかりません。最初に考えたのは、PS1でキャリッジリターンを使用することでしたが、残念ながら、これによりモード文字列が上書きされます。

i:$ PS1='\r\w $ '
~/projects $

私の2番目の考えは、readlineにプロンプ​​トに書き込ませるのではなく、どういうわけかモード文字列を取得して$ Prompt_COMMANDに挿入することでした。現在のモードは次の方法で取得できます。

i:$ bind -v | grep keymap | awk '{print $3}'
vi-insert

ただし、Prompt_COMMAND値は、Promptが発行される前にのみ実行されるため、モードの変更は表示されません。

試行番号3には、ディレクトリ用のスペースがあるように、モード文字列のパディングが含まれていました。これは機能する可能性がありますが、スペースの量を可変にする方法がわかりません。また、プロンプトはモード文字列の前に開始され、モード文字列はコマンドによって上書きされます。モードを切り替えると、入力したテキストがモード文字列全体に置き換えられ、スペースのために効果的にクリアされます。

                                i:  cat ~/.inputrc
set editing-mode vi
set show-mode-in-Prompt on
set vi-ins-mode-string "                                \1\e[1;32m\2i:\1\e[0m\2"
set vi-cmd-mode-string "                                \1\e[1;31m\2c?\1\e[0m\2"
set colored-stats on
                                i:  PS1="\r\w $ "
~/projects $                    i:
~/projects $ # typing stuff     i:
~/projects $ # typing more stuff overwrites the mode line
~/projects $                    c?verwrites the mode line

これを行う他の賢い方法はありますか?おそらく、行の先頭にジャンプするが既存の文字を上書きしないキャリッジリターンのような制御文字ですか?

i:$ echo $BASH_VERSION
5.0.7(1)-release
3
Josh Cooley

これを実現するには、コマンドモードと挿入モードに非常に長いモード文字列を設定します。これには、プロンプトに必要な他の項目が含まれます。これは、現在のディレクトリの「きれいな」印刷に\wなどのPS1で利用可能な特別なショートカットを使用できないことを意味することに注意してください。しかし、同じことを行うシェルコードでもおそらく同じことを達成できます。

bind "set vi-ins-mode-string \"...\""およびbind "set vi-cmd-mode-string \"...\""コマンドを使用してreadline変数を設定できます。 (詳細については、help bindを参照してください。)そして、Prompt_COMMANDから設定して、各プロンプトの前にリセットされるようにすることができます(したがって、ディレクトリ、日付、時刻の変更を含めると反映されます)。など)

引用には注意が必要です:-)

自分で使用した例の場合:

/current/dir/here $ i:

あなたはこれを使うことができます:

reset_readline_Prompt_mode_strings () {
    bind "set vi-ins-mode-string \"$PWD \$ \1\e[1;32m\2i:\1\e[0m\2\""
    bind "set vi-cmd-mode-string \"$PWD \$ \1\e[1;31m\2c?\1\e[0m\2\""
}
Prompt_COMMAND=reset_readline_Prompt_mode_strings
PS1=' '

前述のように、$PWDの展開にはフルパスが含まれ、~などからの相対パスは使用されません。

プロンプトで使用されるのと同じ 展開を取得できます bashの${variable@P}演算子展開を使用します。

EMBEDDED_PS1='\w $ '
reset_readline_Prompt_mode_strings () {
    bind "set vi-ins-mode-string \"${EMBEDDED_PS1@P}\1\e[1;32m\2i:\1\e[0m\2\""
    bind "set vi-cmd-mode-string \"${EMBEDDED_PS1@P}\1\e[1;31m\2c?\1\e[0m\2\""
}

PS1を空でないものに設定する必要があることに注意してください。そうしないと、プロンプトがまったく出力されません。この場合、単一のスペースを使用できます。行の継続のために、PS2を適切に設定することを検討することをお勧めします。

ところで、insおよびcmdモードの文字列の記号と色に関する私の推奨事項は次のとおりです。

  • cmd:を使用する必要があり(Vimの通常モードから:コマンドを入力できるのと同じ)、緑色を使用する必要があります(これは lightline によって設定されるデフォルトの色であるため) 「通常」モードのステータス行にあります。)
  • ins+(バッファが変更されたことを示すためにVimが使用する記号です。挿入すると変更されます)を使用し、青色( lightlineで使用されるデフォルトの色)を使用する必要があります。 「挿入」モードのステータス行。)

個人的には、以下はかなりクールだと思います。

EMBEDDED_PS1='\w $ '
reset_readline_Prompt_mode_strings () {
    bind "set vi-ins-mode-string \"${EMBEDDED_PS1@P}\1\e[32m\2: >\1\e[92m\2>\1\e[0m\2>\""
    bind "set vi-cmd-mode-string \"${EMBEDDED_PS1@P}\1\e[34m\2+ >\1\e[94m\2>\1\e[0m\2>\""
}
Prompt_COMMAND=reset_readline_Prompt_mode_strings
PS1=' '
PS2=' ... '
4
filbranden