vim tips その3

前回にひき続いてvimのtipsを紹介していきましょう。今回はコマンドラインモードについてまとめたいと思います。

コマンドラインモードとは

vimは :(コロン)をタイプすることでコマンドラインモードという特殊なモードに遷移することができあらかじめ用意された組み込みの動作を実行することができます。

コマンドラインモードの幾つかはノーマルモードで同等のことが実行でき、状況に応じて両者を使い分けることでより快適な編集ができることになると思います。

コマンドの構成を理解する

例えば三行目を削除するといった動作を考えてみましょう。
これは:3dというコマンドで実現できます。
まずはこのコマンドを紐解いていきます。
コマンドラインモードへ映るには:をタイプします。
さらにその後にある3はレンジを表します。今は単行を示していますが、複数行やファイル全体をレンジ対象とすることもできます。
最後にdに関してですが、これは指定したレンジに対する動作を表し、以前説明したオペレータと同様のものになります。

まとめるとバッファに対する編集操作を行うコマンドは下記のように構成されています

構成要素 意味
プレフィクス : コマンドラインを使用することを表す
レンジ 3 編集する対象範囲を表す
オペレータ d レンジに対する動作を表す

基本的なレンジ指定方法を理解する

先程は単行のレンジ指定を例として取り上げましたが、レンジ指定にはいろいろな指定ができ、これが非常に汎用性が高く便利なものなので、是非理解していきましょう。

下記に主要なレンジ指定を示したいと思います。

意味
1,5 指定の行を範囲とする。例では1行目から5行目までをレンジとする
.,5 .を用いて現在カーソルのある行を表せる。例では現在行から5行目までをレンジとする
5,$ $を用いてファイルの末尾を表せる。例では5行目からファイルの末尾までをレンジとする
% バッファ全体をレンジとする

例としてファイルの5行目から10行目だけを削除したい場合は下記のようにコマンドをタイプします

# 5行目から10行目を削除し、レジスタに格納する
:5,10d

またよくあるsubstituteコマンドによりファイル全体を置換するコマンドに関しても%を用いてバッファ全体をレンジに指定にしていると理解することができます

# ファイル置換コマンド。%はバッファ全体をレンジとすることを意味し、sは置換オペレータの省略形を意味する
:%s/before/after/g

パターンによるレンジ指定方法を理解する

直接的な行指定だけでなくコマンドにはパターンを用いたレンジ指定も可能です。

意味
/<html>/,/<\/html> 指定の行を範囲とする。例では1行目から5行目までをレンジとする

はじめは少し見慣れないかもしれないですが、実態としてはスラッシュ区切りで開始パターンと終了パターンを指定しているだけで、そこまで複雑なものではありません。

使用例として、たとえばbodyタグの内部をタグも含めて削除するような場合下記のようなコマンドとなります

:/<body>/,/<\/body>/d

下記のようなテキストファイルに対して上記のコマンドを実行します

<html>
  <body>
    textext
  </body>
</html>

結果は下記になります。bodyタグ含む内部が削除されていることがわかりますね。

<html>
</html>

またパターンに関して、パターンが存在する行からのオフセットを指定することもできます。

例として、htmlタグの内部のみを削除するような場合下記のようなコマンドとなります

:/<html>/+1,/<\/html>/-1d

同様に先ほどのテキストに対してコマンドを実行すると結果は下記のようになり、bodyタグを除いて内部が削除されていることがわかりますね。

<html>
  <body>
  </body>
</html>

コピー・移動コマンドを理解する

先に取り扱ったコマンドと同じような形で指定行のコピーや移動を行うことができます。
その構文は下記のようになります。これも見て行きましょう。

:{source}{command}{desctination}

それぞれのコマンドは下記のようになっています。

動作 コマンド 意味
バッファの内容をコピーする copy または t 任意の行のコピーを行う
バッファの内容を移動する move または m 任意の行の移動を行う

例えば下記のようなバッファに対して3行目の内容を4行目に移動したい場合を考えましょう。

<html>
  <body>
    <i>hogehoge</i>
    <div><p>fugafuga</p></div>
  </body>
</html>

その際には下記のようなコマンドで実現することができます。

:3t4

単行での例となりましたが、複数行でのレンジ指定ももちろん使用可能ですので非常に汎用性の高いコマンドとなります。

normalコマンドを理解する

