18

ターミナルにvimのようなナビゲーションが必要だったので、次のように追加しました。

set editing-mode vi
set keymap vi

これ.inputrcに基づいて私のファイルに。viナビゲーションを追加します。何をしますか、なぜそれが必要なのですか?editing-mode vikeymap vi

4

2 に答える 2

12

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
于 2012-04-03T23:04:51.553 に答える
12

TL; DR

デフォルトのキーマップでバインディングを変更/追加したくない場合は、行は必要ありませんkeymap vi

それkeymap vi以降にリストされているバインディングは、そのキーマップ(およびとまったく同じキーマップ)に適用されると述べてます。vi-commandvi-move

挿入キーマップを変更する場合(たとえば、Ctrl-A入力中に行の先頭に移動するためのバインディングを追加する場合)、keymap vi-insert行の下でこれを行う必要があります。

モードとマップの詳細が必要な場合は、見出し(最後viの見出し)にスキップしてください。editing-mode vi

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

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

editing-modeとの違いは何keymapですか?

sは2つだけです:(デフォルト)と。editing-modeemacsvi

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-commandvi-moveキーマップも同等です。

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

これにより、、、、、、およびを説明するための一意のキーマップが残りますemacs。キーマップを区別することは、おそらくそれらを検査することによって最もよく行われます...emacs-metaemacs-ctlxvivi-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-ctlxvi-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-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番目の形式の方が読みやすいと主張するかもしれません。

テキストの挿入:emacsvsvi-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-insertemacsvi-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-move1つの同じキーマップです。

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

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

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

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

キーマップを使用すると、コマンドを使用して//とvi-insert呼ばれるテキスト操作キーマップにスワップできます。デフォルトでは、キーマップのキーにバインドされています。vi-commandvivi-movevi-movement-modeESCvi-insert

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

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

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

キーマップは、エディタのデフォルトモードやコマンドモードと同じように、、などのvi-command標準的な1回のキー押下を使用して、テキストを移動および操作します。通常、+の組み合わせはありません。このモードではテキストを挿入できません。文字キーは編集/移動コマンドにマップされます。テキストを入力するには、キーマップに切り替えます(例:「挿入」の場合はを押します)。abcviCtrlkeyvi-inserti

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

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

于 2016-08-17T06:13:06.707 に答える