Vimの極め方

Vim勉強会#3@大阪

kana <http://whileimautomaton.net/>

はじめに

自己紹介

Vim歴

何故Vimを極めるのか

「メモ帳でも良いじゃない」

目次

準備編: :helpを使いこなす

何故:helpか?

:helpを使いこなす = Vimを極めるための一歩

:helpの欠点

最初の一歩

:help

:helpの引き方

基本

:help {topic}
  • {topic}についての項目を表示する
    • :help CTRL-]
    • :help :tag
    • :help taglist()
    • :help tags
  • 省略形: :h
    • 普通は:hを使う

{topic}は正確でなくていい

それっぽい項目が選ばれて表示される

  • :help quickref → クイックリファレンス
  • :help quickr → 同上
  • :help quick → quickfixの概要
  • :help qui:quitの説明
  • :help q → recordingのqコマンドの説明

{topic}は正確でなくていい(補足)

  • 対話的に調べる場合に便利
  • ポインタを示すときは正確に書いた方が良い
  • :helpの内容が更新される → 飛び先が変化する(かも)

{topic}は補完できる

<C-i>
補完開始
<C-n> / <C-p>
候補選択
<C-d>
補完候補を全て表示

詳細: :help cmdline-completion

補完を活用した{topic}の探し方

:help '*key<C-d>
「key」を含むオプションの一覧
:help *key*(<C-d>
「key」を含む関数の一覧
:help v_<C-d>
Visual modeのキーバインドの一覧

飛ぶ/戻る

<C-]> - カーソル下の項目に「飛ぶ」
それっぽくハイライトされているものは大体「飛ぶ」ことができる
<C-t> - 「戻る」
「飛ぶ」直前の箇所に「戻る」

詳細: :help tags-and-searches

おまけ

  • :helpは英語版を使おう
  • :helpを読む習慣をつけよう
  • :helpを書こう

:helpは英語版を使おう

  • 日本語版を使っていいのは初心者まで
  • {topic}は全言語共通
  • でも{topic}自体は英語
  • 英語版ならどこに何があるか自然と覚える

:helpを読む習慣をつけよう

  • 読めば読むほど発見がある
  • 暇な時間ができた → :helpの面白そうな項目を読む
  • 全て読もうとは思わないこと(分量が膨大)
  • おすすめ項目: options, quickref, tips
  • 基本的な使い方の復習: usr_01から順に

:helpを書こう

  • 書式は簡単(プレインテキスト+ちょっとしたマークアップ)
  • どんなメディアよりも素早く調べられる
  • ユーザーにも便利、作者自身にも便利
  • :helpのないプラグインは爆発しろ

準備編: vimrcを変更し易い環境を整える

何故?

Vimは優秀ではない

デフォルトのままでは不便な点はいくらでもある

  • 押し難いキーバインド
  • 覚え難いキーバインド
  • キーの割り当てられていないコマンド
  • 自分好みではない動作や設定
  • その他色々

結論: vimrcを書こう

変更し易い環境を整えると

  • 不便な点を発見
  • 即座に修正できる
  • 即座に修正結果を反映できる
  • vimrcがどんどん自分色になっていく
  • 編集効率が向上していく → 時間の節約

変更し難い環境だと

  • 不便な点を発見
  • 修正するのが億劫
  • なかなか修正されない
  • vimrcが変更されない → 不便なまま
  • 編集効率が向上しない → 時間の節約ができない

vimrcを即座に開く

マークを活用する場合

  1. :edit $MYVIMRC - vimrcを開く
  2. mV - カーソル位置をマーク
  • 'Vで即座にvimrcが開ける
  • 利点: 対話的に設定可能 / 即座に反映される
  • 欠点: viminfoがなくなるとマークしなおす必要がある

詳細: :help mark-motions

専用ホットキーを定義する場合

nnoremap <Space>.
\        :<C-u>edit $MYVIMRC<CR>
  • <Space>.で即座にvimrcが開ける
  • 利点: viminfoがなくなっても安心
  • 欠点: マークに比べて設定と反映が面倒

vimrcを即座にリロード