こちらも非常に汎用性が高いもので、指定のレンジに対してノーマルモードで行いたいオペレータを適用することができます。
もちろんこちらはノーマルモードやビジュアルモードと併用したりしても同様のことが実現できます。
コマンドモードからの実行のほうが効率が良いこともありますので是非覚えておきましょう。

構文については下記のようになります

:{レンジ指定}normal {ノーマルコマンド}

例えばバッファ全体に対してコメントアウト(//)を追記したい場合下記のようにコマンドします

:%normal i//

一つ一つみていきましょう。
%レンジを指定しているので対象がバッファ全体となります。
その後にnomarlとタイプすることでnormalコマンドを実行できます。
半角スペースをひとつ開けて、続いてタイプした内容が実際のノーマルコマンドの内容となります。
ここではiを入力して挿入モードに遷移し//をタイプしているため、全行のコメントアウトということが実装できるわけです。

またお察しの良い方は気づいているかもしれませんが、normalモードを実行する際にはカーソルの位置は暗黙的に行の先頭に初期化されます。

コマンドラインウインドウを理解する

vimでは実行したコマンド履歴を保存しており、それらを参照したり編集したりすることができます。
コマンドラインウインドウを開くにはq:とタイプします。
(すこし:qと紛らわしいですので注意ですね。)

コマンドを実行すると過去の実行履歴がサブウインドウによって開かれます。
コマンドラインウインドウは通常のvimウインドウと同じように編集することができ、編集を保存し終了するときなども同様に:wqで行うことができます。
またUpキーやDownキーにより、過去のコマンドを選択することができ、エンターキーをタイプすると現在のウインドウに対して過去実行したコマンドを再度実行することが可能です。

シェルとのやりとりを理解する

またvimはシェルとも非常に親和性が高く、vimを起動中にシェルを呼び出したり、その標準出力や標準入力に関してやりとりすることが可能です。

まずvimの中からshellを実行するには下記のようなコマンドになります

:!{任意のコマンド}

例えばlsコマンドを叩く場合は下記のようになります

:!ls

コマンドを実行すると一度vimではなくシェルウインドウが開き、結果が表示されます。
その状態からエンターキーをタイプすると再びvimの画面へと戻ってくるような流れになります。

ワンライナーでの実行ではなくシェルとインタラクティブに対話したいときは

:shell

と実行することでシェルが起動します。これは通常のシェルと同様で、再びvimに戻る場合はexitを用いてシェルを終了する必要があります。vimの編集している状態を残しつつ一時的にシェルを起動したい時など非常に有用だと思います。

またバッファの内容をシェルとやりとりすることができます。

vimからシェルを呼び出しその実行結果(標準出力)を現在のバッファに挿入する場合はreadコマンドを用います。
例えばlsの結果をバッファに挿入したい場合は下記のようになります

:read !ls

逆にバッファの内容をシェルの標準入力に挿入する場合はwriteコマンドを用います。
例えばphpスクリプトを記述していて、それをvimの中から呼び出す場合なんかは下記のようになります。

:write !php

最後に範囲指定で!コマンドを行うとバッファの内容をシェルに渡したあと、結果で選択範囲のバッファを上書きすることもできます。

例えば下記のようなテキストがあった場合
対象をgmail.comのユーザのみに絞り込みたいとします。

id,name,email
1,Bob,ex1@gmail.com
2,Jobeth,ex2@yahoo.com
3,Steven,ex3@gmail.com
4,Smith,ex4@yahoo.com

この際に2行目から最終行までをレンジ選択して、grepコマンドを用いてフィルタリング処理を行ってみましょう。

:2,$ !grep @gmail.com

結果として下記のようにフィルタリング処理が実行できています。

id,name,email
1,Bob,ex1@gmail.com
3,Steven,ex3@gmail.com

いかがでしたでしょうか。
非常に汎用性の高いコマンドが多く、便利なものばかりですね。
またシェルとのやりとりも覚えることで、別窓で処理したり、一度vimを閉じてから・・・などという手間もなくなるので覚えておきたいですね!

1 個のコメント

  • […] するとvimは内部でそれぞれのファイルに対応するバッファを展開します。 この様子は下記のexコマンドを実行することで、展開しているバッファの様子を確認することができます。 (exコマンドには前回説明しましたので、わからない方は参照してみてください。) […]

  • コメントを残す

    メールアドレスが公開されることはありません。 が付いている欄は必須項目です

    このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください