反省はしても後悔はしない

Vim とか備忘録とか。それと関数型言語勉強中

Nagoya.vim #1 を開催してきた

Vim Advent Calendar 2012 の 282 日目の記事です。

名古屋在住 Vimmer の @sgur さんと一緒に 9/7 土曜日に Nagoya.vim という勉強会を主催してきました。 開催の経緯から当日の様子、ちょっと補足あたりについて書きます。

経緯とか

何回目かの vimrc 読書会で @sgur さんの vimrc を読んでいたのですが、なんとそこで @sgur さんが名古屋在住であることが発覚。僕も名古屋在住だったので nagoya.vim やりましょうかみたいな話に。ちなみに、今ログを見返してみたら nagoya.vim 煽ってたのは id:thinca さんでした。。。しかし、名古屋で Vim 勉強会を開催してもどれだけ集まるか未知数だったので、しばらくは様子を見ることにしました。

sgur さんとの事前打ち合わせ

名古屋の他の勉強会などで「Vim の勉強会やろうかとおもっているんですよー」という話をしたら、「行ってみたい」という人が数名いたので、開催を前向きに検討することにしました。とりあえず何やるかとか決めましょうということで sgur さんと事前打ち合わせをしました。開催日時とか何をやるかとかはその時におおまかに決めました。ちなみに、その時は「あまり知られていない Vim の機能紹介」「unite.vim ユーザに対する ctrlp の紹介」のように少しレベルの高い話にする予定でした。あと、とりあえず 5 人くらい集まれば勉強会の体は保てますかねーみたいな話をしたのを覚えています。

connpass イベントを立てる

早速、20 人くらいの会場を予約して connpass にイベントを立てました。すぐに 10 名程度の参加者が集まって「おー」と思っていました、その時は。そこで、全く予想していない自体が起きます。Qiita の開催する Get Great Git #2 が同日別会場で開催することになったのです。Vim と Git ではかなり参加者層が被ります。正直焦りました。しかし、なんと Git 側の運営から会場は無料で良いので同日同会場で連結して開催しませんかという打診が。sgur さんと相談して Get Great Git と一緒に開催することに決めました。その後 Git との相乗効果もあり参加者がみるみる増加。最終的に 36 名まで集まりました。どうしてこうなった

そして当日

