第 11 章マクロ これは、検索語の次のマッチへカーソルを移動させること ) かもしれないし、カー ソル行の先頭にカーソルを移動させること ( 0 ) かもしれないし、現在のファイルの先 頭行にカーソルを移動させること ( 空 ) かもしれない。多くの場合、何かの先頭から 始めることで、毎回のマクロ実行時に、正しいターゲットを撃ち抜くのが簡単になる。 繰り返し可能なモーションでターゲットを撃破しよう Vim ではたくさんの種類のモーションを使って、テキストファイルをあちらこちら に移動できる。これらをうまく使おう。 カーソルが目的地にたどり着くまで、一を叩き続けたりしてはいけない。思い出そ う。自分が入力したキーストロークを Vim は何も考えずに実行する。マクロの記録時 に、カーソルを 10 文字右に移動して、目的地にカーソルが到着した。でも、これをあ とから再生するとどうなるだろう。別の場面では、カーソルを 10 文字右に移動させる と、目的地をいきすぎたり、目的地まで届かないこともあるかもしれない。 ト、ふなど、単語単位のモーションのほうが、ふーという文字単位のモーショ ンよりも柔軟性が高くなることがよくある。 0 に続けてトというモーションを己録する と、実行するたびに予想どおりの結果が得られると考えられるだろう。カーノル行の 最初の単語の最後の文字にカーソルが移動する。その行に最低でも 1 つの単語があれ ば、単語の文字数はどうでもいい。 検索を使ってカーソルを移動しよう。テキストオプジェクトを使おう。マクロの柔 軟性を最大限に高めて、可能な限り繰り返し可能とするために、 Vim が用意している あらゆるモーションをフルに活用しよう。忘れちゃいけない。マクロを記録するとき に、マウスを使うのは御法度だ ! モーションに失敗したら処理は中断する モーションは失敗することがある。たとえば、ファイルの先頭行にカーソルがある 状態で、第コマンドを実行しても何も起こらない。ファイルの最後の行にカーソルがあ る状態での」コマンドも同じだ。デフォルトでは、モーションが失敗すると、 Vim は ピープ音を鳴らしてくれる。ただし、「 visualbell 」設定によって、これを鳴らさな いようにもできる ( → : h ' visualbell , ①◎ ) 。 216
索引く ・・ 57 オペレータ待機モードとテキストオプジェ クト・ ・・ 169 オムニ補完・ ・・ 365 , 366 zz コマンド . あ アクション・ 値渡し・ アドレス・ アンドゥコマンド アンドゥコマンドの粒度・ ・・ 25 , 33 , 51 , 52 ・・ 287 カーソル位置・ ・・ 85 , 86 ・・ 19 カーソル位置にある単語をコマンドプロ ・・ 33 , 42 , 181 ンプトに挿入・ ・・ 43 ・・ 99 カーソル位置に記述されているファイル 名のファイルにジャンプ・・ ・・ 183 以前に行った検索の呼び出し・ カーソル位置の正規化・ ・・ 261 ・・ 215 , 220 以前の quickfix リストから結果を呼び戻 カーソル位置の単語をレジスタ a にヤン す・ ク・ ・・ 338 ・・ 196 カーソル移動・ イテレータ・ ・・ 230 ・・ 28 カーソル移動用のキー入力が 1 つ、何か インクリメンタルサーチ・ ・・ 263 を実行するキー入力がもう 1 つ・・・ 30 インクルードされるファイル・ ・・ 359 インデックス・ カーソルキー ・・ 320 ・・ 151 カーソル行をレジスタ b にカット・・・ 196 回数指定・・ ・・ 47 回数を指定してマクロを再生・ ウインドウ・ ・・ 124 ・・ 217 ウインドウの位置変更・ 外部のコマンドを介してバッフアの内容 ・・ 127 ウインドウのサイズ変更・ をフィルタリング . ・・ 127 ・・ 107 ウインドウ間のフォーカスを変更する 外部プログラム・ ・・ 104 カウント・ ・ 126 ・・ 47 ウインドウを閉じる・ 画家・ ・ 127 ・・ 42 隠しバッフア・ ・・ 122 隠しファイル・ ・・ 121 ・・ 244 カスタマイズを特定のファイルタイプに 適用する・ ・・ 380 カスタムオペレータ・ ・・ 52 ・・ 89 カスタムモーション・・ ・・ 53 仮想置換モード・ ・・ 51 , 52 ・・ 54 カッコからカッコにジャンプ・ か う え 工スケープ・・ お モ 機 待 トタタ セレレ オオオ ・・ 63 , 64 ・ 174 393
TIPIO : 回数指定を使って簡単な計算を行うく T 旧 10 : 回数指定を使って簡単な計算を行う ノーマルモードの大半のコマンドは回数を指定して実行できる。この機能を 使うと、ちょっとした計算を行える。 ノーマルモードで利用可能なコマンドの多くは、コマンドの前に回数 ( カウント ) を 指定できる。コマンドを 1 回だけ実行するのではなく、 Vim はそのコマンドを指定し た回数だけ実行しようとする ( → :h countOO)0 叱と 59 : をは数値の加算もしくは減算を行うコマンドだ。カウントなしで実行す ると、 1 だけ加算 / 減算されるが、コマンドの前にカウントを指定すると、指定した 数だけ加算 / 減算される。たとえば、「 5 」という文字の上にカーソルがあるときに 記」を実行すると「 5 」が「 15 」に変わる。 でも、カーソルが数字の上になかったらどうなるだろう。ドキュメントによれは 30H ミ当 コマンドは「カーソル位置もしくはカーソル以降にある数に指定した数を加算する」 とある ( → :h Ctr1-aOO)0 ということは、カーソルが数字の上にない場合、 : 叱 コマンドは現在行にある数字を探す。数字があれば、カーソルがそこに移動する。 れを使うと便利なことができる。 以下に CSS のコード片を示そう。 normal-mode/sprite. css ・ blog, ・ news { background—image : url (/sprite ・ png) ; } . blog { background-position: Opx Opx } 2 行目をコピーして、そこに 2 つほど変更を加えよう。「 b1 。 g 」を「 news 」に置き換 えて、「 0px 」を「一 180PX 」にするのだ。行のコピーは yyp で行える。そうしたら、 で最初の単語を変更する。でも、数字についてはどうすればよいだろう。 で数字にカーソルを移動してから、挿入モードに入って、手でこの値を変更する というのは 1 つのやり方だろう。コマンドにすると第 18 く Esc > だ。だが、一 40 、この ほうが手つ取り早い。最初、カーソルは数字の上にないので、カーソル以降で最初に ある数字にジャンプする。これにより、手でカーソルを移動する手順を省ける。この 作業手順を実際に見てみよう。 47
第 8 章モーションによるファイル内の移動 ; コマンドと , コマンドは相補的なコマンドだ。どちらかを使えないようにしてし まうと、文字検索コマンドが全体として使いづらいものになってしまう。 検索対象を文字検索に含めるか、含めないか 文字検索コマンドにはえなコマンド、一コマンド、一コマンド以外のコマンドも ある。以下の表にすべての文字検索コマンドをまとめておこう。 コマンド ま { char 敢 char V{char char 動作 次にある { char } までカーソルを末尾方向に移動 前にある { char } までカーソルを先頭方向に移動 次にある { char } の直前の文字までカーソルを末尾方向に移動 前にある { char } の直後の文字までカーソルを先頭方向に移動 直前の文字検索コマンドを繰り返す 直前の文字検索コマンドを逆方向に繰り返す : ) コマンドと ) コマンドは、指定した文字の手前まで (till) を検索す ると考えよう。カーソルは { char } の 1 文字手前で止まる。一方、なコマンド と言コマンドは指定した文字の上にカーソルを移動させる。 両方の種類の文字検索が必要な理由はちょっとわかりにくい。実際に例を見てみ よう。 キーストローク {start} バッフアの内容 臼 've been expecting you, Mister Bond. I 've been expecting yo Mister Bond. I ' ve been expecting yo まず、カーソルをカンマ記号の上にそのまま移動させたい。これには、、コマンド を実行する。次に、センテンスの末尾までのテキストをすべて削除したい。ただし、 ピリオド記号自体は残しておきたい。今度は並 , コマンドでこれを行う。 あるいは、 4 を使うのもありだろう。これは、カーソル位置から「 Bond 」の最後 の文字までをすべて削除する。最終的な結果は同じだが、 4 いのほうが認識しやすい 162
TlP2 : DRY (Don't Repeat YourseIf) く だろう。しかし、それでは能がない。 ドットコマンドは直前の変更を繰り返すのだか ら、まったく同じキー操作をするのではなく、龜 : と 2 回やればよいのではないだろう か。ドット 0 ) 1 つで 3 つのキーストロークは; く Esc>) の代わりになる。ほんの少 しの節約だが、これを繰り返すことで、効率が高まっていく。 しかし、というやり方をもっとよく見てみよう。」コマンドでカーソルを 1 行下 に移動する。そのあとに、コマンドでカーソルを行末に移動する。ドットコマンドを 使えるようにカーソルを移動させるためにキー操作を 2 回行っている。 ーこに改善の 余地がある、わかるかな。 余計なカーソル移動をなくす ミコマンドはカーソルの現在位置の後ろに追加を行う。対して、一コマンドは現在の 行の末尾に追加を行う。このとき、カーソルがどこにあるかは関係ない。ーを押せば、 挿入モードになり、カーソルは行末に移動する。つまり、を一度のキーストローク にまとめられる。「 1 つのお値段で 2 つ ! 」 ( 30 ページ ) では、 Vim にはこのような複 合コマンドがいくつも用意されているのを紹介しよう。 上のサンプルをもう少しカッコよくしたものが以下だ。 キーストロークバッフアの内容 ar f00 var bar var foobar = f00 + bar var f00 var bar var foobar = f00 + bar f00 = var bar var foobar = f00 + bar f00 = var foobar f00 + bar var f00 var bar var foobar f00 + じゃなく一を使うことで、ドットコマンドの威力も増した。行末を変更したいの で、さっきはそこにカーソルを移動する必要があったが、今度はその必要はない。そ 29 1
第 8 章モー よう。 キーストローク {start} ションによるファイル内の移動 バッフアの内容 ind the first occurrence Of {char} and move tO ind the first occurrence Of {char} and move tO Find the first ・ ccurrence Of {char} and move tO it . it . it . 文字 x がある この例では、コマンドでは何も起こらない。 Vim は行末に向けて、 かを検索するが、マッチしないので、カーソルは動かすにそのままだ。コマンドは だからといって、いつでもをな新メコマンドでこんなにうまくいくとは限らない。 感じるくらいだ。 この例のようにうまくいったときには、 Vim が自分の心を読んでいるんじゃないかと ロークよりも少ない手順でこれを行う方法はない。な可コマンドは効率的であり、 単語。 ccu て rence の先頭にカーソルを移動する必要があるときに、 2 つのキースト 文字。があるのをみつけるので、カーソルは最初にマッチする部分に移動する。 カーソルを { c れ ar } の先頭の c に移動したいとする。コマンドを使うとどうなるかを 見てみよう。 キーストローク {start} バッフアの内容 ind the first occurrence Of Find the first 0 currence Of Find the first OC rrence Of Find the first occurre e Of Find the first occurrence Of {char} and move tO {char} and move tO {char} and move t0 {char} and move t0 { 印 la て } and move to it . it . it . it . it . この行には文字 c がいくつもあるので、今度は移動させたいところにスパッと移 動できない。そこまで移動させるには、何度かカーソル移動を繰り返すことになる。 ラッキーなのは、繰り返すときにコマンドをまた入力する必要はない点だ。 Vim は 直前のまな検索を記録しているので、一コマンドを使えば、同じ検索を繰り返せる ( →山 ; ◎ ) 。この例では、カーソルを目的地まで移動させるために一を 3 回押す必 要がある。 ) コマンドとーコマンドはとても強力な組み合わせであり、ほんのわずかの キーストロークでかなりの距離のカーソル移動をカバーできる。ただし、カーソルが 160
TlP33 : カーソル位置にある単語をコマンドプロンプトに挿入く wil 面 enu オプションを有効にすると、候補の一覧をキー操作で選択できるようにな る。品ゝ、 c-n 、 5 gh いで次の候補を表示したり、き醪 Left の候補を表示できるようになる。 T 旧 33 : カーソル位置にある単語をコマンドプロ ンプトに挿入 コマンドラインモードにいても、 Vim は常にカーソルがどこにあるか、どの スプリットウインドウがアクティブかを把握している。アクティブなドキュ メントのカーソル位置にある単語 (word もしくは WORD) をコマンドプロン プトに挿入すると、時間の節約になる。 Vim のコマンドラインでは、を岐というキーマッピングにより、カーソル位 置にある単語がコピーされ、コマンドラインプロンプトに挿入される。これを使うと、 ほんのちょっとだが、タイプ入力の時間の節約になる。 以下の行の tally 変数を counter に変更したいとしよう。 x mode/loop,JS var tally; for (tally=l; tally く = 10 ; tally + + ) { / / dO something with tally tally にカーソルがあれば、一コマンドを使うことで、そこにあるすべての tally を 検索できる ( 第コマンドは / \ くく c ーて > く c ー \ > く CR > というキーをズラズラと入力するのに 等しい。 \ くと \ > という 2 つの要素がパターン中でどのように働くかについては 249 ペー ジの TIP76 を参照のこと ) 。 99
TlP49 : 文字を検索く この例では、 WORD 単位のモーションのほうがよさげだ。でも、常にそうではな い。場合によっては、「 we 」を単語 (word) として扱いたいこともあるだろう。たと えば、「 we 」を「 you 」に変えたいとしよう。だとしたら、以下のようにするだろう。 キーストロークバッフアの内容 {start} gvyou く Esc> e ・ g ・ e're going t00 SIOW e ・ g ・ YO し re going t00 slow あるいは、「 we're 」を単語 (WORD) として扱いたいこともあるかもしれない。た とえば、「 we're 」を「 it's 」に変えたいとしよう。だとしたら、以下のようにするだ ろう。 キーストローク {start} fWit 's く Esc> バッフアの内容 e ・ g ・ ue're going t00 slow e ・ g ・ going t00 SIOW 高速にカーソルを移動したければ、 WORD 単位のモーションを使おう。そして、もっ と細かな単位でカーソルを移動したければ word 単位のモーションを使おう。ちょっ と試してみれば、 word 単位のモーションを使うのはどんなときか、 WORD 単位のモー ションを使うのはどんなときかの感覚がつかめるだろう。実装の詳細を完全には理解 しなくとも、これらのモーションを直感的に使えるようになる。 T 旧 49 : 文字を検索 Vim の文字検索コマンドを使うと、 1 行のなかで素早くカーソルを移動でき る。また、これらのコマンドはオペレータ待機モードでも非常にうまく機能 する。 な ) コマンドは、 Vim でカーソルを移動させる最も高速な方法の 1 つだ。この コマンドは指定された文字を検索する。カーソル位置をスタート地点として、現在行 の末尾方向へ検索を行う。マッチするものがあれば、指定された文字までカーソルが 移動する。マッチしなければ、カーソルはそのままだ ( → : h f ①◎ ) 。 聞いていると複雑そうだが、実際にはこれはとてもシンプルだ。以下の例を見てみ 159
第 13 章検索 ットする 引 P83 : 検索のマッチの末尾にカーソルをオフセ 266 おかしなことになる。なぜかわかるだろうか ? 最後の「 15g 」は実際には「 languages 」 そうでもない ? 同じコマンドシーケンス、言をもう一度叩き込むと、最後の単語が いが、最低限のことはできている。 要な残りが追加される。キーストロークは 3 つ。理想のドットの公式にはなっていな にジャンプして、トで単語の末尾に移動して、一により単語をフルスペルにするのに必 がやってくれるはす。 : と入力すれば、次の「 1 g 」を修正できる。で次のマッチ こうなったら、カーソルを適切な位置に動かしさえすれば、あとはドットコマンド あることであり、もこれが 1 つのコマンドのように指が滑っていくはすだ。 いⅱ age く Esc > と入力して単語の末尾に追加をする。単語の末尾に追加をするのはよく したい文字列を検索すると、カーソルが最初のマッチの先頭に移動する。そこから、 まず、検索オフセットを使わないでこれに挑戦してみる。 / 15g く c として、修正 を使う別の方法があるかを調べてみよう。その過程で何かが学べるかもしれない。 置換コマンドを使って「 :%s/lang/language/g 」とすることだ。でも、ドットの公式 3 つある「 1 g 」をフルスペルに展開するにはどうすればよいだろう。 1 つの方法は Which langs would you like t0 learn? Which lang did you pick up last year? Aim t0 learn a new programming lang each year. search/langs. txt 表記している。 それでは、例を見てみよう。以下の引用では、著者は一貫して「 language 」を省略 よいこともある。検索オフセットを使うことで、これが可能だ ( → :h search-offset フォルトの振る舞いは妥当なものに思えるが、カーソルがマッチの末尾にあったほうが 検索コマンドを実行するたびに、カーソルはマッチの先頭の文字に移動する。このデ で、ドットの公式を使って同じ変更を何度も繰り返すサンプルを紹介しよう。 だけ移動させるのに使える。ここでは、カーソルをマッチの末尾に置くこと 検索オフセットは、カーソルをマッチの先頭もしくは末尾から特定の文字数分
第 1 章Ⅵ m のやり方 . we're waiting for O 、 before the site can go 1ive. . If you are 第 9nt04 with this , let's go ahead with it. . We ' 11 launch as soon as we have the copy ・ . We're waiting for cop before the site can go 1ive. . If you are onten with this, let's go ahead with it . . We ' 11 launch as soon as we have the copy ・ 36 すべてのマッチを置換したければ、何も考えずに矼矼のように、すべての変更が えられる。 チまで移動するので、そこで一を押すと、カーソル位置にある単語が「 copy 」で置き換 これで準備はすべて完了 ! 日キーを押すたびに、カーソルは「 content 」の次のマッ すべてをまとめると き換えられる。 れる。ーコマンドを押すと、現在の単語の末尾までが削除されて、それが「 copy 」で置 してくれるので、 c 。 py く Esc > という一連のキーストロークが一度の変更として扱わ う。そこで、「 copy 」と入力する。 Vim は挿入モードを抜けるまでの入力内容を記憶 カーソル位置からそこにある単語の末尾までを削除して、挿入モードに切り替えを行 の手順が含まれている。「 content 」の削除と、その置換内容の入力だ。コマンドは 「 content 」の先頭にカーソルを移動したら、変更の準備は完了。この変更には 2 つ 変更を繰り返し可能に てくる。 この場合、をと押すと、すべてのマッチが循環して、スタート位置にカーソルが戻っ 「 content 」の検索を実行したあとは、キーを押すだけで、次のマッチに移動できる。 照してほしい。 されなければ「 :set hls 」を実行する。この詳細については TIP80 ( 262 ページ ) を参 が次のマッチに移動する。それから、マッチしたすべてが強調表示される。強調表示 語を検索する。自分でも試してみよう。 2 つのことが起こるはすだ。まず、カーソル 最初、カーソルは「 content 」の上に置いておき、 こで一コマンドを使ってこの単