web-dev-qa-db-ja.com

readline:vi、vi-move、vi-command、vi-insertキーマップの違い

Readline(3)のマンページには、これら4つ(vi、vi-move、vi-command、vi-insert)がkeymap設定の可能なオプションとしてリストされています。これらのさまざまなオプションを設定しようとしましたが、set editing-mode viの機能以外には効果がないようです。

おそらく、この質問に答える最も簡潔な方法は、keymapを変更することでどのように違いが生じるかの例を示すことです。

マンページからの引用:

keymap (emacs)
          Set the current readline keymap.  The set of legal keymap  names
          is  emacs,  emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
          vi-command, and vi-insert.   vi  is  equivalent  to  vi-command;
          <<snip>>
7
chisophugis

これらは、viモード内のさまざまなキーマップです。たとえば、私の.inputrcさまざまなモードでキーをバインドするようにkeymapを設定します。抜粋:

# insert mode bindings
set keymap vi-insert
"\C-p": previous-history
"\C-n": next-history

# command mode bindings
set keymap vi-command
"|": beginning-of-line
"_": vi-first-print
2
peth

TL; DR

要旨が必要な場合は、見出しediting-mode vi(最後の見出し)にスキップしてください。

ちょっと待って!ただし、必要になる可能性のある背景情報がかなりあります。たとえば、editing-modekeymapの違いです。

特に便利なのは、テキストを挿入し、変更を加えるためにvi-commandに簡単にアクセスできるハイブリッドemacsキーマップの概念です。

editing-modekeymapの違いは何ですか?

only2つのediting-modesがあります:emacs(デフォルト)とvi

GNU Readline Libraryのドキュメント は次のように述べています。

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-modekeymapの違いに注意してください。editing-mode viでは、viエディター。 [〜#〜] all [〜#〜]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キーマップも同等です。

[email protected]:~$ diff <(bind -pm vi) <(bind -pm vi-move)
[email protected]:~$ 

これにより、説明する一意のキーマップとして、emacsemacs-metaemacs-ctlxvi、および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番目のコマンドをemacs-standardemacs-metaemacs-ctlxvi-command、およびvi-insertというファイルに出力すると対応するkeymaps、あなたはそれを見つけることができます:

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-ctlxemacs-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 vs vi-insert

emacs-standardには28個のコマンドがありますがvi-insertにはありません

[email protected]:~/lib/readline$ comm -12 vi-insert emacs-standard |wc -l
28
[email protected]:~/lib/readline$

emacs/emacs-standardは基本的にvi-insertのスーパーセットです。したがって、テキストを入力する場合は、できる限りemacs-standardvi-insertキーマップを使用するのが最善です emacsvi-commandを簡単に切り替えます

vi-insertにないemacs-standardの追加のバインディングは次のとおりです。

[email protected]:~/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

上で見たように、vivi-command、およびvi-move1つの同じキーマップです。

[email protected]:~$ diff <(bind -pm vi) <(bind -pm vi-move)
[email protected]:~$ 

これは、デフォルトでediting-mode viに関連付けられている2つの個別のマップの合計であることに注意してください。

editing-mode viにある場合、使用中のkeymapsはvi/vi-command/vi-moveおよびvi-insert(開始キーマップ)です。これら2つのマップのうち、一度にアクティブになるのは1つだけです。

editing-mode viは、シェルの起動時にvi-insertというラベルの付いたデフォルトのキーマップを設定するだけです。繰り返しますが、ここでは一度にアクティブなキーマップは1つだけです。このvi-insertキーマップはほとんどのキーをself-insertにマップするため、キーボードのプラスチックボタンを押すと、キーボードに印刷されている記号が画面に表示されます。

vi-insertキーマップを使用すると、vi-commandコマンドを使用して、vi-move/vi/vi-movement-modeと呼ばれるテキスト操作キーマップにスワップできます。 ESCvi-insertキーマップのデフォルトのキー。

実際には、上記のハイブリッドソリューションのように、emacsキーマップでも、vi-movement-modeコマンドを使用して、viのようなテキスト操作キーマップをアクティブに設定できます。

またはより簡単な言語で...

デフォルトでは、を押します ESCvi-commandキーマップがアクティブなときにvi-insertキーマップに変更します。

vi-commandキーマップは、次のような標準の単一キー押下を使用します a、 b そして cviエディターのデフォルトモードまたはコマンドモードと同じように、テキストを移動して操作します。一般的にはありません Ctrl+key 組み合わせ。このモードではテキストを挿入できません。文字キーは編集/移動コマンドにマップされます。テキストを入力するには、vi-insertキーマップに切り替えます(例:を押します) i 「挿入」の場合)。

テキストの入力は、vi-insertキーマップを使用して行われます。このキーマップは、editing-mode viファイルに.inputrcがある場合にシェルの起動時にアクティブになります。を押して、vi-insertキーマップにスワップします i vi-commandにいる間の「挿入」の場合(またはviで開始された場合は他の多くの方法で)。

viエディターを知らない限り、最初はvi-commandキーを使用するのは非常に難しいと思うかもしれませんが、上手くいけば、長いひげを生やしたウィザードのようにテキストを編集できます。

3
Tom Hale