僕はだいたいの勉強会に遅刻してしまうのが常なのですが、さすがに主催者なので開場の10分前には着いていました。偉い。そしていつも調子の悪い僕のノート PC (7 年前のやつ) も当日は特に問題なくプロジェクタと接続出来ました。以下、各発表のレポート

  • (初心者向け) Vim の機能紹介: 参加者に割りと初心者が多いことから追加した発表です。カーソル移動から dot コマンドの使い方までさらっと初心者向けに機能紹介をしました。ほとんど Vim を触ったことがないような人が主なターゲットです。ただ、初心者向けだとある程度 Vim を使いこなしている人には退屈かと思ったのであまり知られていなさそうな Tip を随所に挟みました。割りと当たり前の内容過ぎて退屈されるのではという不安がありましたがそんなこともなく割りとみんなに好評だったみたいでよかったです。反省点としては「とりあえず、:help を引け」と言った割りに :help の使い方まで説明していなかったので後で初心者の人から「:help を打ったはいいが、抜け出せなくなった」と言われてしまい、ちょっと配慮が足らなかったかなと思いました。

  • Vim script と vimrc の正しい書き方: 僕が本当に喋りたかったネタです。僕もそうなんですが、初心者のうちは人の vimrc をワケも分からずコピペして使っている人が多いんじゃないかと思って Vim script と vimrc の書き方について説明しました。実は、Vim script の説明のところは :help usr_41 あたりをとても参考にしていますし、vimrc の書き方は kana さんの「Vim の極め方」に vimrc 読書会で得られた知識をちょっと足しただけの内容です。Vim をよく知らない人でも Vim script の独特のあの感じを理解してもらえたのではないかと思っています。あと、終わった後にいろんな人から「vimrc 見なおしてみます」と言われました。これが聞けただけでも開催した甲斐があったなと思いました。

  • Vim plugin について: sgur さんの発表です。まず Vim plugin の仕組みとか plugin 管理の仕組みから始まり、最後に怒涛のプラグイン紹介という構成でした。とくに Plugin 紹介のところは、おすすめのプラグインを一つ言うのではなく、競合するプラグインを幾つか提示しつつそれぞれのメリット/デメリットを説明していたところがとても良かったです。僕も知らないプラグインがたくさんあってとても勉強になりました。時間があるときにでも公開されている資料を見ながらプラグインを見なおしてみたいと思います。

  • みんなで vimrc を書いてみよう: せっかく vimrc の書き方とかプラグイン紹介とかをやるので参加者が自由に vimrc なりなんなりを書く時間を設けました。結構みんなもくもくと作業していました。うーん、Vim にはもくもくさせる何かがあるんですかね。あと、中途半端に Vim 7.4 の情報を出してしまったせいで、Vim のビルドを始める人もちらほら。主催者としてはそういうのはビルドよりも vimrc を書いてもらいたかったのですが。。。他にもあまり質問を吸い上げられなかったり、普段あまり交流のない人とコミュニケーションできなかったところも反省点でした。

  • その後は引き続いて Git のイベントと懇親会が続く: Nagoya.vim がつつがなく終了した後は予定通り Get Great Git #2 がスタートしました。Nagoya.vim の参加者から引き続いて参加している人が 7 割ほどいたので同時開催にして本当に良かったです。あと、主催の Qiita の偉い人から感謝されました。いやいや、むしろこちらが感謝する側なのに。懇親会もありました。Nagoya.vim の懇親会ではないので Vim の話ばかり出来なかったのはちょっと残念でした。

KPT

  • Keep
    • Nagoya.vim #2 やりたい
    • 講義形式が割りと好評だった
    • 参加者に Vim (のカスタマイズ) に興味を持ってもらえた
    • 名古屋は Vim 不毛の地ではないことがわかった
  • Problem
    • 資料作るのが大変すぎた。次回はもっと負担が少ない方向にするかも
    • 参加者とあまり交流できなかった
  • Try
    • もっと名古屋の Vim 使いとの交流する
    • 読書会形式とかいいかもしれない
    • ハッカソン形式とかいいかもしれない

今後とも、Nagoya.vim をよろしくお願いします。

すごい Vim で Haskell を書こう ... の補足

この記事は Vim Advent Calendar の 274 日目の記事です。昨日は id:osyo-manga さんの unite-highlight つくった でした。

はじめに

先週の日曜日(8/25)になごやまつりというイベントがあり、そこで HaskellVim で書く方法というネタで LT をしてきました。発表するのが決まったのが前日ということもありちゃんとまとまった内容になっていなかったので、本エントリで少し補足を書きたいと思います。

とりあえず、インデントをどうにかする

発表では「Haskell のデフォルトのインデントプラグインは全然ダメ」という発言をしましたが、間違いでした。訂正します。 「Haskell のデフォルトのインデントプラグインなんてなかった!」

まさか、ないとは...。

という訳で、インデントプラグインを入れましょう。作者は Vim 界の神こと kana さんです。

NeoBundle 'kana/vim-filetype-haskell'

これで、↓みたいな残念な感じのが、

f:id:cohama:20130901013812p:plain

↓のようにちゃんとインデントされます。ただ、Haskell のインデントの計算は難しいっぽく常に正しいインデントが得られるとは限らないので適宜手動で調整が必要です。

f:id:cohama:20130901013829p:plain

型の表示

Haskell は静的型付け言語です。せっかく型の情報があるのでこれを Vim 上で表示できると便利そうです。

まず、外部コマンドの ghc-mod というものを用意します。これは cabal で簡単にインストールできます。

$ cabal install ghc-mod

あとは、このコマンドの出力を Vim から使えるようにする ghcmod.vim というプラグインを入れます。

