vim-users.jp

Hack #241: Haskellで使いたい関数を使ってからそのモジュールをimportする

Posted at 2011/12/19
このエントリーをはてなブックマークに追加

Haskell Advent Calendar 2011への寄稿記事です。

問題

Haskellを書いていて、長いソースコードの末尾の方にて、急にとあるモジュールのとある関数を使いたい、そんなときはよくあります。ありがちなのがApplicativeの演算子いくつかと、Data.Function.onと、Data.Listのアレとコレと・・・。いくらでもあります。

Haskellでは一般的に、モジュールのimportはソースコードのかなりはじめの方にまとめて記述します。importしたい関数を一度しか使わず、しかもソースコードの末尾の方に位置していようと、おかまい無しです。このとき、ggなどでソースコード上部まで移動し、neco-ghcなどを駆使してmoduleとその関数を的確にimportし、そして<C-o>などでもといた場所に戻ることになると思います。:spなどで画面分割してから行ったり、あるいはmarkをつけるという方法もありますが、いずれにせよこれらの作業のため脳内の作業メモリがスタックオーバーフローするのは明らかでしょう。

解決

unite-haskellimportを用います。

https://github.com/ujihisa/unite-haskellimport

まずは上記プラギンをインストールします。依存プラギンはunite.vim、依存ツールはhoogleです。

$ cabal update && cabal install hoogle && hoogle data

たとえば急に==>という関数を使いたくなったとしましょう。

:Unite haskellimport

としてunite窓を開き、==>と打鍵しましょう。

Test.QuickCheck.Property (==>) :: Testable prop => Bool -> prop -> Property
Test.QuickCheck (==>) :: Testable prop => Bool -> prop -> Property

インストールしているcabalパッケージにもよりますが、たとえば上記のような項目が選択肢にでてくることでしょう。実際にimportしたい側を選択します。

候補を選択すると、unite-haskellimportはdefaultのactionとして:Haskellimportコマンドを発行します。これは、対象を、ソースコードのそれらしい場所に挿入するものです。既に他のimport文がある場合は、最後のimportのあとに挿入します。

Before

import qualified Data.Text as T

f x = ...

After

import qualified Data.Text as T
import Test.QuickCheck ((==>))

f x = ...

今回importしたのは記号からなる関数でした。が、もしも記号ではない関数、つまりVimの<cword>になるようなものならば、:Uniteのかわりに

:UniteWithCursorWord haskellimport

とするとよいでしょう。これを頻繁に行うようならば、適切なキーにマッピングしておくべきです。たとえば以下を ~/.vim/ftplugin/haskell.vimに記述すると、<space>Iと打鍵するだけでカーソル以下にある単語の関数をimportしてくれます。

nnoremap <buffer> <space>I :<C-u>UniteWithCursorWord haskellimport<Cr>
ujihisa

もどる
blog comments powered by Disqus