ターミナルにvimのようなナビゲーションが必要だったので、次のように追加しました。
set editing-mode vi
set keymap vi
これ.inputrc
に基づいて私のファイルに。viナビゲーションを追加します。何をしますか、なぜそれが必要なのですか?editing-mode vi
keymap vi
man readline
(私の強調)から:
有効なキーマップ名のセットは、emacs、emacs-standard、emacs-meta、emacs-ctlx、vi、vi-move、vi-command、およびvi-insertです。 viはviコマンドと同等です
したがって、では、inputrc
モードごとに異なるキーバインドを指定できます。たとえば、command
モードでは、前のコマンドの最後の引数をでヤンクできますがAltp、このキーバインドはモードでは効果がありませんinsert
(とにかくこの単純なセットアップでは)。
set editing-mode vi
set keymap vi-command
# these are for vi-command mode
"\e[A": history-search-backward
"\e[B": history-search-forward
"\ep": yank-last-arg
set keymap vi-insert
# these are for vi-insert mode
"\e[A": history-search-backward
"\e[B": history-search-forward
Control-l: clear-screen
TL; DR
デフォルトのキーマップでバインディングを変更/追加したくない場合は、行は必要ありませんkeymap vi
。
それkeymap vi
以降にリストされているバインディングは、そのキーマップ(およびとまったく同じキーマップ)に適用されると述べています。vi-command
vi-move
挿入キーマップを変更する場合(たとえば、Ctrl-A
入力中に行の先頭に移動するためのバインディングを追加する場合)、keymap vi-insert
行の下でこれを行う必要があります。
モードとマップの詳細が必要な場合は、見出し(最後vi
の見出し)にスキップしてください。editing-mode vi
ちょっと待って!ただし、必要になる可能性のある背景情報がかなりあります。たとえば、との違いediting-mode
ですkeymap
。
特に便利なのは、emacs
テキストを挿入しvi-command
、変更を簡単に行うためのハイブリッドキーマップの概念です。
editing-mode
との違いは何keymap
ですか?
sは2つだけです:(デフォルト)と。editing-mode
emacs
vi
GNUReadlineLibraryのドキュメントには次のように書かれています。
editing-mode The editing-mode variable controls which default set of key bindings is used. By default, Readline starts up in Emacs editing mode, where the keystrokes are most similar to Emacs. This variable can be set to either `emacs' or `vi'.
editing-mode
との違いに注意してくださいkeymap
。2editing-mode vi
つ(はい、2つしかないので、読み進めてください)では、キーマップがスワップインおよびスワップアウトされて、vi
エディターのさまざまなモードがエミュレートされます。すべてのemacs
ものが同時に動作しますediting-mode emacs
(後で説明します)。
では、editing-mode
実際には何をするのでしょうか?シェルの起動時にアクティブなキーマップをemacs
またはに設定するだけvi-insert
です。
ユニークなキーマップは何ですか?
Acceptable keymap names are emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, vi-command, and vi-insert. vi is equivalent to vi-command; emacs is equivalent to emacs-standard.
文書化されていませんが、vi
/vi-command
とvi-move
キーマップも同等です。
+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$
これにより、、、、、、およびを説明するための一意のキーマップが残りますemacs
。キーマップを区別することは、おそらくそれらを検査することによって最もよく行われます...emacs-meta
emacs-ctlx
vi
vi-insert
キーマップのデフォルトのバインディングは何ですか?
(例)emacs(デフォルト)のデフォルトのキーバインディングを表示するには、次を使用します。
INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -v '^#
emacs
上記の例では、他のキーマップ名に置き換えることができます。
self-insert
あまり役に立たない、またはdo-lowercase-version
あまり役に立たないという行がたくさんあるので、それらを削除します。
INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -vE '^#|: (do-lowercase-version|self-insert)$' | sort
さまざまなキーマップの違いは何emacs
ですか?
TL; DR:に適用される単一のマッピングセットに対する異なるビューediting-mode emacs
です。
2番目のコマンドを、、、、、、およびそれらの対応するsのファイルに出力すると、次emacs-standard
のことemacs-meta
がわかります。emacs-ctlx
vi-command
vi-insert
keymap
emacs-meta
マップされているコマンドはなく、次のコマンドにemacs-ctlx
も表示されませんemacs-standard
。
$ comm -13 <(sed -r 's/.*: (\S+)/\1/' emacs-standard|sort) <(sed -r 's/.*: (\S+)/\1/' emacs-ctlx|sort)
$ comm -13 <(sed -r 's/.*: (\S+)/\1/' emacs-standard|sort) <(sed -r 's/.*: (\S+)/\1/' emacs-meta|sort)
$
したがって、 emacs
/emacs-standard
は両方の動作的に機能するスーパーセットでありemacs-ctlx
、emacs-meta
これは次のことを意味します。
keymap emacs
"\eg": glob-expand-word
"\C-x\C-r": re-read-init-file
機能的には次のものと同等です。
keymap emacs-meta
"g": glob-expand-word
keymap emacs-ctlx
"\C-r": re-read-init-file
2番目の形式の方が読みやすいと主張するかもしれません。
テキストの挿入:emacs
vsvi-insert
emacs-standard
にない28のコマンドがありますvi-insert
+ravi@boxy:~/lib/readline$ comm -12 vi-insert emacs-standard |wc -l
28
+ravi@boxy:~/lib/readline$
emacs
/emacs-standard
は基本的にのスーパーセットですvi-insert
。したがって、テキストを入力する場合は、とを簡単に切り替えることができる限り、emacs-standard
キーマップを使用するのが最適です。vi-insert
emacs
vi-command
notinの追加のバインディングvi-insert
は次のemacs-standard
とおりです。
+ravi@boxy:~/lib/readline$ comm -23 vi-insert emacs-standard
"\C-d": vi-eof-maybe
"\C-n": menu-complete
"\C-p": menu-complete-backward
"\e": vi-movement-mode
これら4つの最初の3つは、emacs
バインディングと競合します。
"\C-d": delete-char
"\C-n": next-history
"\C-p": previous-history
私は次のように解決しました:
set keymap emacs
"\e": "kj" # see https://unix.stackexchange.com/questions/303631/how-can-i-setup-a-hybrid-readline-with-emacs-insert-mode-and-vi-command-mode
"\C-d": delete-char # eof-maybe: ^D does nothing if there is text on the line
"\C-n": menu-complete
"\C-p": menu-complete-backward
"\C-y": previous-history # historY
"\e\C-y": previous-history
editing-mode vi
上で見たようにvi
、、、vi-command
およびvi-move
は1つの同じキーマップです。
+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$
これは、デフォルトでに関連付けられている2つの異なるマップの合計であることに注意してくださいediting-mode vi
。
の場合、使用editing-mode vi
中のkeymap
sはvi
//vi-command
および(開始キーマップ)です。これら2つのマップのうち、一度にアクティブになるのは1つだけです。vi-move
vi-insert
editing-mode vi
シェルの起動時に、というラベルの付いたデフォルトのキーマップを設定するだけですvi-insert
。繰り返しますが、ここでは一度にアクティブなキーマップは1つだけです。このvi-insert
キーマップはほとんどのキーをにマップするself-insert
ため、キーボードのプラスチックボタンを押すと、キーボードに印刷されている記号が画面に表示されます。
キーマップを使用すると、コマンドを使用して//とvi-insert
呼ばれるテキスト操作キーマップにスワップできます。デフォルトでは、キーマップのキーにバインドされています。vi-command
vi
vi-move
vi-movement-mode
ESCvi-insert
実際には、上記のハイブリッドソリューションのように、キーマップでさえ、コマンドを使用して-likeテキスト操作キーマップをアクティブにemacs
設定できます。vi
vi-movement-mode
またはより簡単な言語で...
デフォルトでは、キーマップがアクティブなときにを押してキーマップにESC変更します。vi-command
vi-insert
キーマップは、エディタのデフォルトモードやコマンドモードと同じように、、などのvi-command
標準的な1回のキー押下を使用して、テキストを移動および操作します。通常、+の組み合わせはありません。このモードではテキストを挿入できません。文字キーは編集/移動コマンドにマップされます。テキストを入力するには、キーマップに切り替えます(例:「挿入」の場合はを押します)。abcvi
Ctrlkeyvi-insert
i
テキストの入力はキーマップを使用して行われます。キーマップは、ファイルvi-insert
にある場合はシェルの起動時にアクティブになります。中に「挿入」を押してキーマップにスワップします(または、に開始された場合は他の多くの方法で)。editing-mode vi
.inputrc
vi-insert
ivi-command
vi
vi
エディターを知らない限りvi-command
、最初はキーを使用するのが非常に難しいと思うかもしれませんが、それが上手になれば、長いひげを生やしたウィザードのようにテキストを編集できます。