「vi」モードまたは「emacs」モードのシェルとはどういう意味ですか?


32

この質問は答えから直接続きます。この場合、私は言う部分を明確に理解することができません:

その点で、その動作はbash(readline)/ ksh / zsh emacsモードよりもemacs 'に近いですCtrl-Wが、前の単語を削除するターミナルドライバーの組み込み行エディター(標準モード)からは離れています(vi )。

ここでは、2つの完全に異なるプログラムであるエディターではなく、シェルについて説明しています。シェルが何らかのエディターモードにあるとはどういう意味ですか?

PS:シェルとは何か、基本的な編集にvimを使用する方法を理解しているという前提に基づいて答えを出すことができます。


これは、コアシェルの機能そのものではなく、行の編集(入力ミスをして自分自身に戻って修正するときに行うこと)に関するものです。
n。「代名詞」m。

回答:


27

「vi」モードでは、viエディターの行のように、現在のシェルプロンプトで編集/移動できます。1行のテキストファイルのように見ることができます。同様に、「emacs」モードでは、Emacsのショートカットの一部を使用して現在のコマンドラインを編集/ナビゲートできます。

たとえば、viモードでは(bashで)次のようなことができます。

$ set -o vi
$ ls hello world
<ESC>
bbdw # results in
$ ls world

emacsモードでは、たとえばCtrl+ Aを押すと、行の先頭にジャンプできます(vi:Ctrl+ [0またはESC0)。set -o emacs(bash、ksh、zshなどで)emacsモードをオンにできます。

読み込まれた行

多くの対話型コマンドラインプログラム(bashを含む)はreadlineライブラリを使用します。したがって、使用する入力モード(viまたはemacs)およびその他のオプションを1か所で構成して、readlineを使用するすべてのプログラムでまったく同じ編集/ナビゲーションインターフェイスを使用できます。

たとえば、私のreadline設定は次のようになります。

$ cat ~/.inputrc 
set editing-mode vi
set blink-matching-paren on

たとえば、zsh / kshは私の知る限りreadlineを使用しませんが、bash / readlineに非常によく似たvi / emacsモードもサポートします。

もちろん、コマンドラインシェルのvi / emacsモードは、完全なエディター機能セットのサブセットにすぎません。すべての機能がコマンドラインシェルで意味をなすわけではなく、一部の機能は他の機能よりもサポートが複雑です。

正規モード

インタラクティブコマンドラインシェルのvi / emacsモードが「発明された」前は、シェルはターミナルの標準モードのみを使用し、限られた編集コマンドセットのみを提供します(たとえば、最後の単語を削除するにはCtrl+ W


どの入力モードになっているかわからないとします。テキストを入力して[Ctrl] + [A]を押して確認できますか?カーソルがemacsの先頭に移動した場合、それ以外はvi
リモバラ

2
@limovalaは、適切な近似値です。もちろん、シェルに依存します-CTL + Aが機能しない場合は、シェルに編集モードが含まれていない可能性があります。おそらく、いくつかのシェルは他の編集モードも実装しています。しかし、実際にはあなたの方法は十分に良いはずです。さらに確実にするために、viコマンドを使用してテストすることもできます。bashでは、のようなものも使用できますset -o | grep 'emacs\|vi'。ただし、zsh(viモードがある場合)では、これは機能しません。
maxschlepzig

バインド-Pは、モード1がであるのは良い兆候与えるだろう
ポール

23

catターミナルのシェルプロンプトで実行すると、catstdinから読み取った内容をstdoutに書き込むことになっていて、を押すaa、ターミナルドライバーによってエコーバックが表示されますが、それcatは書き込まれませんa( 1つのみa、ターミナルドライバによってエコーされるもの)。

ただし、a Backspace b Entercat入力するとa\010b\015、の出力は表示されませんが、b\012bおよび改行)が表示されます。

それは、ターミナルドライバ(カーネル内のソフトウェアではなく、カーネル内のソフトウェアxterm)が標準モードの場合に非常に基本的なラインエディタを実装するためです。ターミナルドライバーは、コマンドを使用するときなどのシステムコールを使用して構成できます。たとえば、標準モードを終了するには、を実行できます。もしあなたがそうするなら:ioctl()sttystty -icanon

stty -icanon; cat

次に、echo(で無効にすることもできますstty -echo)とcat出力の両方が同時に表示されます。

そのエディターはラインエディターです。つまり、ユーザーがを押すと、端末デバイスを読み取るアプリケーションに送信されるまで、1行のテキストを編集できますEnter

そのエディターの編集機能は非常に限られています。ほとんどの実装では、4つの編集キー(実際には文字)のみが設定可能sttyです。

  • erase(^Hまたは^?通常):前の文字を消去します
  • kill(^U通常):空(kill)これまでに入力された行
  • werase(^W):前の単語を消去します
  • lnext(^V):次の文字をそのまま入力します(上記すべての特別な意味をキャンセルします)

昔は、ターミナルドライバーのラインエディターがより優れた機能で拡張されると考えられていました。そのため、初期のシェルにはコマンドライン編集機能がありません(cat上記のように実行した場合よりもシェルプロンプトで同じ行編集機能を使用できます)。

しかし、それは実際には起こりませんでした。おそらく、いくつかのキーを押しても異なる端末が同じ文字を送信しないという混乱が原因で、カーネル空間に実装すべきではないことが明らかになりました。

そのため、一部のシェルは、ターミナルドライバーの標準モードを削除し、独自のラインエディターを実装し始めました。当時、emacsvi完全に異なるキーバインディングや運転モードで最も人気のある視覚的なテキストエディタでした。にはvi、テキストを入力するモードと編集するモードがあります。ではemacs、常にテキストモードになりますが、編集はキーの組み合わせを押すことで行われます(^b文字を後方に移動するなど)。

当時、シェルが独自の異なるキーバインディングを考案することは意味がありませんでした。それは人々が別のものを学ばなければならないためにフラストレーションを引き起こしたでしょう。ただし、一方のスタイル(emacsまたはvi)を他方のスタイルよりも選択することは、他のエディターのユーザーを疎外する確実な方法でした。

https://www.usenix.org/legacy/publications/library/proceedings/vhll/full_papers/korn.ksh.aによると:

kshの一般的なインライン編集機能(viおよびemacsモード)は、Bell Laboratoriesのソフトウェア開発者によって作成されました。Pat Sullivanによるviライン編集モード、Mike Veachによるemacsライン編集モード。それぞれが独自にBourneシェルを変更してこれらの機能を追加し、両方とも、kshにそれぞれのインラインエディターがある場合にのみkshを使用したい組織にいました。元々、コマンドライン編集をkshに追加するというアイデアは、行編集がターミナルドライバーに移行することを期待して拒否されました。ただし、これがすぐに発生する可能性が低いことが明らかになったとき、両方の行編集モードがkshに統合され、端末インターフェイスの一部として編集を提供するシステムで無効にできるようにオプションになりました。

そのため、代わりに、両方と、ユーザーが2つから選択するためのインターフェイスを実装しました。kshほとんどの場合、80年代前半に最初に(上記のように個別に記述されたコードを再利用してviモードとemacsモードをBourneシェルに追加)、その後tcshtcsh最初にemacsキーバインドのみがあり、viモードは後で追加されました)および後でbashそしてzsh90年代初期。

