( 1 # ( 2 %a " a . txt ” "b . txt" TlP36 : バッファリストを使ってオープン中のファイルを管理するく 行 1 ) 行 1 ) % 記号は、ウインドウに現在表示されているバッフアがどれかを示している。一方、 # 記号は代替ファイルを示している。トを押すだけで、現在編集中のファイルと代 替ファイルとを簡単に切り替えられる。一度押せば a. txt に切り替わり、もう一度押 せば再び b. txt に切り替わるというわけだ。 バッファリストを使う バッファリスト間を移動するには 4 つのコマンドが使える。 :bprev/:bnext コマン ドはバッファリストを 1 つずつ前後に移動し、 :bfirst/:blast コマンドはリストの 先頭 / 末尾に一気に移動する。指が届きやすいキーのどれかにこれらをマッピングす るというのはなかなかよいアイデアだ。この下の「 Vim のリストをサクサク移動する ためのキーマッピング」にはお勧めのマッピングを掲載している。 : ls が表示するバッファリストの先頭には数字がある。これは、バッフアの作成時 に自動的に各バッフアに割り当てられた番号だ。「 :buffer N 」コマンドでこの番号 を指定して、対応するバッフアに直接移動することも可能だ ( → :h : b ◎① ) 。もっ と直接的に「 :buffer {bufname} 」としてもよい。 {bufname} には、ただ 1 つのバッ フアを特定するような文字列をファイルバスから指定する。指定した文字列が、バッ ファリストに含まれる複数の要素にマッチする場合、タブ補完を使って ( 97 ページの TIP32 を参照 ) 、候補のなかから選択できる。 : bufdo コマンドを使うと、 : ls で一覧されるすべてのバッフアに対して Ex コマン ドを実行できる ( → : h : bufdo ◎◎ ) 。実際のところ、筆者的には、これらのコマン ドではなく : argd 。を使うほうがもっと実践的だと思う。これについては TIP37 ( 117 ページ ) で紹介しよう。 115
第 6 章 複数ファイルの管理 Vim では一度に複数のファイルを扱える。バッファリストを使うと、編集セッショ ン時にオープンしてきたファイル群を管理可能だ。次の TIP36 では、このリストの使 い方と、ファイルとバッフアの違いについて説明する。 引数リストは、バッファリストと対になる非常に便利なツールだ。 TIP37 ( 117 ペー ジ ) では、 : args コマンドを使って、バッファリストに含まれるファイルをコレクショ ンにグループ化する方法を見てみよう。 : argd 。コマンドを使うと、リストの要素間を 移動したり、 1 つ 1 つのファイルに対して Ex コマンドを実行したりできる。 Vim では、ワークスペースを分割ウインドウに分けられる。 TIP39 ( 124 ページ ) で はその方法を取り上げる。その後、 TIP40 ( 128 ページ ) では、タブっきのインターフェ イスを使って、分割ウインドウをコレクションとして整理整頓する方法を説明しよう。 T 旧 36 : バッファリストを使ってオープン中のフ ファイルとバッフアの違いを理解する だファイルをバッファリストを使って管理する。 複数のファイルを 1 つの編集セッションで読み込める。 Vim では、読み込ん ァイルを管理する 113 れをバッフアと呼ぶ。 そうじゃなくて、ファイルのインメモリ表現を編集しているのだ。 Vim の用語ではこ を編集しているかのようによくいうけれども、実際にやっているのはそうじゃない。 変更を保存できる。自分たちの仕事の仕方について話をするときには、あるファイル 他のテキストエデイタと同じく、 Vim では複数のファイルを読み込んで、編集して、
第 7 章ファイルのオープンとディスクへの保存 T 旧 44 : 存在していないディレクトリにファイルを保存 ラッキーなことに、 Vim では存在していないディレクトリをバスに含んでい るバッフアでも編集が可能だ。 Vim が文句をつけてくるのは、そのバッファ をファイルに書き込もうとしたときだけだ。ここでは、このときに、どうす ればよいかを説明しよう。 既存のファイルをオープンするのに最もよく使われるコマンドは「 : edit {f ile} 」 だ。ただし、既存のファイルに対応していないファイルバスを指定すると、 Vim は空 のバッフアを新規に作成する。三を押すと、バッフアには rnew file 」 ( 新ファイ ル ) というラベルがつけられているのがわかる ( 起ミコマンドは現在のファイルの 名前と状態をエコーするコマンドだ→ : h ct て 1 ー G ①① ) 。 : write コマンドを実行する と、 Vim は、バッファ作成時に指定されたファイルバスを使って、そのバッフアの内 容を新しいファイルに保存しようとする。 「 :edit {file} 」を実行して、存在しないディレクトリを含むファイルバスを指定す ("madeup/dir/doesnotexit ・ yet" E212 : 書込み用にファイルを開けません ) "madeup/dir/doesnotexist. yet" E212 : Can't open file for writing :write : edit madeup/dir/doesnotexist. yet ると、ちょっとやっかいなことになる。 ← → 144 クトリに対して相対的にファイルをオープン」を参照してほしい。 文字列の説明については、 135 ページの「アクテイプなファイルを格納しているディレ ー p フラグは mkdir に中間にあるディレクトリも作成するための指示だ。 % : h という ー + :write → :!mkdir -p %:h きだけだ。この状況は、外部プログラムの mkdir を呼び出すことで解消できる。 ている。 Vim がエラーを発生させるのは、ディスクにバッフアを書き込もうとすると は新規に作成するが、今度のラベルは「 new DIRECTORY 」 ( 新規ディレクトリ ) となっ この場合、 madeup/dir ディレクトリが存在していない。 Vim はとりあえすバッファ
TlP38 : 隠しファイルの管理く T 旧 38 : 隠しファイルの管理 バッフアの内容が変更されたら、変更を保存しないまま間違ってエデイタを終 了することがないように、 Vim はこれを特別扱いするようになる。バッファ を隠しバッフアとする方法、隠しバッフアを Vim の終了時に取り扱う方法を ここでは見てみよう。 シェルから以下のコマンドを実行して Vim を起動しよう * 2 。 cd code/files $ ls b . txt ← a . txt vim * . txt 2 files to edit a. txt を変更してみる。といっても、を押して、バッフアの末尾に空行を追加す こで保存をせずに、バッファリストを確認してみる * 3 。 るだけだ。 → : ls 1 %a + " a. txt " "b . txt" 2 ( 1 %a + "a . txt" "b . txt" line 1 line 0 1 0 行行 ' は、これが変更されたことを示す + 記号がつけられている。 a. txt のノヾッフアに でファイルを保存してみると、バッフアの内容がディスクに書き込まれ、 + 記号が表 こではまだ保存をしないで、次のバッフアに移動してみよ 示されなくなる。でも、 * 4 : bnext E37 : No write since last change (add ! to override) ( E37 : 最後の変更が保存されていません ( ! を追加で変更を破棄 ) ) Vim はエラーメッセージを表示して、現在のバッフアには保存されていない変更が 含まれていることを教えてくれる。カッコ内のアドバイスに従って、ビックリマーク をつけてみよう。 * 2. 訳注 : ls コマンドはもっと多くのファイル / ディレクトリを出力するかもしれません。 * 3. 表示される行番号は例とは異なるかもしれません。 * 4. 訳注 : 工ラーにならないときには「 :set nohiddenJ を実行してみてくたさい ( 後述 ) 。 121
TlP37 : 引数リストを使ってバッフアをコレクションにまとめるく るのに十分な理由がない限りは、わざわざそんなことはしないだろう。そういうわけ で、 : ls コマンドの表示には、編集中にオープンしたすべてのファイルが表示される ようになっている。 Vim に組み込まれている、バッファリスト管理用のコマンドは柔軟性に欠けている。 仕事の進め方に合うようにバッフアを並べ替えたいという場合、バッファリストを整 理しようとするのは間違っている。そうではなく、分割ウインドウ、タブページ、引 数リストを使って、ワークスペースを分けていくほうがよい。次に、このやり方をい くつか見ていこつ。 引 P37 : 引数リストを使ってバッフアをコレクシ ョンにまとめる 引数リストは管理も簡単で、これを使うと、ファイルをコレクションにして、 ファイル間を簡単に移動できるようになる。 :argdo コマンドを使えば、引数 リスト中の各要素に Ex コマンドも実行できる。 まずは Vim でファイルをいくつかオープンしよう。 $ cd code/files/letters $ vim * . txt 5 files to edit TIP36 ( 113 ページ ) では、 : ls コマンドでバッフアのリストが表示されるという話 をした。 こでは、引数リストを試してみよう。 - 、 : args ← [a. txt] b . txt c . txt . d. txt e . txt 引数リストは vim コマンドの起動時に引数として渡されたファイルのリストを表す。 上の例では、 *. txt という引数を 1 つ渡しただけだが、シェルが * ワイルドカードを展 開して、 5 つのファイルがマッチした。これが引数リストに現れている。ロは引数リ ストのなかで現在アクテイプなものを示している。 : ls コマンドが返すリストと比べて、 : args コマンドを実行したときの出力はそのま まという感じだ。引数リストが vi の機能だったこと、そして、バッファリストは Vim で導入された拡張機能であることを知れば、これは別に驚くようなことではない。し 117
第 6 章複数ファイルの管理 : bnext ! :ls 1 #h + " a . txt " 2 %a "b . txt" ( 1 #h + 'ta . txt" ( 2 %a "b . txt" ピックリマークをつけると、 Vim は強制的にバッフアを切り替える。現在のバッ フアに保存されていない変更が含まれていてもだ。ここで : ls コマンドを実行すると、 b. txt にアクティブであることを意味する a がつく。一方、 a. txt には隠しバッフアで あることを示す h がつけられる。 Vim 終了時の隠しバッフアの取り扱い 隠しバッフアがあっても、いつもどおりに作業を行える。別のバッフアをオープン して、その内容を変更し、それを保存できる。このときに隠しバッフアに関連したこ とは何も行われない。つまり、編集セッションを終了しようとするまでは。編集セッ ションを終了しようとすると、バッフアの 1 つに保存されていない変更があると Vim が教えてくれる。 → : quit E37 : No write since last change (add ! to override) E162 : No write since last change fo て buffer "a. txt" ( E37 : 最後の変更が保存されていません ( ! を追加で変更を破棄 ) ) ( E162 : バッファ "a. txt" の変更は保存されていません ) Vim は変更された最初の隠しバッフアを現在のウインドウに読み込んでくれるので、 こでこれをどうするかの判断を行える。変更を保存したければ、 : write を実行し てバッフアをファイルに保存できる。変更を捨てたければ、 : edit ! を実行できる。 れはファイルをディスクから読み込み直して、バッフアの内容を上書きするコマンド だ。バッフアの内容とディスク上のファイルの内容が同じになったところで、もう一 度 : quit コマンドを実行しよう。 変更された隠しバッフアが複数あるときには、 : quit コマンドを入力するたびに、未 保存の次のバッフアがアクテイプになる。ここでも : write か : edit ! で変更を保存す るか捨てるかする。変更された隠しバッフアのすべてでこの判断が終わるまでは、 れがずっと繰り返される。ウインドウと変更された隠しバッフアがなくなると、 : q で line 1 line 1 1 宀イ上 122
第 6 章複数ファイルの管理 ファイルはディスクに保存されるもので、バッフアはメモリ上に存在するものだ。 Vim でファイルを開くと、その内容がバッフアに読み込まれる。バッフアの名前はファ イル名と同じだ。最初は、バッフアの内容はファイルの内容と同じだが、バッフアに 対して変更を行っていくことで、両者の内容は異なるものになっていく。変更を保存 しておこうと思ったところで、バッフアの内容をファイルへと書き出すことができる。 Vim のコマンドの大半はバッフアを操作するが、ファイルを操作するものもいくつか ある。たとえば、 :write 、 :update 、 :saveas コマンドがそうた バッファリスト Vim では、複数のバッフアを同時に扱える。シェルから以下のコマンドを実行して、 ファイルをいくつかオープンしてみよう。 $ cd code/files $ vim * . txt 2 files to edit *. txt というワイルドカードがカレントディレクトリにある 2 つのファイル、 a. txt と b. txt にマッチしているとする。このコマンドは、 Vim にこれらのファイルをオー プンするように伝える。 Vim の起動時には、ウインドウが 1 つ開き、そこには 2 つの ファイルのうち最初のものが表示される。もう 1 つのファイルは表示はされないもの の、バックグラウンドのバッフアには読み込まれている。これは以下のコマンドを実 行すればわかるとおりだ。 :ls 1 %a 2 ( 1 %a ー a. txt " "b . txt" " a. txt " t'b . txt" 行 1 ) 行 0 ) line 1 line 0 : ls は、メモリに読み込まれている全バッフアを一覧表示するコマンドだ ( → :h :ls ①◎ ) 。リスト中の次のバッフアに切り替えるには : b Ⅱ ext コマンドを実行すればよい。 : bnext → : ls 2 %a 114 ー a. txt " "b . txt" line 1 line 1
引 PI 1 3 : キー バッファリスト ワードの定義元を把握するく 自動補完用の単語リストを作成するための最もシンプルな機構とは、現在のバッファ だけに含まれている単語を使うことだ。現在のファイルのキーワード補完はまさに れを行うものであり、 c ー x > く c ー n> で起動される ( → :h compl-current ①◎ ) 。これ は、汎用のキーワード補完ではあまりに多くの候補が生成されてしまう場合や、現在 のバッフアのどこかに必要な単語が含まれていることがわかっている場合に、特に便 利に使える。 ただし、現在のバッフアの単語数が少ないと、現在のバッフアによるキーワード補 完で提供されるものも少なくなってしまう。単語リストに含まれる単語数を増やすに は、 Vim がバッファリストの各要素のキーワードをソースとするようにすればよい。 これらは、以下のコマンドで確認できる。 → : ls ! 汎用のキーワードは、このリストの各ファイルの内容から作成され、現在の Vim セッションでオープンされた全ファイルを反映したものとなっている。以下で見るよ うに、自動補完用の単語リストにその内容を抜き出すためには、そのファイルをオー プンする必要すらない。 インクルードされるファイル 大半のプログラミング言語には、外部のファイルやライプラリからコードをロード する方法が用意されている。 C では、これは #include ディレクテイプで行える。 方、 Python では import を、 Ruby では require を使用する。他のライプラリからコー ドをインクルードしているファイルを利用するときには、単語リストの作成時にそ れらの参照されているファイルの内容を Vim が読み込めると便利だろう。そして、 第きのコマンドでキーワード補完を起動したときには、まさにこれが行われるの だ ( → :h compl-keyword ◎◎ ) 。 Vim は C でファイルをインクルードする方法は知っているが、「 include 」設定を変更す ることで、他の言語の対応するディレクテイプに従うように指示できる ( → :h 'include' ⑩⑩ ) 。これは通常、ファイルタイププラグインで処理される。そして、うれしいこ 359
第 11 章マクロ 0 コマンドを使ってカーソル行の上に空行を作成して、新しくテキストを挿入する。 そして、カーソルを次の行に進めて、起コマンドでファイル末尾までの各行のインデ ントを 1 レベル深くする。最後に、 0 コマンドでファイル末尾にジャンプしたら、その 下にコマンドで空行を作成して、 end キーワードをそこに記述する。 自分のエデイタでこれを試しているのなら、 : w を実行して、変更をファイルに保存 したくなってもがまんすること。その理由はすぐに説明する。 マクロを並列に実行する : a て gd 。コマンドを使うと、引数リストに含まれるバッファ 1 つにつき Ex コマンドを 一度実行できる ( → :h :argdoOO)0 ただし、 こでいますぐ「 : argdo normal @a」 を実行しようとすると、副作用が発生するだろう。 これについて考えてみよう。「 : argdo normal 」により、いま記録したばかりの マクロが引数リストに含まれるすべてのバッフアで実行される。これには、引数リス トの先頭のバッフア、すなわち、マクロの記録時にすでに変更をしているバッフアも 含まれる。このため、最初のバッフアはモジュールに 2 回含められることになる。 これを避けるには、 : edit ! を実行して、引数リストの先頭のバッフアで行われた変 更をすべてなかったことにする ( → :h :edit! ◎◎ ) 。 → :edit! すでに変更をファイルに書き込んだあとなら、 : edit ! を実行してもだめだ。その場 合は、ファイルをオープンしたときの状態になるまで冒コマンドを何回か実行すれば では、引数リストのすべてのバッフアで、このマクロを実行してみよう。 よい。 228 をしてくれる。このマクロを直列に実行する方法を見てみよう。 このテクニックは設定にちょっと手間がかかるが、コマンドー発でたくさんのこと → : argd0 normal @a
第 6 章複数ファイルの管理 「 hidden 」設定を有効にすると ( → :h 'hidden' ①◎ ) 、 :next 、 :bnext 、 :cnext など のコマンドを最後のビックリマークなしで実行できるようになる。アクテイプなバッ フアが変更されている場合、そこから別のバッフアに移動しようとすると、 Vim は自 動的にこれを隠しバッフアにしてくれる。「 hidden 」設定により、 :argdo と :bufdo を 使って、コマンドー発でバッフアのコレクションに変更を加えられるようになる。 :argdo { cmd } の実行後には、引数リストの各要素に対して行われた変更を保存する のが普通だ。 :first を実行してから : w Ⅱを実行すると、 1 つずっ保存できる。この方 法なら、各ファイルを確認できる。すべてが思ったとおりになっていると自信満々な らば、「 :argdo write 」 ( か : wall ) を実行してすべてのバッフアを保存するってのも ありだ。 T 旧 39 : ワークスペースを分割ウインドウにする Vim では、ワークスペースを分割ウインドウにすることで、複数のバッファ を同時に表示できる。 Vim の用語では、ウインドウとはバッフアに対するビューポートのことだ ( → : h window ◎◎ ) 。ウインドウを複数開くと、そこに同じバッフアを表示したり、それぞれのウィ ンドウに別々のバッフアを読み込んだりできる。 Vim のウインドウ管理システムは柔 軟にできていて、自分の仕事のやり方に合わせてワークスペースを作り上げられるよ うになっている。 分割ウインドウの作成 Vim の起動時には、ウインドウは 1 つだけだ。このウインドウは 59 : 当誉コマンドで 水平方向に分割、つまり、同じ高さのウインドウを 2 つ作成できる。三ョコマンド を使えば、垂直方向に分割、つまり、同じ幅のウインドウを 2 つ作成できる。これら のコマンドを好きなだけ繰り返せる。これにより、ワークスペースはセル分割と似た 感じに何度も何度も分割されていく。 どんな感じになるかを以下の図に示そう。それぞれグレーになっている矩形がアク テイプなウインドウとなっている。 124