NeoBundle 'eagletmt/ghcmod-vim'

Haskell のコード上でおもむろに :GhcModType すると現在のカーソルがある位置の項がハイライトされ、その型が下の方に表示されます。 ハイライトを消すには GhcModTypeClear します。常用するにはコマンドが長いので適当に \t とかにマップすると良いでしょう。

f:id:cohama:20130901013130p:plain

いい感じで補完をする

Haskell でも IDE のように空気を読んだ補完をしたいものです。これも ghc-mod でできるのでその出力を使って補完するプラグインがあれば可能になります。

NeoBundle 'Shougo/neocomplcache'
NeoBundle 'ujihisa/neco-ghc'

f:id:cohama:20130901013143p:plain

Haskell のコードを即座に実行する

ちょっと Haskell のコードを書くときなんかに、今編集しているファイルを Vim 上からすぐに実行できると便利です。そういう時のために 'quickrun' というプラグインがあります。Haskell だけでなく他にもいろいろな filetype に対応しています。

NeoBundle 'thinca/vim-quickrun'

f:id:cohama:20130901013232p:plain

Haskell のエラーを Vim 上に表示する

文法のエラーや型エラー何かを Vim 上で表示するととても便利です。これも ghc-mod でできるので、その結果を使うプラグインを入れましょう。

NeoBundle 'osyo-manga/vim-watchdogs'

vim-watchdogs を使うと ghc-mod を使ってチェックした結果を Quickfix に突っ込むことができます。それをさらに別のプラグインを使って Vim のウィンドウに結果を表示させています。このプラグインは Haskell 以外にも RubyJavaScript など他の filetype にも汎用に使えるので便利なのですが、依存関係や設定が少し面倒なのが玉に瑕です。詳しくはwatchdogs.vim つくりました - C++でゲームプログラミング で説明されています。

f:id:cohama:20130901013200p:plain

watchdogs 入れるの面倒だよという人はさっきの型の表示に使った ghcmod.vim でも同様のことができます。:GhcModCheckAndLintAsync とすると watchdogs と同様にチェックの結果を Quickfix に突っ込みます。

Vim から即座に hoogle を引く

hoogle というのは Haskell のリファレンスです。すごいやつです。例えば、人のソースコードを読むなどのときによく分からない関数などが出てきたらとりあえず、Hoogle を引きたいですよね。Vim から。これを可能にするのが ref-vim および ref-hoogle です。なお、実行には cabal install hoogle が必要です。

NeoBundle 'thinca/vim-ref'
NeoBundle 'ujihisa/ref-hoogle'

調べたいキーワードにカーソルを合わせて K で hoogle の結果が表示されます。

f:id:cohama:20130901013244p:plain

もっと import を便利にする

Haskell では import 文はファイルの先頭にまとめるのが普通のようですね。しかし、いちいち先頭まで移動して import を書くのは面倒です。これを解決するのが unite-haskellimport です。当たり前ですが unite.vim に依存します。あと hoogle も必要です。

NeoBundle 'Shougo/unite.vim'
NeoBundle 'ujihisa/unite-haskellimport'

:Unite haskellimport すると Unite のインターフェースでパッケージを選択→挿入できます。 詳しくは Vim-users.jp - Hack #241: Haskellで使いたい関数を使ってからそのモジュールをimportする を参照してください。

おわりに

すみません。偉そうに書いた割に実は Haskell は全然書けないのです。適当にネットとかで調べたのをまとめただけです。もっと Haskell を勉強すれば便利な機能とかプラグインとかに気づくかもしれません。頑張って勉強します。

明日は id:manga-osyo さんです。

インサートモード時に行番号の色を反転させる Vim のプラグイン作った

この記事は Vim Advent Calendar 2012 の 259 日目の記事です。 昨日は @IMAGEDRIVE さんの Vim で EPUB を制作する時に役に立つかもしれないスニペットファイル でした。

はじめに