あなたは、2つのモードを切り替えbashzshまたはksh持つset -o viset -o emacs、ととbindkey -ebindkey -vtcshまたはzsh

POSIXは、実際に指定するviモードとないemacsためのモードsh(物語があることがあるリチャード・ストールマンが指定POSIXに反対emacsするためのモードをsh)。

デフォルトのモードではbash、パブリック・ドメインは、の変異体ksh(pdkshの、mksh、oksh)、tcshおよびzshEmacsのモード(とかかわらずであるzsh、それはですviあなたの場合$EDITOR、IS viAT&Tにいる間、) ksh、それはだダムない限り、モード$EDITORまたは$VISUAL言及viemacs

kshまた、後で異なる方法で処理されるgmacsGoslingのユーザーに対応するモードを追加しました。emacsCtrl+T

今の取扱い^Wemacsまたは中tcshのemacsモードは、おそらく以前からwerase私たちは本当にその約私の陳述のためにそれらを責めることはできないので、ターミナルラインエディタで文字を「...出発」誤解を招くとして見ることができます。を入力したときに、他のすべてのものとは異なる動作をしたりemacs、他のすべての動作と異なる動作をしtcshたりinfoすると、イライラするだけですCtrl-W。あなたがタイプしたときにいくつかのアプリケーションがウィンドウを閉じ始めたとき、私はそれがはるかにイライラすることを発見したと想像できます Ctrl-W


1
pdkshまた、起動時にモードを解析$EDITORviて切り替えます。私はそれを削除しましたmksh(特に、とにかくEmacsモードしか維持していないので)。
ミラビロス

特に、さまざまなシェルの動作と履歴に関する詳細な議論を追加していただき、ありがとうございます。私が設定しなかったシェルでさまざまなディストリビューションでの作業を定期的に要求される人として、これは非常に役立ちます。
-BryKKan

素晴らしい歴史的背景をありがとう。当時、より洗練されたインライン編集機能がターミナルドライバーに追加されなかったことは残念です。Readlineなどのライブラリをプログラムに含める必要はありません。また、なぜEmacsモードがPOSIXによって指定されていないのか不思議に思っていたので、理論的根拠へのリンクは興味深いものでした。(また、^Wウィンドウを閉じることに不満を感じています)。
アンソニーG-モニカの正義

1
@AnthonyGeoghegan、ファイル名/コマンド補完のようなものは実際にはターミナルドライバーで実行できなかったので、zle / readlineのようなものがまだ必要です。
ステファンシャゼル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.