前の記事がやたらポエミーになってしまったので、もうちょっと実際的なとこでVim使う上での注意点とか、今後覚えておきたいこと書いときます。
正規表現を使いこなす
そもそも正規表現がきちんと修められていないので、これまで検索と置換はあまり使ってこなかった。が、これ使えないとVimの魅力半減だと思うので、ちゃんと使いこなせるようになるのが目標。
正規表現と一言に言っても言語やツールによって書き方が違う場合があって、Vimについても一部の正規表現用の特殊文字を使うとき、エスケープが必要なことがある。これについてはvery magicというオプションを使うとエスケープせずに済むらしい。vimrcに書いたりできないのがちょっと煩わしいが、エスケープ必要な特殊文字を逐一覚えて1個1個処理していくよりは良い。
せっかく正規表現を使うならvimgrepもマスターしておこうと思う。というかカレントバッファだけを編集するんじゃなくて、ファイルを扱うツールとしてVimを使いたい。今使っているのはNERDTreeぐらいなものである。
vimgrepは名前通り:vimgrepで打ちたくなるが、:vim {pattern} {files}の書式で使える。{files}にはフォルダパスやワイルドカードの他、標準出力も渡せるらしく、例えばgit ls-filesでGitにインデックスされているファイルだけを対象にしたりできるらしい。よくコード中に「TODO」とコメントしていく場面があるみたいだが、IDEではなくVimでも一斉検索して処理したりできるってことか。なるほど。vimgrepで探し当てた候補は:cpreviousと:cnextというちょっと面倒なコマンドで選択するようなので、ここはマッピングしときたいですね。
繰り返し操作
去年読んだ『実践Vim』にこのあたりのことはガッツリ書いてあった。.を有効活用せよ、繰り返しができるような操作を心掛けよと。例えばhoge=fugaとあって、イコールの前後にスペースを入れたい場合どうするか。イコールにカーソル持って行ってi<Space><esc>la<Space><esc>とかでももちろんいいんだろうけど、『実践Vim』ではs<Space>=<Space>を進める。挿入モード1回だけで入力が終わるので、この操作は.で使いまわせるからだ。もっと言えばuによるアンドゥも可能。移動→挿入モード→<esc>という動き1回で何が出来るか考えろと、簡単にまとめるとそういうこと。もちろんマクロも使えと。自分は複数行に同じ処理をするときとかによく使ってます。一度記録したマクロを再編集するとか、そういう使い方もあるらしいけど、ちょっとまだそこまではできてない。
コマンド、コード実行
今はtmuxで画面分割して、一方ではVimでコードを書き、もう一方で実行してエラーを確認したりしている。でもこれはVim内で完結できるはずかなと。プラグインとしてvim-quickrunを入れているのに使っていないのが原因。すっごい単純な話、
:QuickRun
さえ覚えておけば、編集中のコードを実行させることができる。長いので何かしらマッピングはしたいが。最初はこれだけやってればいいかもしれない。物足りなくなったらオプションいじってみたり。あとは:!でシェルのコマンド実行できるってこともちゃんと覚えておけば、Vim上だけでやれることがだいぶ増えると思う。
:!echo $HOME
移動
ぶっちゃけキーアサイン覚えるのが面倒なので、基本のhjklとgg,G,あとはft/?あたりによる検索でしか移動してなかった。行番号指定での移動もデバッグのときとか(エラーメッセージ内に行番号出るので)よく使うけど、いちいち移動したい先の行番号確認してコマンド打つのは面倒だなぁとか思っててあまり使ってない。
というわけで移動をもうちょっとハッピーにしようと思う。このあたり?
w 次の単語の語頭へ移動
b 前の単語の語頭へ移動
e 次の単号の語末へ移動
ge 前の単語の語末へ移動
{ 段落単位で戻る
} 段落単位で進む
C-u 画面半分単位で戻る
C-d 画面半分単位で進む
H 画面内最上の行へ移動
M 画面内中央の行へ移動
L 画面内最下の行へ移動
% 対応する括弧へ移動
wbeあたり、wの逆がbに対してeの逆がgeってのは気に入らないなぁ。。。WBEにもそれぞれマッピングはあるみたいだけど、覚えるの面倒だし逆移動にマッピングしちゃってもいいかもと思う。Shift付ければ逆操作になるってのは直感的で良い。あとbbにバッファウィンドウ開くようマッピングしてしまっている自分はbを多用できない問題もあったりする。他は比較的納得感のあるアサインなので覚えやすい気が。特に{}、Vimでブログも書いてる自分は重宝しそう。括弧に関しては自分Rubyをよく書くので、matchitの設定でdefからendとかにも飛べるようにした。
if !exists('loaded_matchit') runtime macros/matchit.vim endif
また移動系だとvim-easymotionを入れているけど使ってないので、使えれば使ってみようかなと。コンセプトとしては3wや4fa等と打つとき、いくつ先に行くのか数を数えなくてはならないという煩わしさがあるので、移動可能な場所候補にラベルを表示して、ラベルの打ち込みにより一発で移動しようというもの。s{char}で画面全体検索というキーバインドもあるみたい。感覚としてはVimperatorのFollow hintの動作に近いのか。ちなみに『実践Vim』では回数指定はやっぱり煩わしいので、.や;で繰り返した方が速いよってなことが書いてあった。
あとctagsとかマークの機能もちゃんと使いたいのだが。ctagsはVimの機能というより、元々あったプログラムを活用して楽に移動できるようにしましたという話なので、そもそものctagsに対する理解を深めなければと思う。マークは次のキーマップを覚えれば使えそうだが、使いこなすのが難しそうな気もする。
m{char} カーソル位置にマークを設定
`{char} 指定のマークに移動
`` 直前のマークに移動
:marks マーク一覧の表示
その他キーマップ
今まであまり使ってなかったけど便利そうなキーマップ、改めてピックアップ。
D カーソル位置から行末まで削除 C カーソル位置から行末まで削除して挿入モード
このキーマップに付随してYもy$に割り当てたいよねってのが↓の記事に載ってたので早速vimrcに追記してます。+で<C-a>,-で<C-x>というのも真似してみた。確かにこれ、今まで便利なのは知ってたけど、キーマップが覚えられてなかった。そういうのはガンガン割り当て替えるべきですね。
s 1文字消して挿入モード
S 1行消して挿入モード
c{operator} 指定範囲を消して挿入モード
sとcの違いが掴めてなかった。cはオペレーターを取る。
zf 折り畳み(folding)
忘れる。これ。あまり使ってないけど。foldingの展開は<Space>で。
ヴィジュアルモードでo 始点と終点を入れ替え
『実践Vim』に載ってた。始点間違えてv押しちゃってもモード抜けなくて済むのですごく便利。
"0p ヤンクレジスタから貼り付け
0はヤンクレジスタにあたり、ヤンクしたテキストが暗黙的に入力されている。ddなどで削除したテキストはこちらには入らないので、よくあるヤンクして数行後の行を削除してからペーストしようとしたら、ddしたものが貼り付けられてしまった、みたいな事象を避けられる。レジスタはこれ意外にもいろいろ奥が深そうなので、機会があれば調べたい。