Vim はモード切替が特徴的なエディタですが、ときどき自分がインサートモードなのかノーマルモードなのかわからなくなることってありますよね。(ありませんか。そうですか)

たとえば、ステータスラインを使ってモードを識別するようなのはすでに vim-powerline とか insert-statusline とかありますね。

でも、ステータスラインだと解像度の高いモニタで画面上部を編集しているときにステータスラインが目に入らなくて微妙に困ります。

そこで、行番号の色を変えてモードの識別をする Vim のプラグインをつくりました。行番号ならばカーソルがどこにあっても結構目立つ上、編集の邪魔にもあまりなりません。

vim-insert-linenr

vim-insert-linenr

NeoBundle 'cohama/vim-insert-linenr'

NeoBundle などでインストールすればすぐに使えます。

ノーマルモード時

f:id:cohama:20130816162928p:plain

インサートモード時

f:id:cohama:20130816162931p:plain

こんな感じで、行番号の色が反転表示になります。

明日は @ujihisa さんです。

Vim のカラースキームが微妙に気に食わないときの対処法

この記事は Vim Advent Calendar の 253 日目の記事です。昨日は id:tyru さんの Alt-Spaceでウインドウのメニューを表示、あとウインドウの最大化 でした。

はじめに

Vim にはたくさんのカラースキームがありますね。きっとみなさんは、たくさんあるカラースキームの中からお気に入りを見つけて設定をしていることでしょう。

しかし中には 99% 気に入って入るけれど、1% だけ微妙に気に食わないという場合もあるかと思います。今日はそんなときにカラースキームの一部だけをちょこっと改造する方法を紹介します。

:highlight を vimrc に書く (基本編)

色を変えたい部分は highlight コマンドをちょろっと vimrc に書けば OK です。

" 以下のコマンドは :colorscheme の前に設定します
" コメントを濃い緑にする
autocmd ColorScheme * highlight Comment ctermfg=22 guifg=#008800
" ...
colorscheme molokai

まず、:highlight コマンドは autocmd ColorScheme で囲むようにします。こうすることにより、気が変わって途中でカラースキームを変えたとしても再度設定し直されるようになります。

Comment というのがコメントを表しています。他にどういうのがあるかは :help group-name :help highlight-groupsして調べてみましょう。ソースコードの要素だけでなく行番号やビジュアルモードの選択範囲なども設定出来ます。

ctermfg はターミナルの、guifg は GUI 版の Vim の前景色を表します。GUI 版の場合は CSS などでお馴染みの RGB を 16 進数で記述しますが、ターミナルの場合は色を表す番号で指定します。どの番号がどの色かを調べる Perl スクリプトがあるのでそれを利用すればよいでしょう。

f:id:cohama:20130811020341p:plain

ほかにも太字にしたい場合は cterm=BOLD gui=BOLD などのように設定出来ます。

蛇足 syntax と highlight

ここからは応用編です。 Vim の色を決定しているのは主に syntax と highlight という仕組みです。syntax は構文とその構文が属するハイライトグループを決定するもので、例えば "hoge" は文字列、int はキーワードなどのように各言語ごとに用意された構文用のファイルに従って決定されます。highlight は各ハイライトグループどのように色付けするかを設定するものです。文字列は緑、キーワードは青などのように設定します。

どのハイライトグループがどのように highlight されているかは :highlight コマンドを引数なしで起動することで確認できます。

f:id:cohama:20130811020358p:plain

この出力を眺めていると、ハイライトの仕方ではなく link to となっているものがあることに気づきます。実はハイライトグループは他のハイライトグループにリンクさせることができます。

例えば、Vim script の文字列は vimString、Ruby の文字列は rubyString というハイライトグループになっていますが、どちらも String というハイライトグループにリンクされています。これにより、String というハイライトグループだけ変更すればほとんどの言語での文字列の色を帰ることができます。また、逆に特定の言語の文字列の色だけを変えるということもできます。(デフォルトでちゃんと設定されていれば)

カーソル下の syntax 情報を取得する

例として以下の Ruby ファイルを見てください。

