1. ホーム
  2. vim

[解決済み] Vimで最も生産性の高いショートカットは何ですか?

2022-03-16 22:44:17

質問内容

について、よく耳にするようになりました。 ヴィム 長所も短所も。 Vim は他のエディタより(開発者として)速いはずです。 私はVimを使って基本的なことをやっていますが、せいぜい10倍程度です。 生産性低下 Vimで。

速度の話をするときに気にすべきなのは、次の2つだけです(十分には気にしないかもしれませんが、気にする必要があります)。

  1. 左と右を交互に使う ハンドは 最速 を使用する方法です。 キーボード
  2. マウスを触らないというのは 2つ目の方法は、できるだけ速くすることです。 手を動かすのに時間がかかる。 マウスを掴んで、動かして、戻す。 キーボードに戻る(しかも、しばしば キーボードに目をやるのは 正しい位置に手を戻す)

Vimを使うとなぜ生産性が落ちるのか、2つの例を挙げてみましょう。

コピー/カット & ペースト。 いつもやっていますよ。現代のすべてのエディターで、あなたは シフト 左手でテキストを選択し、右手でカーソルを移動させる。そして Ctrl + C をコピーすると、カーソルを移動して Ctrl + V を貼り付けます。

Vimだと恐ろしいことになります。

  • yy で1行コピーします(行全体をコピーすることはほとんどありません!)。
  • [number xx]yy をコピーする xx の行をバッファに入れます。しかし、自分が望んでいたものを選択できたかどうか、正確にはわからないのです。私はよく [number xx]dd では u を元に戻す!?

別の例? 検索&置換を行います。

  • PSPad : Ctrl + f と入力し、検索したい内容を入力して 入力 .
  • Vimの場合 / を入力し、検索したいものを入力し、特殊文字がある場合は \ 前に 特殊文字を入力し 入力 .

そして、Vimのすべてがそうです。私は正しい方法で処理する方法を知らないようです。

NB : 私はすでにVimの 騙す シート :)

質問です。

Vimの使い方の中で、現代のエディタよりも生産性が高いのはどのような点ですか?

解決方法は?

に関する問題 ヴィム を理解できていないことです。 vi .

でカットするとありますが yy と、行全体を切りたいことはほとんどないと不満を述べています。 実際、プログラマはソースコードを編集するとき、行全体、行の範囲、コードのブロックなどを編集したいと思うことが非常に多いのです。 しかし yy は、テキストを匿名コピーバッファ(または ヴィ ).

の「禅」。 ヴィ は、言語を話しているということです。 最初の y は動詞です。 文は yy は同義語で y_ . その y は、よくある操作なので、入力しやすいように二重になっています。

これは次のように表すこともできます。 dd P (現在の行を削除し、コピーを元の場所に貼り付けます。副次的に匿名レジスタにコピーを残します)。 このとき yd 動詞はどんな動きも主語にします。 yW は "ここ(カーソル)から現在の/次の(大きな)単語の終わりまで引っ張る" であり y'a は、ここから''というマークがある行まで引っ張ります。 a '."

カーソルの上下左右の基本的な動きしか理解できていないのであれば ヴィ は、あなたにとって "notepad" のコピー以上の生産性はないでしょう。 (もちろん、シンタックスハイライトや、~45KB程度の小さなファイルより大きなファイルを扱う能力はありますが、ここでは私と一緒に働きましょう)。

vi は26個のマークと26個のレジスタを持ちます。 m コマンドを使用します。 各マークは小文字1文字で指定される。 このように ma は、' a ' マークを現在の位置に、そして mz は、' z マークが表示されます。 マークを含む行への移動は ' (シングルクォート)コマンドを使用します。 このように 'a を含む行の先頭に移動します。 a マークが表示されます。 マークの正確な位置への移動は ` (バッククオート)コマンドを使用します。 このように `z の正確な位置に直接移動します。 z マークが表示されます。

これらは「動き」であるため、他の「文」の主語としても使用できます。

