ホーム > タグ > lv1

lv1

Hack #129: 複数のファイルから検索する

時折、大量にあるテキストファイルから特定のテキストを検索したい場合があります。grep などのプログラムが有名ですが、やはり検索結果から直接該当のファイルにジャンプできると便利です。

:grep コマンド

:grep コマンドは、'grepprg' オプションで指定された外部プログラムを実行してテキストの検索を行い、結果を 'errorformat' オプションに従って解釈したあと、quickfix ウィンドウへ出力します。quickfix 上で結果を選択して <Enter> を押すことで目的のファイルの目的の行にジャンプすることができます。 各オプションにはデフォルトで適切な値が設定されており、通常はいじる必要はありません。

:grepadd と言うコマンドもあり、これは quickfix ウィンドウの中身を置き代えずに追記します。複数の grep の結果を見るのに便利です。

:vimgrep コマンド

:grep コマンドは外部のプログラムに依存するため、その実装によって挙動が異なることがあります。例えば、Windows では標準では findstr が使用されます。これは grep とはまったく異なるものなので、指定する引数も使える正規表現も違います。

そういう経緯もあってかどうかは知りませんが、Vim には :vimgrep と言う自力で grep を行う組み込みコマンドがあります。基本的な使い方は :grep と同じです。

:vimgrep /pattern/ {file}...
:vimgrepadd /pattern/ {file}...

pattern には Vim の正規表現が使えます。単純な単語の場合、前後の / は省略可能です。

{file} の部分に検索対象のファイルを指定します。指定にはワイルドカードが使えます(:help wildcard)。これは ** による再帰的な探索に対応しています。

:vimgrep /\<variable\>/ **/*.c

パターンの後ろにフラグを付けることで挙動を変更できます。

フラグ意味
g1 つの行に複数のマッチが見つかった場合、同じ行を複数回列挙します。
j通常、検索対象が見つかった場合は最初の候補にジャンプしますが、このジャンプを抑制します。
:vimgrep /\<variable\>/j **/*.c

コマンドの前に数字を置くことで、検索件数の上限を指定できます。これにより検索時間を短縮できます。例えば、最初に見つかった 1 件だけを表示するには以下のようにします。