f:id:cohama:20130811020503p:plain

これは、molokai というカラースキームで Ruby ファイルを表示したものですが、module class といったキーワードと実際のモジュール名、クラス名が同じ色になってしまっています。これを改善するために module class というキーワードの色を変えたいとして、これらがどのハイライトグループに属するかが予めわかっていないといけません。

そこで、Vim script の synID synIDattr synIDtrans という組み込みの関数を使って構文情報とそのハイライト情報を取得してみましょう。

以下の様な Vim script を書いてみます。

function! s:get_syn_id(transparent)
  let synid = synID(line("."), col("."), 1)
  if a:transparent
    return synIDtrans(synid)
  else
    return synid
  endif
endfunction
function! s:get_syn_attr(synid)
  let name = synIDattr(a:synid, "name")
  let ctermfg = synIDattr(a:synid, "fg", "cterm")
  let ctermbg = synIDattr(a:synid, "bg", "cterm")
  let guifg = synIDattr(a:synid, "fg", "gui")
  let guibg = synIDattr(a:synid, "bg", "gui")
  return {
        \ "name": name,
        \ "ctermfg": ctermfg,
        \ "ctermbg": ctermbg,
        \ "guifg": guifg,
        \ "guibg": guibg}
endfunction
function! s:get_syn_info()
  let baseSyn = s:get_syn_attr(s:get_syn_id(0))
  echo "name: " . baseSyn.name .
        \ " ctermfg: " . baseSyn.ctermfg .
        \ " ctermbg: " . baseSyn.ctermbg .
        \ " guifg: " . baseSyn.guifg .
        \ " guibg: " . baseSyn.guibg
  let linkedSyn = s:get_syn_attr(s:get_syn_id(1))
  echo "link to"
  echo "name: " . linkedSyn.name .
        \ " ctermfg: " . linkedSyn.ctermfg .
        \ " ctermbg: " . linkedSyn.ctermbg .
        \ " guifg: " . linkedSyn.guifg .
        \ " guibg: " . linkedSyn.guibg
endfunction
command! SyntaxInfo call s:get_syn_info()

これで :SyntaxInfo というコマンドによりカーソル下の構文情報(ハイライト情報)を取得できるようになりました。

f:id:cohama:20130811020537p:plain

f:id:cohama:20130811020543p:plain

調べてみると、module は rubyModule で Define というハイライトグループにリンクしており、モジュール名(Hoge) は rubyConstant でType というハイライトグループにリンクしていることが分かります。

この情報を使って色を変えてみましょう。

autocmd ColorScheme * highlight rubyModule guifg=#88ff88

f:id:cohama:20130811020555p:plain

これで Ruby の時だけ module というキーワードの色を変えることができました。

カラースキームを自作してみる

いろいろ改造していると、たくさんの :highlight コマンドが vimrc に増えてきます。そこまで来たらむしろカラースキームを作ってしまったほうが良いでしょう。

乱暴に言ってしまうとカラースキームの実態はここで説明した highlight コマンドの集合体です。なので、既存のカラースキームを改造するだけの場合は結構簡単に作れます。

カラースキームの作り方については下記の id:thinca さんの記事がとても参考になるでしょう。 *1

カラースキームを作ってみよう

まとめ

  • :highlight を vimrc に書けば色付けを変更できる
  • synID などの関数により構文情報を取得できるのでハイライトの設定に便利
  • カラースキームの自作は難しくない

明日は @ujihisa さんです。

*1:書いている途中でネタかぶりに気づきました

Vim 7.4 からの ocaml.vim の変更点

Vim の次期バージョンである Vim 7.4 *1から、デフォルトの ftplugin/ocaml.vim が変わります。 というかデフォルトのやつがいろいろひどかったので僕がパッチを書きました。

パッチを書くにあたり、github の vim-jp の人たちにいろいろ教えてもらいました。ありがとうございました。

変更点

  • global なマッピングを排除してすべて buffer-local なマッピングに

