vim-users.jp

Hack #30: 範囲を指定してコマンドを実行する

Posted at 2009/06/22
このエントリーをはてなブックマークに追加

Vim のコマンドの中には範囲を指定できるものがあります。範囲を指定することで、より細かい指示を Vim に与えることができます。ここでは範囲の指定の仕方について解説します。

範囲を与えられるコマンド

まず最初に注意したいのですが、全てのコマンドに対して範囲を指定できるわけではありません。範囲が指定できるものに関しては help 内で :{range}command:[range]command などと表記されています。また、:! などのように範囲を指定するかどうかで動作が変わるコマンドも一部あります。

また、範囲ではなくカウントを与えるコマンドもあります。:tag などがそうです。が、指定方法に大差はありません。扱われ方が違うだけです。

範囲を指定できるコマンドに対して範囲指定を省略した場合、多くのコマンドは現在の 1 行のみを指定したことになります。ただし例外もあります。例えば、:global:sort は範囲指定を省略するとファイル全体を指定したことになります。

範囲の指定方法

基本

範囲は行単位で指定します。つまり、ある行からある行まで、ということです。最も単純な例を示します。

:10,20command

これは 10 行目から 20 行目の間の範囲に対して command を実行する、という意味です。ここで、10 や 20 の部分を行指定子と呼びます。行指定子には具体的な数字以外にも以下のものが使用できます。

行指定子説明
{number}絶対的な行番号です。0 から最終行までの範囲である必要があります。0 を指定した場合、多くのコマンドは 1 として解釈しますが、:read のような一部のコマンドや続けて検索をする行指定子を指定する場合などは「先頭行の前」として解釈します。また、カウントを与えるコマンドの場合はそのまま 0 として使われます。
.現在の行です。
$最後の行です。
%ファイル全体です。1,$ を指定したのと同じになります。
m' で移動できるマークです。大文字のマークの場合同じファイルに対するマークだった場合のみ使用可能です。
/{pattern}[/] ?{pattern}[?]次に {pattern} にマッチする行です。/ は下向き、? は上向きになります。最後の /? は、パターンとその後の項目とを区別する場合に必要です。
\/ \?現在行から次に直前に使われた検索パターンにマッチする行です。/ は下向き、? は上向きになります。
\&現在行から次に直前に使われた置換元パターンにマッチする行です。

例: 現在行から最終行を html にしてファイルに出力(参考: Hack #23: Vimでハイライト表示させたコードを見た目そのままにHTML出力させる)

:.,$TOhtml

行指定子を指定する数

行指定子は 1 つだけ指定することも可能で、その場合指定した 1 行のみが範囲になります。

また、3 つ以上指定することも可能です。この場合、最後の 2 つの範囲が指定されたことになります。このようなことが許可されているのは現在行を調整できるようにするためです。

行指定子の区切り

行指定子は カンマ(,)かセミコロン(;)で区切ります。 セミコロンで区切った場合、次の行指定子を解釈する前にカーソルが前の行指定子で指定した行に移動します。 コマンド実行後にもカーソルの位置は移動したままです。

例: 次の “class” で始まる行から、その行より下にある次の “end” で始まる行までを削除

:/^class/;/^end/delete

この例をカンマで区切った場合、現在の行から “class” より近い位置に “end” があった場合、予期しない結果になるでしょう。 セミコロンで区切ることでまず “class” の行に移動し、その後 “end” を探します。ただし、結果としてコマンド実行後にカーソルが移動してしまいます。

相対行指定

各行指定子の末尾には、+n -n のように相対行を指定することができます。複数回指定することも可能です。n を省略すると 1 を指定したことになります。

例: 次の “class” で始まる行の次の行から、その行より下にある次の “end” で始まる行の前の行までを削除

:/^class/+1;/^end/-1delete

検索系の行指定子の指定

検索を行なう行指定子 “/” と “?” は、行指定子の更に後に指定することができます。これを利用すると検索の開始位置を調整できます。セミコロンで区切った場合と違い、カーソル自体は移動しません。

例: カーソルを移動せずに、次の “class” で始まる行から、その行より下にある次の “end” で始まる行までを削除

:/^class/,/^class//^end/delete

先ほどのセミコロンで区切った場合と違い、カーソルが移動することはありません。

自動で入力される範囲

Visual mode

Visual mode から Command-line mode に入ると、プロンプトに以下のような文字列が自動的に挿入されます。

:'<,'>

ここで、’< は Visual mode 最後に選択した範囲の最初の行、’> は最後の行を表すマークです。つまり、Visual mode から Command-line mode に入ると自動的に今選択していた範囲を対象にコマンドを実行することができます。

count

Normal mode で数字を入力してから Command-line mode に入ると、プロンプトに以下のような文字列が自動的に挿入されます。

:.,.+(count - 1)

例えば、5: と入力すると :.,.+4 と入力された状態になります。これはつまり、現在の行から 5 行分という意味です。

範囲の反転

指定した範囲の開始行が終了行より下だった場合、Vim は開始行と終了行を入れ替えても良いか訊いてきます。許可した場合のみ、コマンドは実行されます。:silent コマンドを前置してコマンドを実行することで、確認せずに入れ替えて実行させることができます。また、:global コマンドに対して指定するコマンドでも入れ替えの確認は行われません。

範囲の指定方法について紹介しましたが、多くの機能は普段はあまり使いません。ほとんどの場合 Visual mode との組み合わせで事足りると思います。稀に Vim script を書く際に便利なこともありますが、こんな機能もある、程度の認識で問題ないでしょう。

thinca

もどる
blog comments powered by Disqus