そこで、任意の選択テキストをカットする一つの方法として、マークをドロップする(私は通常' a を最初のマークとして、' z ' を次のマークとして、' b を別のものとして、そして' e を15年間使ってきて、4つ以上のマークをインタラクティブに使った記憶はない。 ヴィ マークやレジスタがマクロによってどのように使用されるかについては、対話的な文脈を妨げない範囲で自分なりの慣例を作る必要があります)。 次に、目的のテキストのもう一方の端に行きます。どちらの端から始めてもかまいません。 そして、単純に d`a でカットしたり y`a でコピーします。 したがって、この処理全体では5回のキーストロークがオーバーヘッドとなります("insert" モードで開始し、以下の処理が必要な場合は6回)。 エスケープ コマンドモード)。 カットまたはコピーした後、コピーを貼り付けるのは1回のキー操作で済みます。 p .

これは、テキストをカットしたりコピーしたりする方法の1つだと言います。 しかし、これは数ある方法のうちのひとつに過ぎません。 カーソルを動かしてマークを落とさずに、テキストの範囲をもっと簡潔に表現できることがよくあります。 たとえば、テキストの段落の中にいる場合、次のように記述します。 {} をそれぞれ段落の先頭と末尾に移動させます。 つまり、テキストの段落を移動するには { d} (キー操作3回)。 (もし私がすでに段落の最初の行か最後の行にいるのなら、単に d} または d{ をそれぞれ指定します。

段落の概念は、通常、直感的に合理的なものに設定されています。 したがって、これはしばしば散文と同様にコードにも有効です。

私たちはしばしば、興味のあるテキストの片方またはもう片方を示す何らかのパターン(正規表現)を知っています。 前方や後方を検索するのは、以下のような動きである。 ヴィ . したがって、これらは文の中で主語として使用することもできます。 d/foo という文字列を含む行を現在の行から次の行に切り出すために使用します。 y?bar を使えば、現在の行から "bar." を含む最新の(前の)行にコピーすることができます。 `x コマンドを使用します。

動詞と主語の他に、quot;verbs" とquot;subject" があります。 ヴィ は、(文法的な意味での)オブジェクトも持っています。 ここまでは、匿名ダイアログの使い方について説明しました。 しかし、26個の"named"レジスタのどれでも、次のようにして使うことができます。 接頭辞 オブジェクトの参照に " (ダブルクォート修飾子)。 したがって、もし私が "add 現在の行を切り取って、' a 'を登録し、もし私が "by/foo とすると、ここから次の "foo" を含む行までのテキストをコピーして、'Submit' に取り込んでいます。 b レジスター レジスタからペーストするには、ペーストの前に同じ修飾語を付けるだけです。 "ap のコピーを貼り付けます。 a レジスターの内容をカーソルの後のテキストに挿入し "bP からのコピーを貼り付けます。 b ' を現在の行の前に置く。

この接頭辞の概念は、文法的な形容詞や副詞のようなものをテキスト操作の言語に追加するものです。このように 3J は「次の3行を繋ぐ」という意味であり d5} は「現在の行からここから5つ下の段落の終わりまでを削除する」という意味です。

これはすべて中級レベル ヴィ . どれも ヴィム にはもっと高度なトリックがあります。 vi を学ぼうと思えば学べます。 なぜなら、テキスト操作言語は十分に簡潔で表現力があり、エディタ本来の言語を使ってほとんどのことを簡単に行うことができるからです。


より高度なトリックの一例です。

は数多く存在します。 : コマンド、特に :% s/foo/bar/g グローバル置換のテクニック (それは高度なものではありませんが、他の : コマンドは可能です)。 全体の : コマンドのセットは、歴史的に vi の前身である エド (ラインエディタ)、そして後に エクス (拡張ラインエディタ)のユーティリティです。 実際 ヴィ の視覚的なインターフェイスであるため、この名前が付けられました。 エクス .

: コマンドは通常、テキスト行に対して操作します。 エド は、端末画面が一般的でなく、多くの端末がテレタイプ(TTY)であった時代に書かれたものです。 そのため、印刷されたテキストをもとに、非常に簡潔なインターフェイスでコマンドを使用するのが一般的でした (一般的な接続速度は 110 ボー、つまりおよそ 1 秒間に 11 文字で、これは高速タイピストよりも遅く、マルチユーザーの対話型セッションでは遅延がよく発生し、さらに用紙を節約する動機もよく見られました)。

そのため、ほとんどの : コマンドは、アドレスまたはアドレスの範囲(行番号)の後にコマンドを記述します。 もちろん、リテラルな行番号を使うこともできます。 :127,215 s/foo/bar と入力すると、127から215までの各行で最初に出現する "foo" を "bar" に変更します。 また、次のような省略形も使用できます。 . または $ はそれぞれ現在の行と最後の行を表します。 また、相対的な接頭辞を使うこともできます。 +- で,それぞれ現在の行の後と前のオフセットを参照します。 したがって :.,$j の意味は、「現在の行から最後の行まで、すべて1行に結合する」です。 :% と同義です。 :1,$ (全行)です。

は、その :... g:... v コマンドは、非常に強力なので、少し説明が必要です。 :... g は、パターン (正規表現) に一致するすべての行に後続のコマンドをグローバルに適用するための接頭辞であるのに対し :... v は、与えられたパターン("conVerse"の"v")にマッチしないすべての行にそのようなコマンドを適用します。 他の ex コマンドの前に、アドレスや範囲を指定することができます。 このように :.,+21g/foo/d は、現在の行から次の21行目までの、文字列 "foo" を含むすべての行を削除することを意味します。 :.,$v/bar/d ここからファイルの終わりまで、文字列 "bar." を含まない行をすべて削除することを意味します。

面白いことに、Unixの一般的なコマンドである グレップ は、実はここから着想を得ています。 ex コマンドを使用することができます(そして、このコマンドのドキュメントに記載されている方法にちなんで命名されました)。 その ex コマンド :g/re/p (grep)は、quot;正規表現(re)を含む行をグローバルに"印刷"する方法を文書化したものでした。 このとき が使用されていた場合 :p コマンドは、誰もが最初に習うコマンドの一つで、どんなファイルでも編集するときに最初に使うことが多いものでした。 これは、現在の内容を印刷する方法です。 :.,+25p など)。

なお :% g/.../d または(そのreVerse/conVerseの対応するもの。 :% v/.../d が最も一般的な使用パターンです。 しかし、他にもいくつかの ex コマンドは覚えておくとよいでしょう。

私たちは m で行を移動させ j で行を結合します。 例えば、リストがあって、あるパターンにマッチするもの(逆にマッチしないもの)を削除せずにすべて分けたい場合、次のような使い方ができます。 :% g/foo/m$ ...すると、すべての "foo" 行がファイルの末尾に移動したことになります。 (ファイルの最後をスクラッチスペースとして使用するという他のヒントに注意してください)。 これにより、すべての "foo" 行の相対的な順序が維持され、残りのリストから抽出されたことになります。 (これは、次のようなことと同じです。 1G!GGmap!Ggrep foo<ENTER>1G:1,'a g/foo'/d (ファイルを自身の末尾にコピーし、末尾にフィルターを通して grep そして、headのものをすべて削除してください)。

行を結合するには、通常、前任者と結合する必要があるすべての行のパターンを見つけることができます(たとえば、いくつかの箇条書きのリストで "^ * " ではなく "^ " で始まるすべての行)。 このような場合、私ならこうします。 :% g/^ /-1j (一致する行ごとに、1行上に移動して結合する)。(ところで、箇条書きリストの場合、箇条書きの行を検索して次の行に結合しようとすると、いくつかの理由でうまくいきません...ある箇条書きの行を別の箇所に結合することができますが、どの箇条書きの行も、その行を すべて の連続したもので、マッチしたものに対してのみペアとして機能します)。

言うまでもないことですが、私たちの古い友人である s (代用)を使って gv (global/converse-global)コマンドを使用します。 通常、そのようなことは必要ありません。 しかし、他のパターンにマッチする行にのみ置換を行いたい場合を考えてみましょう。 多くの場合、キャプチャを使った複雑なパターンを使用し、変更したくない行の部分を保持するために後方参照を使用することができます。 しかし、多くの場合、マッチと置換を分離する方が簡単でしょう。 :% g/foo/s/bar/zzz/g -- "foo" を含むすべての行について、すべての "bar" を "zzz." で置き換える(以下のようなもの)。 :% s/\(.*foo.*\)bar\(.*\)/\1zzz\2/g は、同じ行で "foo" に先行された "bar" のインスタンスに対してのみ機能します。すでに十分不格好ですし、 "bar" が "foo" に先行するすべての場合を捕らえるためにさらにマングリングしなければならないでしょう)。

要は p , s および d の行は ex コマンドセットを使用します。

: のアドレスは、マークを参照することもできます。 したがって、使用することができます。 :'a,'bg/foo/j の間の行にある場合、文字列fooを含む任意の行をその次の行に結合します。 a と' b のマークがあります。 (そう、前のすべての ex コマンドの例は、この種のアドレス指定表現を前に付けることで、ファイルの行の一部に限定することができます)。

かなり曖昧ですね(この15年間で数回しか使ったことがない)。しかし、正しい呪文を考え出すのに時間をかければ、おそらくもっと効率的にできたであろうことを、私はしばしば反復的かつ対話的に行ってきたことを、自由に認めます。

もう一つ、とても便利なものがあります。 ヴィ または エクス コマンドは :r を使えば、他のファイルの内容を読み込むことができます。 このように :r foo は、現在の行に "foo" という名前のファイルの内容を挿入します。

より強力なのは :r! コマンドを使用します。 これは、あるコマンドの結果を読み出すものです。 を一時停止するのと同じです。 vi セッションを再開し、コマンドを実行し、その出力を一時ファイルにリダイレクトし、その後に vi セッションを開始し、一時ファイルから内容を読み込む。

さらに強力なのは ! (バン) と :... ! ( bang)コマンドを使用します。 これらも外部コマンドを実行し、その結果を現在のテキストに読み込んでいます。しかし、このコマンドでは、テキストの選択部分をフィルタリングすることもできます。 このように、ファイル内のすべての行を並べ替えるには 1G!Gsort ( G ヴィ デフォルトではファイルの最終行に進みますが、1 のように行番号を前に付けて最初の行に進むこともできます)。 これは、次のコマンドと同じです。 ex バリアント :1,$!sort . ライターがよく使うのは ! と共に、Unixの エフエムティー または 折りたたみ は、選択されたテキストを整形したり、ワードラッピングしたりするユーティリティです。 非常に一般的なマクロは {!}fmt (現在の段落を再フォーマットする)。 プログラマーは、このツールを使って、自分のコードやその一部を インデント などのコード再フォーマットツールに対応しています。

を使用すると :r!! コマンドは、外部のユーティリティやフィルタをエディタの拡張機能として扱えることを意味します。 私は時々、データベースからデータを取得するスクリプトや、あるいは ウィジェット または リンクス ウェブサイトからデータを取得するコマンドや ssh コマンドは、リモートシステムからデータを引き出すためのものでした。

もう一つの便利な機能 エクス コマンドは :so (略 :source ). これは、ファイルの中身を一連のコマンドとして読み込むものです。 を起動すると vi は通常、暗黙のうちに :source について ~/.exinitrc ファイル(および ヴィム は通常 ~/.vimrc 当然ですが)。 これを利用すると、新しいマクロ、省略形、エディタ設定のセットをソースに入れるだけで、エディタプロファイルをその場で変更することができます。 もしあなたがずる賢ければ、これを一連の ex 編集コマンドをファイルに対してオンデマンドで適用することができます。

例えば私は7行のファイル(36文字)で、ファイルを実行します。 wc そして、その語数データを含むC言語スタイルのコメントをファイルの先頭に挿入します。 そのマクロをファイルに適用するには、次のようなコマンドを使用します。 vim +'so mymacro.ex' ./mytarget

(この + のコマンドラインオプションで vi ヴィム は通常、指定された行番号から編集セッションを開始するために使用されます。 しかし、あまり知られていないことですが、このように + を、任意の有効な ex コマンドや式、例えば私がここで行ったような "source"コマンドなどです。簡単な例として、私は起動するスクリプトを持っています。 vi +'/foo/d|wq!' ~/.ssh/known_hosts を使用して、SSH known hosts ファイルからエントリを削除することができます(サーバーのセットを再イメージングしている間、非対話的に)。

通常、PerlやAWKを使ってこのようなマクロを書く方がはるかに簡単です。 セッド (これは、実際には グレップ に触発されたユーティリティです。 エド コマンド)を使用します。

@ コマンドは、おそらく最もわかりにくい vi コマンドを使用します。 10年近く上級システム管理のコースを時々教えてきましたが、これを使ったことのある人にほとんど会いませんでした。 @ は、レジスタの内容をあたかも vi または エクス コマンドを使用します。
例 私がよく使うのは :r!locate ... を使ってシステム上のファイルを探し、その名前を文書に読み込ませる。 そこから余計なヒットを削除し、目的のファイルへのフルパスのみを残す。 苦労して タブ -のコピーでタブ補完をサポートしていないマシンで、パスの各コンポーネントを調べている場合(もっとひどい場合は vi を使うだけです。

  1. 0i:r (現在の行を有効な :r コマンドを使用することができます)。
  2. "cdd (行を "c"レジスタに削除する場合) と
  3. @c はそのコマンドを実行します。

たった10回のキー操作で(しかも式は "cdd @c は、私にとっては事実上フィンガーマクロなので、一般的な6文字の単語とほぼ同じ速さで入力できます)。


しみじみとした思い

まだ表面しか見ていませんが ヴィ のパワーの一部でもありませんし、ここで説明したようなことは vim という名前がついています。 ここで説明したことは、どんな古いバージョンの vi 20年前、30年前のものです。

をかなり多く使っている人がいます。 ヴィ の力は、私よりもずっと大きい。