一番許せなかったやつです。型を表示させる <LocalLeader>t がなぜか global なマッピングになっていましたが、最新版では buffer-local になっています。

  • すべてのコマンドに <Plug> によるインターフェースを追加

既存のキーマップを変えたい場合に便利です。

<Plug>マッピング デフォルトの割り当て 機能
<Plug>OCamlSwitchEdit <Localleader>s ml と mli を切り替え
<Plug>OCamlSwitchNewWin <Localleader>S ml と mli を切り替え(分割して開く)
<Plug>OCamlPrintType <Localleader>t 型を表示

デフォルトのマッピングをさせたくない場合は vimrc に let g:no_ocaml_maps = 1 と書きましょう。

  • きもい abbrev を削除

ASS で assert (0=1) とかに展開されるなどという設定があったのですが、こういう個人的な設定はデフォルトの ftplugin にはふさわしくないので削除。他の ftplugin でも abbrev を設定しているようなものはほとんどないようですね。欲しい人は自分で vimrc に書きましょう。

*1:正確には、アルファ版の Vim 7.4a.047

おすすめの :help まとめ

この記事は Vim Advent Calendar 2012 の 240 日目の記事です。 昨日は id:thinca さんの 空間を飛び越えろ!portal.vim を作りました でした。

:help について

:help といえばおなじみ Vim のヘルプを引くためのコマンドです。

:help の引き方については過去の良質な記事を参照しましょう。

しかし、:help はあくまでもリファレンスであるため、調べたい対象がある程度わかっている場合でなければ望んだ情報にたどり着けません。 そこで、今回は膨大な :help のページの中からおすすめを紹介します。

一番最初の :help

:help

引数なしで :help を起動します。:help から見れるページの目次が閲覧出来ます。気になる項目があれば <C-]> で閲覧してみましょう。

ユーザマニュアル

:help usr_toc

Vim の使い方や機能が体系的にまとまっています。とりあえず、Vim 初心者の人は初級編の :help usr_01 から順番に読んでいきましょう。Vim に慣れた人でも時間があるときに全部読んでみましょう。新しい発見があるかもしれません。

クイック・リファレンス

:help quickref

Vim のよく使うコマンドを網羅したクイックリファレンスです。機能ごとに分類されています。クイックリファレンスなのに約 1400 行あります。Vim にはそれだけ膨大なコマンドがあるってことですね。これも時間があるときに目を通してみるといいとおもいます。詳細な説明を読みたければ <C-]> です。

:help index

Vim の(ほとんど)すべてのコマンドがまとめてあります。こちらはアルファベット順になっています。

オプションまとめ

:help option-list

一番最初に vimrc を書くとすればまずはオプションの設定でしょう。このページでどんなオプションがあるかを調べて自分だけの Vim にカスタマイズしましょう。実はこのページは先ほど紹介した quickref の中にあります。

Tips

:help tips

Vim Advent Calendar の中でも Tips 系の記事は人気ですね。Vim のヘルプの中にも Tips のページがあります。一度覗いてみると良いでしょう。

Vim の起動引数

:help startup-options

Vim には起動するときにオプションとして引数を渡せます。たとえば vim --noplugin でプラグインを読み込まない、などです。このページでどんな起動引数があるか調べましょう。

Vim のウィンドウについて

:help windows

Vim のウィンドウは水平や垂直に分割できたりしてかなり高機能なのですが、それ以外にもいろいろ機能があります。このページに Vim のウィンドウについての情報があります。ちなみに、OS の Windows について知りたい場合は :help win32 です。

Vim のタブページについて

:help tabpage

あまり使いこなされていないという噂の Vim のタブページについての help です。<Tab> と混同しないようにしましょう。

Vim正規表現

:help pattern-overview

Vim正規表現は結構独特で記号なんかどれをエスケープすべきかいつも忘れます。そんな時はこのページを見に行きましょう。Vim で使えるパターンがまとめてあります。

Vim script

:help usr_41