専用Exコマンドを定義する場合

command ReloadVimrc  source $MYVIMRC
  • :ReloadVimrc<Return>でリロード

専用ホットキーを定義する場合

nnoremap <Space>s.
\        :<C-u>source $MYVIMRC<CR>
  • <Space>s.でリロード

リローダブルなvimrcを書く

何故?

  • 記述内容によってはリロードで問題が起きる
  • 設定反映のためにVimを再起動するのは面倒
  • リローダブルなvimrcを書くべき

変数やオプションの設定でありがちなミス

  • 駄目な例
  • 正しい例

駄目な例

set backupdir+=/foo
  1. set backupdir+=/foo,/barに変更してリロード
  2. &backupdir ==# '...,/foo,/foo,/bar'になってしまう

正しい例

set backupdir& backupdir+=/foo

変数やオプションの設定で+=-=を使う場合、デフォルト値も明らかにする

関数とExコマンド定義でありがちなミス

  • 駄目な例
  • 正しい例

駄目な例

command Foo  ...
function Foo()
  ...
endfunction
  • デフォルトでは上書き定義できない
  • リロード時にエラー

正しい例

command! Foo  ...
function! Foo()
  ...
endfunction

上書き定義するために!を付ける

:autocmdの定義でありがちなミス

  • 駄目な例
  • 正しい例(1)
  • 正しい例(2)

駄目な例

autocmd BufEnter *  ...
autocmd BufLeave *  ...
...
  • :autocmdは常に「追加」される
  • リロードされるたびに「追加」される
  • リロードで徐々に重くなるか妙な副作用が起きる

正しい例(1)

augroup MyAutoCmd
  autocmd!
  autocmd BufEnter *  ...
  autocmd BufLeave *  ...
  ...
augroup
  • 追加する前にリセットする
  • :augroupを使って自分が追加した:autocmdをまとめておく

正しい例(2)

augroup MyAutoCmd
  autocmd!
augroup END

autocmd MyAutoCmd BufEnter *  ...
autocmd MyAutoCmd BufLeave *  ...
...
  • :augroup:autocmdを分けて記述することもできる

実践編: vimrcを自分色に染める事例集

オプションを簡単に切り替える

問題

  • 一部のオプションはよく切り替える
  • でも:setl wrap!と入力するのは面倒
  • オプションは省略名があるがそれでも面倒

解決方法

nnoremap <Space>ow
\  :<C-u>setlocal wrap!
\ \|     setlocal wrap?<CR>
  • 専用キーを割り当てる
  • 例: <Space>ow'wrap'を切り替え
  • 他のオプションでも同様

レジスタ/マークの確認を楽にする

問題

  • レジスタやマークの内容はよく忘れる
  • でも:marks等の入力は面倒

解決方法

nnoremap <Space>m  :<C-u>marks
nnoremap <Space>r  :<C-u>registers
  • 専用キーを割り当てる
  • 例: <Space>mでマーク内容を確認

最後に変更されたテキストを選択する

問題

  • gvで最後にVisual modeで選択された領域を再度選択できる
  • 同様に「最後に変更されたテキスト」を選択したいときがある
  • 例: ペーストしたテキストをインデントしたい

解決方法

nnoremap gc  `[v`]
  • `[`]で最後に変更された範囲へ移動できる
  • 注: 厳密には上記の定義は不完全

/と?の検索を楽にする

問題

  • /での検索時、/を検索するには\/と書く
  • ?も同様
  • いちいちエスケープするのは面倒

解決方法

cnoremap <expr> /
\ getcmdtype() == '/' ? '\/' : '/'
  • 検索パターン入力中は/\/を入力
  • /そのものを入力するには<C-v>/とタイプ
  • ?については同様なので省略

文字エンコーディングを指定してファイルを開く

問題

  • 稀に文字エンコーディングの判定に失敗する場合がある
  • いちいち:e ++enc=utf-8等と入力するのは面倒

解決方法

command! -bang -nargs=? Utf8
\ edit<bang> ++enc=utf-8 <args>
  • 専用のExコマンドを作成する
  • :Utf8で現在のファイルをUTF-8で開き直す
  • 他のエンコーディングも用意すると便利