:1vimgrep /\<variable\>/ **/*.c

'grepprg' に "internal" と設定すると、:grep で :vimgrep が使われるようになります。

set grepprg=internal

:vimgrep は挙動が統一されているので、様々な環境で同じように grep を行いたい場合に非常に便利です。

thinca

Hack #126: クリップボードを利用する

問題1

ふつうのテキストエディタであれば クリップボードにあるテキストがペーストされ、 コピーしたテキストはクリップボードに保存されます。

しかしVimではコピー/ペーストされるテキストは レジスタと呼ばれるVim内部の領域から読み書きされるため、 そのようにはなっていません。

クリップボードに対してコピー/ペーストを行なうにはどうすればよいのでしょうか。

解決方法1

Vimには クリップボードを表す仮想的なレジスタ"*があるため、 コピー/ペーストする際にそのレジスタを使用するよう指定します。 例えばクリップボードへ1行分のテキストをコピーする場合は 以下のコマンドを入力します:

"*Y

クリップボードからテキストをペーストする場合は 以下のコマンドを入力します:

"*p

問題2

Vimからクリップボードにアクセスする方法は分かりました。 しかし毎回"*を指定しなければならず、入力が面倒です。 Vim内でテキストのコピー/ペーストを行なう場合に、 何も指定しなくても自動的にクリップボードを利用するようにできないでしょうか。

解決方法2

以下のコマンドを実行します:

:set clipboard=unnamed

この設定を行なうと、 特にレジスタを指定せずにコピー/ペーストを行なった場合は クリップボードを利用するようになります。

また、xtermなどのX Window System下のアプリケーションでは 選択されたテキストが自動的にクリップボードへコピーされます。 VimのVisual modeでも同様の挙動にしたい場合は以下のコマンドを実行します。

:set clipboard=autoselect

もし両方の挙動が必要な場合は以下のように値をコンマ(,)区切りで指定します:

:set clipboard=unnamed,autoselect

問題3

基本的にGUI版のVimでしかクリップボードに関する機能は利用できません。 つまり、諸事情で端末エミュレータ内でVimを利用している場合は クリップボード関連の機能は使えません。

幸いなことに、 一部の環境ではクリップボードにアクセスするためのコマンドがあります。 例えばMac OS Xの場合はpbcopy/pbpasteでクリップボードの読み書きができるため、 :read !pbpasteなどとすればクリップボードの内容を取り込むことが できます。

しかしこのようなコマンドは入力が煩雑ですし、 何よりd/p/yのような Vim本来の操作と比べると不便です。 どうにかして"*と同様の操作性を実現できないでしょうか。

解決方法3

fakeclipを使います。 このプラグインをインストールすると Cygwin、Mac OS X、X Window Systemの非GUI版Vimでも "*Y"*pなどの操作ができるようになります (バージョン0.2.6現在)。

解説

Q. なぜ"*Yのようなまどろっこしい操作になっているのですか?

A. 祖先のviが生まれた頃にクリップボードなんてものはなかったからです。

Q. なぜ:set clipboard=unnamedがデフォルトでないのですか?

A. Vimのデフォルト設定は可能な限りviライクだからです。 そして祖先のviが生まれた頃にクリップボードなんてものはなかったからです。

参考資料

kana

Hack #125: 矩形選択で自由に移動する

Vim は <C-v> で矩形選択を行うことができます。非常に便利な機能ですが、矩形の端の行の行末にテキストがない場合、選択が困難、もしくは不可能になってしまう場合があります。これは設定で回避できます。

設定

以下の設定を行います。

set virtualedit+=block

この設定を行うことで、矩形選択中は行末にテキストがなくてもカーソルを行末以降に移動させることができるようになります。

解説

'virtualedit' オプションは、仮想編集を有効にするモードを設定するオプションです。仮想編集中は実際に文字がないところへカーソルを移動させることができます。つまり、タブ文字の内部や行末より後ろへカーソルを移動させることができるようになります。ただしファイルの末尾以降の行へは移動できません。

また、'virtualedit' オプションはカンマ区切りの値を指定するオプションで、+= を使っていたのはそのためです。他にも insert(Insert mode で仮想編集を有効にする) や all(全てのモードで仮想編集を有効にする) が指定でき、他にはちょっと変わった値として onemore(行末の1文字先までカーソルを移動できるようにする) が指定できます。

thinca

Hack #122: 行末までヤンクする

問題

カーソル位置から行末まで削除するにはDします。 カーソル位置から行末まで編集する(削除して挿入モードに入る)にはCします。

さて、カーソル位置から行末までヤンクするにはどうすればいいでしょうか。 答えはYではなく、y$です。

VimのYの挙動は、「カーソル行をヤンク」です。カーソル位置より左もまとめてヤンクされてしまいます。 オリジナルのviとの互換性のためか、このような仕様になっているみたいです。 オリジナルのviがなぜこのような仕様になっているかは不明です。

解決

~/.vimrcに以下を記述します。

nnoremap Y y$

これで、Yの挙動がDCと同様に、「カーソル位置から行末までヤンクする」になります。 一貫性がとれる上に、$というとても人間には入力不可能な記号の入力を省略することができ、開発効率の大幅な向上が期待されます。

解説

なお、ヘルプ :h Y を引くと以下のように説明されています。

["x]Y yank [count] lines [into register x] (synonym for yy, |linewise|). If you like "Y" to work from the cursor to the end of line (which is more logical, but not Vi-compatible) use ":map Y y$".

しかし、このやりかたは2点留意事項があります。

  • ヘルプに書いている方法ですと、y$の挙動が上書きされているときに、上書きされた側の挙動で今回定義したYが実行されます。多くの場合それは意図した挙動ではないため、本Hackではmapではなくnoremapとしました
  • ビジュアルモードなどでは今回のYは関係ないため、mapではなくnmapがより好ましいです

組み合わせて、本Hackではnnoremapとしました。

ujihisa

Hack #121: バッファ名をペーストする

問題

ときおりバッファ名をペーストしたいことがあります。 短い名前なら手動で入力しても構いませんし、 ファイルに対応するバッファならばファイル名補完で多少の手間を省けますが、 面倒臭いことには変わりありません。 直接バッファ名をペーストできないでしょうか。

解決方法

Normal modeの場合は以下のコマンドを実行します:

"%p

Insert modeやCommand-line modeの場合は以下のコマンドを入力します:

<C-r>%

上記のコマンドはカレントバッファ名をペーストします。 %の代わりに#を用いると 代替バッファ の名前をペーストします。

解説

上記のコマンドは実際には指定されたレジスタの内容をペーストするコマンドです。 Vimには特殊なレジスタとしてカレントバッファ名や代替バッファ名を表すものがあり、 この二つを組み合わせることで上記のようにバッファ名のペーストができます。

Vimには他にも様々な 特殊レジスタ があるので、一度確認しておくとより便利に使うことができるでしょう。

参考資料

kana

Hack #117: 置換行為を繰り返す

問題

:substitute (:s)による置換処理は頻繁に使います。 バッファ全体を対象にする場合は:%s/foo/bar/gなどでできますし、 特定範囲のみを対象にする場合はVisual modeで選択しておいて :s/foo/bar/gでできます。

では飛び飛びの場所で置換を行なう場合はどうでしょうか。 例えばソースコード中の特定の関数3つに対して置換を行なうとしましょう。 この場合は3箇所それぞれを対象として置換を実行することになりますが、 毎回 :s/foo/bar/g のような長ったらしいコマンドを入力したくはありません。 <Up>/<Down> でコマンドの入力履歴を辿って実行してもいいのですが、 これらのキーは概して遠い位置にあるため押下が面倒ですし、 押し易いキーバインドを設定することも面倒です。 どうにかして最小の手数で置換行為を繰り返せないでしょうか。

解決方法

以下のコマンドを実行します:

:s

通常、:sには検索パターンと置換文字列を指定しますが、 それらを省略した場合は最後に実行された :sと同じ検索パターンと置換文字列で置換が行なわれます。

なお:sでは :s/foo/bar/gc などのフラグは無視されます。 フラグまで同一にする場合は:sの代わりに

:&&

を使います。

また1行だけ繰り返す場合には:sの代わりに

&

を使うこともできます。

参考資料

kana

Hack #102: 長いソースコードをざっと眺める

問題

1000行を超える長いファイルをざっと通して見るとき、あなたはどのようにページ送りしていますか?

  • jを押しっぱなしにしてスクロール
  • <C-f>で1画面ずつページ送り

行数が少ないときは前者で十分ですが、ある程度以上の行数になるとスクロール酔いすることが知られています。 またターミナル上のVimで縦分割を行なっているときや、MacBook Airが熱暴走しているときには、jを押したままのスクロールは大変高負荷な処理なわけですので、画面がチラついてあなたの体力を一気に消耗させてしまいます。

このような場合には<C-f>で一気にページ送りすることが妥当と考えられますが、<C-f>というキーマッピングの入力はとてつもなく困難で、入力できる人はごくわずかでしょう。

解決

以下を~/.vimrcに記述します。

noremap <Space>j <C-f>
noremap <Space>k <C-b>

以後、ノーマルモードやビジュアルモードで、<Space>jでページ送りができます。上方向には<Space>kで移動することになります。 j, kと直接対応するため非常に直感的です。

Vimでは一般に<C-f>などの入力が困難なキーは再割り当てを行なうことを前提としていると考えることができます。 このような例は他にも%^などにみることができます。

ujihisa

Hack #100: vimrcにパスワード等を記述しなくてもよくする

問題

blogger.vim などの Plugin を利用する場合、 .vimrc にパスワード等の設定を記述する必要があります。 GitHubVimrcbox に .vimrc を公開している場合、そのままでは利用することができません。

解決

pitconfig.vim もしくは rbpit.vim を利用することで .vimrc に直接記述することなくパスワード等を設定することが可能です。

準備

pitconfig.vim を利用する場合は Perl インターフェイス付きの、 rbpit.vim を利用する場合は Ruby インターフェイス付きの Vim を準備してください。手元の Vim がこれらのインターフェイス付きでない場合は、ソースからコンパイルする必要があります。コンパイル方法については本 Hack の範囲を超えるので省略します。

また pitconfig.vim なら Config::Pit を CPAN から、 rbpit.vim なら pit を Rubygems からインストールします。

Plugin のインストール

pitconfig.vim または rbpit.vim を Plugin Directory へコピーしてください。 Plugin Directory については :h add-global-plugin を参照してください。

pitconfig.vim と rbpit.vim の違いは Perl インターフェイスを利用するか Ruby インターフェイスを利用するかの違いのみで、動作は同一です。1

設定

設定は Config::Pit の ppit コマンドや pit の pit コマンドから設定することが可能です。デフォルトのプロファイル名は vimrc ですが、変更することも可能です。

 pit set vimrc 

設定はYAMLとして記述します。例として blogger.vim の設定方法を記述します。

---
blogger_blogid = 7772225564702673313
blogger_email = blogger.vim@gmail.com
blogger_pass = bloggervimvim

また、 Vim の Command Mode から以下の要領で設定を行うこともできます。例として blogger.vim の設定方法を記述します。

:let g:blogger_blogid = 7772225564702673313
:let g:blogger_email = "blogger.vim@gmail.com"
:let g:blogger_pass = "bloggervimvim"
:PitAdd g:blogger_blogid g:blogger_email g:blogger_pass
:PitSave

デフォルトプロファイル名の設定

デフォルトでのプロファイル名は vimrc になっていますが、 g:pitconfig_default でデフォルトのプロファイル名を変更することが可能です。

コマンド

:PitLoad (プロファイル名)

プロファイル名に保存された設定をロードします。

:PitReload

デフォルトプロファイルをリロードします。

:PitAdd (変数名)

引数で指定した変数を :PitSave で保存する対象に設定します。変数名は複数指定可能です。

:PitDel (変数名)

引数で指定した変数を :PitSave で保存する対象から外します。変数名は複数指定可能です。

:PitSave (プロファイル名)

引数で指定したプロファイル名を使用して設定を保存します。引数なしで実行した場合はデフォルトプロファイルに保存します。

注意

MacVimを利用している場合、 pit は Mac OSX 標準の Rubygems (/usr/bin/gem) を利用してインストールする必要があります。 MacPorts を利用して ruby 及び rb-rubygems をインストールしていたとしても、使われるのは Mac OSX 標準の Rubygems になります。

from_kyushu

Hack #95: .vimrc / .gvimrc を共有したり、他人の.vimrc / .gvimrcを参考にする

Vimを使っている人の大半は.vimrcを編集して自分好みにカスタマイズしていることかと思われます。

Vimを使い始めた人や、Vimを使いこなしている人たちにもレビューしてもらったりできる用に.vimrcを共有してみてはいかがでしょうか。

問題

.vimrcを共有する際に、

  • .vimrcを共有する固定的な場所がないこと
  • .vimrcをアップデートするための作業が必要なこと

こういう問題があります。

解決

これを解決するために.vimrcboxというサービスを作成しました。

Vimrcboxは.vimrcや.gvimrcを共有するためのサービスです。

vimrcbox.vimというpluginを用いて、簡単にvimrcboxにアップロードすることができます。

vimrcbox.vim をインストールします。

また、curlが必要です。必要に応じてインストールを行ってください。

その後 :RcbVimrc や :RcbGVimrc でアップロードできます。

この時訪ねられるパスワードの認証は簡易的な物なので、普段使うパスワードとは別にしておくといいと思います。

また、アップロードの際訪ねられるユーザー名とパスワードは、 g:vimrcbox_user や g:vimrcbox_pass を.vimrcに設定して省略することも可能ですが、 セキュリティ上の問題もあるため別ファイルに書き込み.vimrcからsourceで読み込むとよいと思います。

投稿した.vimrcは、

http://soralabo.net/s/vrcb/s/ユーザー名

から閲覧できます。削除メニューなどもそこから可能です。

.gvimrcは

http://soralabo.net/s/vrcb/sg/ユーザー名

から閲覧できます。

自動でアップロードする

.vimrcに以下を記述します。

augroup VimRcBox
    autocmd!
    autocmd BufWritePost $MYVIMRC RcbVimrc
    autocmd BufWritePost $MYGVIMRC RcbGVimrc
augroup END

これで自動アップデートできます。

既知の問題

  • 行番号がズレている
  • レビューのための機能がない

こちらの機能や問題は近日中に修正します。

参考

Sora Harakami

Hack #94: 開くファイル、保存するファイルのエンコーディングを指定する

日本語には様々なエンコーディング方式があるので、扱う際には気を付ける必要があります。Vim が +multi_byte 機能付きでコンパイルされていれば、これらを正しく扱うことができます。

エンコーディングを指定してファイルを開き直す

開いたファイルが文字化けしていて、かつ正しいエンコーディングがわかっている場合は次のようにすることでエンコーディングを指定してファイルを開き直すことができます。

:edit ++enc={encoding-name}

{encoding-name} にはエンコーディング名が入ります。日本語だと、"utf-8" "cp932"(≒Shift_JIS) "euc-jp" "iso-2022-jp" などがあります。

編集しているファイルのエンコーディングを設定する

現在編集しているファイル(バッファ)のエンコーディングは 'fileencoding' オプションで決まります。ファイルを保存する際にこのエンコーディングに変換して保存されます。つまり、この値を変更すれば保存するファイルのエンコーディングを変更できます。

:setlocal fileencoding={encoding-name}

{encoding-name} は ++enc= に設定するのと同じものです。 :setlocal を使っているのに注意してください。:set を使うと新しく作成するファイルのデフォルトエンコーディングも変わってしまいます。詳しくは Hack #15: ローカルオプション を参照してください。

thinca

Home > Tags > lv1

Search
Feeds
Links
  • 公式
  • 勉強会
  • 情報
  • コミュニティ
  • プラグイン
  • vimrc
  • Meta
    Etc
    Creative Commons License
    This blog is licensed under a Creative Commons License.

    Return to page top