Vim を本気でカスタマイズしようと思ったら Vim script を書かざるを得ません。このページでは Vim script について学ぶことができます。変数、条件文、ループ、関数と Vim script の基本的な部分かプラグインの書き方まで体系的に説明されています。量が多い (2400 行ほど) ので一気に読むのは大変です。最初は基礎的なところだけでいいでしょう。

Vim script の関数一覧

:help function-list

上の usr_41 の一部なのですが、Vim script で使える関数の一覧が機能ごとにまとまっています。

:help functions

こちらはアルファベット順です。

プラグインを書く

:help write-plugin

これも usr_41 の一部ですが。Vim script に小慣れてきたら自分でプラグインを作ってみたくなるものです。プラグインの書き方については良質な記事が Web 上にもありますが、:help に書いてある方も読んでおくといいかもしれません。

:help write-filetype-plugin

ftplugin を作る場合はこちら。

:help help-writing

プラグインを書いたら必ずドキュメントも書きましょう。このページでは自作プラグインのためのヘルプの書き方が説明されています。

Vim の哲学

:help design-goal

Vim そのものを開発するための設計目標が書かれていますが、Vim はかくあるべきという哲学とも言えます。特に design-not には Emacs との考え方の違いに言及されているので一度読んでおくと良いです。

最後に

Vim の :help は情報の宝庫です。:help をうまく活用して Vim の戦闘力を高めましょう。 ちなみに、vimrc 読書会では「歩く :help」みたいな人がたくさんいて気軽に質問に答えてくれます。

明日は id:manga_osyo さんです。*1

*1:おしょーさんすごい

あなたの知らない Vim ~ デフォルトの ftplugin 達 ~

この記事は Vim Advent Calendar 2012 の 214 日目の記事です。 昨日は id:manga_osyo さんの Vim で Web ページを :source する でした。

Vim では何も設定せずとも様々なプログラミング言語のためのシンタックスがはじめから提供されています。マニアックなプログラミング言語を編集しようとしていきなりシンタックスで色付けがされてたりするので驚きです。

実は、Vim にはシンタックスだけでなくプラグインみたいなものも言語別にあります。それが ftplugin です。言語によってコメントの仕方やコンパイルエラーの解析*1だけのものからマッピングやコマンドなどの機能まで提供されているものまであります。しかし、これらは help に書かれておらず調べるには自分でソースを読まないといけないのでなかなか知られていないのが現状です。

そこで、今回はこの知られざる ftplugin の世界を紹介したいと思います。

いざ旅立とう 知られざる ftplugin の世界へ

面倒なプラグインのインストールや設定はほとんど不要です(基本的には)!今お使いの Vim (7.3) ですぐに動作します。

追記 filetype plugin on を vimrc に書く必要があります。完全に忘れてた。thx thincs さん。

git

Git のエディタを Vim にしているとコミットするときに Vim が立ち上がりますね。え、Git の設定をしていない?それはいけない。今すぐ設定しましょう!

git config --global core.editor vim

さて、Git の何らかの編集(commit や rebase -i とか)をするときには Vim 上ではいろいろ便利な機能がデフォルトで使えます。

コマンド 機能 備考
gf, <C-w>f など カーソル下のファイルを開ける diff 表示の時の a/hoge b/hoge みたいなのでも開ける。ちなみに、gf よりも <C-w>f とか <C-w>gf とかの方がコミットメッセージ編集用のバッファが迷子にならないのでおすすめ
K カーソル下のリビジョンで git show する rebase -i の時はカーソル下じゃなくてもOK。すごく便利。ちなみに、Vim のカレントディレクトリが全然別のところにあっても正しいパス上で実行されます
:DiffGitCached コミットされる予定のファイルの差分をプレビューウィンドウで見る コミットメッセージの編集時のみ。ちなみに、開いたプレビューウィンドウは q で閉じれるようになっている
:Pick rebase -i のあれを pick にする rebase -i の編集時のみ。マッピングを設定すると便利かもしれない。
:Squash rebase -i のあれを squash にする 同上
:Edit rebase -i のあれを edit にする 同上
:Reword rebase -i のあれを reword にする 同上
:Fixup rebase -i のあれを fixup にする 同上
:Cycle pick, squash, edit, reword, fixup を順に切り替える 同上