tab pagesを使い易くする

問題

  • Vim 7の新機能tab pages、みんな知ってるね
  • デフォルトのキーバインドは今一
  • キーが割り当てられてないコマンドも色々

解決方法

nnoremap <C-t>  <Nop>
nnoremap <C-t>n  :<C-u>tabnew<CR>
nnoremap <C-t>c  :<C-u>tabclose<CR>
nnoremap <C-t>o  :<C-u>tabonly<CR>
nnoremap <C-t>j  :<C-u>execute 'tabnext' 1 + (tabpagenr() + v:count1 - 1) % tabpagenr('$')<CR>
nnoremap <C-t>k  gT
...
  • 注: <C-t>のデフォルトはtags-and-searchesの「戻る」なので代替キーを用意しないと困る

tags-and-searchesを使い易くする

問題

  • :helpの実態: tags-and-searches
  • 「飛ぶ」「戻る」の正体もこれ
  • 関連するExコマンドは沢山ある
  • キーが割り当てられているのはほんの一部
  • デフォルトのキーバインドは押しにくい
  • デフォルトのキーバインドは覚えにくい

解決方法

nnoremap t  <Nop>
nnoremap tt  <C-]>           「飛ぶ」
nnoremap tj  :<C-u>tag<CR>   「進む」
nnoremap tk  :<C-u>pop<CR>   「戻る」
nnoremap tl  :<C-u>tags<CR>  履歴一覧
...                          その他
  • 抜本的にキーバインドを変えてしまおう
  • tをプレフィックスキーにする
  • 副作用: :helpのナビゲーションが快適に

Exコマンドを1.5倍の速度で実行する

問題

  • 多くの機能はExコマンド限定
  • でも使う機会は非常に多い
  • 例: :edit, :write, ...
  • しかし:はホームポジションにない
    • JIS配列: ;の右隣、右小指ホームポジションの1つ右
    • US配列: Shift+;
    • 負荷: ホームポジション=1 : :=1.5くらい
  • 注: QWERTY配列の話

解決方法

noremap ;  :
noremap :  ;
  • ;でCommand-line modeに移行
  • :には;の本来の機能を割り当てる
  • テキスト入力時はそのまま → Vim素敵!
  • Exコマンドの入力初速度: 1.5倍(当社比)
  • 些細な変更でも効果は絶大

:helpを3倍の速度で引く

問題

:h {topic}
  • {topic}について調べようと思うと
  • :h<Space>と3キーも入力

解決方法

nnoremap <C-h>  :<C-u>help<Space>
  • <C-h>の1キーで:h<Space>が入力される
  • {topic}を調べる準備が3キーから1キーに
  • 3倍の効率(当社比)

トリビア

  • アイデアはEmacsからの流用
  • <C-h>でヘルプ」は良いのだけど
    • *nixで<C-h><Backspace>と同義
    • 1文字削除しようと<C-h> → 何も起きない
    • 押し損ねたかと思い<C-h> → ヘルプのヘルプが表示
    • Emacs爆発しろ
  • でもVimなら両立できる → Vim素敵!

ヒント

不便だと思ったことはメモする

  • あの操作を一発でできないか
  • あのキーは押し難いから変えたいな
  • あんなExコマンドがあったら便利だな
  • ...
  • 以上のようなことは即座にメモする
  • メモしないと絶対に忘れる
  • 後でメモを見返してvimrcを弄る

vimrcを弄った結果や過程は公開しよう

  • 他の人が参考にできる
  • フィードバックがもらえる(かも)
  • 公開ははてなvimグループを使うと良い (宣伝)
  • どうしても分からなければ訊くのも手
  • 質問は http://lingr.vim-users.jp/ ですると良い (宣伝)

vimrc成長過程(一例)

あるVim使いのvimrcの成長過程

日時 行数 単語数 バイト数
2007-01-01 93 240 1940
2007-07-27 912 2448 21405
2007-12-23 1788 5578 46195
2008-08-22 2242 7341 57178

まとめ