readlineのモード、キーマップ、基本バインディングは何ですか?

readlineのモード、キーマップ、基本バインディングは何ですか?

readlineモードとキーマップの違いは何ですか?

各モードの主キーバインディングをどのように見つけますか?

答え1

長い話を短く

emacs(デフォルト)の主キーバインディングを表示するには(例)以下を使用します。

INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -vE '^#|: (do-lowercase-version|self-insert)$'

vivi-commandvi-move一つで同じキーマッピング。

どちらもemacs-metaキーマップemacs-ctlxのサブセットビューですemacs

viモードとマップについてもっと知りたい場合は、タイトルediting-mode vi(最後)にスキップしてください。

しかし、待って!しかし、かなり多くの背景情報が必要な場合があります。たとえば、editing-modeanとaの違いがありますkeymap

emacs特に便利なのは、簡単に変更できながらテキストを挿入できるハイブリッドキーマップの概念ですvi-command

editing-modeこれらのanとaの違いは何ですかkeymap

持つただ2つのediting-modes:(emacsデフォルト)とvi

これGNU Readlineライブラリドキュメント説明する:

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。これら2つ(例:2つしかありません。続きを読む)では、editing-mode viキーマップが互いに変わり、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-commandvi-moveキーマップも同じです。

+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$ 

これによりemacs、、、emacs-metaおよびemacs-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

重要な要約:適用するマッピングセットの異なる視点editing-mode emacs

emacs-standardemacs-meta2番目のコマンドの出力を、、、、および対応するemacs-ctlxsというファイルに入れると、次のようになります。vi-commandvi-insertkeymap

マップされていないコマンドは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番目のフォームが読みやすくなると言うこともできます。

テキスト挿入emacsvi-insert

emacs-standardnot inには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

vi-insertnot inの唯一の追加バインディングは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-commandvi-move一つで同じキーマップ:

+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$ 

総額はちょうど参考にしてください二つ基本的に関連する他の地図ですediting-mode vi

にあるときにediting-mode vi使用さkeymapれるsはvi//vi-commandおよび(開始キーマップ)ですvi-movevi-insertこれら 2 つのマップのうち 1 つだけが同時にアクティブになります。

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

キーマップを使用すると、デフォルトでキーマップのキーにバインドされたコマンドを使用して、vi-insert//というテキスト操作のキーマップに置き換えることができますvi-commandvivi-movevi-movement-modeESCvi-insert

実際には、上記のハイブリッドソリューションのように、コマンドを使用してテキストなどの操作に対してemacsキーマップを有効にすることもできます。vivi-movement-mode

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

デフォルトでは、キーマップが有効になっている場合にESCキーマップを変更するにはタップします。vi-commandvi-insert

キーマップは、エディタのデフォルトモードまたはコマンドモードと同様に、vi-command標準の単一キー(たとえば、aおよびb)を使用してcテキストを移動して対話します。一般的に+の組み合わせはviありません。このモードでは、文字キーが編集/移動コマンドにマップされ、テキストを挿入できません。テキストを入力するには、キーマップに切り替えます(例:「挿入」を押す)。Ctrlkeyvi-inserti

vi-insertファイルにキーマップがある場合は、シェルの起動時にアクティブになるキーマップを使用してテキストを入力します。キーマップに切り替えるには、「挿入」キーを押します。 (キーマップで起動した人のために他の方法もあります。)editing-mode vi.inputrcvi-insertivi-commandvi

viエディタに慣れていないと、vi-command最初はキーを使用するのが難しいかもしれませんが、うまく使用すると、ひげを生やしたウィザードのようにテキストを編集できます。

関連情報