ちなみに、書いた人は fugitive や pathogen や rails.vim の作者の Tim Pope 氏のようです。信頼と実績の ftplugin ですね。

ruby

Ruby 界隈は Vimmer が多いと勝手なイメージを持っています。

コマンド 機能 備考
K カーソル下のキーワードを ri で調べる
キーワードの上にマウスカーソルを置く マウスカーソル位置のキーワードを ri で調べてバルーンで表示 GVim のみ。set ballooneval しておく必要があります
]m, [m 次(前)のメソッド定義(def)に移動
]M, [M 次(前)のメソッド定義の終わり(end)に移動
]], [[ 次(前)のクラス、モジュール定義(class, module)に移動
][, [] 次(前)のクラス、モジュール定義の終わり(end)に移動

ちなみに、vim-ruby というプラグインを入れている人も多いと思いますが、vim-ruby はこれらのデフォルトの ftplugin に追加で textobj とかを提供しているので vim-ruby の有無に関係なく上記のコマンドは使えます。

python

私自身は python はほとんど書けないのですがとりあえず、紹介します。 そういえば、最近 VimPython IDE 化する記事がありましたね。設定が面倒くさくてやっていない人もとりあえず、デフォルト機能くらいは覚えておくといいんじゃないでしょうか。

コマンド 機能 備考
]], [[ 次のトップレベルのクラス、メソッド定義(class, def)に移動 nnoremap しかないのでビジュアルモードでは使えません
]m, [m 次のクラス、メソッド定義(class, def)に移動 nnoremap しかないのでビジュアルモードでは使えません
gf, <C-w>f など from, import とかに書いてあるファイルを開く hoge.fuga は hoge/fuga.py みたいな感じで開かれます。ただし、あまり賢いことはしてくれないようです。

ocaml

静的型付け関数型言語です。楽しい! OCaml は割りとデフォルトでもいろんな機能があります。ちなみに、同じく静的型付け関数型言語Haskell の ftplugin には最低限の設定しかないです。

コマンド 機能 備考
<LocalLeader>s ml と mli ファイルを切り替える
<LocalLeader>S ml と mli ファイルを切り替える(分割して開く)
<LocalLeader>c コメントアウト ノーマルモードのときは行コメント、ビジュアルモードのときは複数行コメントになります
<LocalLeader>C コメントアウトを解除
(インサートモードで)ASS (assert (0=1) ( XXX )) を挿入 iabbrev なので何か他のキーを押した時に展開されます
<LocalLeader>t カーソル下の項の方を表示 annot ファイルが存在している必要があります

<LocalLeader> はデフォルトで \ になっています。let g:maplocalleader = ','などのようにすれば変更できます。

sql

突然の SQL!!! お仕事とかで書く人とかいそうですね。私は資格試験のために勉強しただけで書いたことないです...。ちなみに、ここで紹介する以外に割りと細かいオプションを設定できるようです(ソースを見る限り)。たぶんいろんな方言に対応させるためなんでしょうね。正直全然わからないので気になる人はソースを読んでみるといいと思います。

コマンド 機能 備考
]], [[ 次(前)の begin に移動
][, [] 次(前)の end に移動
]}, [{ 次(前)の create 文に移動 どの文に移動するかはg:ftplugin_sql_statementsで設定可能
]}, [{ 次(前)の create 文に移動 どの文に移動するかはg:ftplugin_sql_statementsで設定可能
]" 次のコメントの始まりに移動
[" 次のコメントの終わりに移動

おわり

割りとメジャーそうな(独断)言語の中で便利な機能が定義されているのは以上でした。もっとあるかと思ったのですが。。。 気になる方は $VIM/vim73/ftplugin 以下を探索してみてはいかがでしょうか?

明日は @supermomonga さんです。

*1:QuickFix で使います