Vim で snippet, template を設定する

はじめに

ぼくが手伝っているプログラミング初心者&Perl入門者向け無料勉強会「Perl入学式」のハッシュタグをたどっていたら、こんな投稿がありました。

これに対して、以下のような回答がありました。

なるほど〜……。ただこちら、内容自体は有用な知見であることに違いないとしても、何となく質問した人の意図としては、もう少し「快適に」という部分が関心の対象なのかなという気もします。上記の回答はそれより「実用的に役立つ設定」という要素にフォーカスが当たっているのかな、と。
あと、「雛形化」のもうちょっと詳しいところも知りたいですね。

それとは別に、こんな回答もありました。

そう、それそれ! と思わず言いたくなるような(笑)個人的にはこちらの回答がヒットしました。この後にどんなやり取りがあったかはわかりませんが(無かったかもしれませんが)、質問者のニーズにも合致している気がします。

……などと偉そうなことを書きましたが、じゃあぼくだったらどう応えるかな、と考えてみた結果が今回の記事です。

参考になりそうなブログ記事

普通なら、参考にした記事へのリンクなどは最後に貼ると思うのですが、この後けっこう偏ったことを書きそうなので、先に正解と言えそうな以下をご紹介しておきます。

いずれもちょっと前の記事なので、現在そのまま使えるかはわかりませんが、参考になる部分は多々あるものと思います。

一方、この先の記事はあくまでぼく個人の勉強過程で得た気づきをメモしたものに過ぎず、正解のマニュアルなどではありませんから、「ああ、こういう解決を試みたやつもいるのだな」ぐらいに思って頂いて、正しく・応用が効く・安全性の高い情報については各公式情報をご参照ください。(免責事項ここまで)

snippet とは

さて、一瞬時間を遡りますが、昨年末に催された「IT Advent Calendar」ではぼくも初めて、Perl入学式のそれに参加しました。

そして、その時に並行して進んでいたPerl編のカレンダーの中で、Perl入学式校長のpapixさんが以下の記事を書かれたのですが、

この最後の方で出てきた以下の内容、

自分の場合, VimPerlスニペットファイルに次のような設定を入れています.

snippet dd
    use DDP { deparse => 1 };

snippet dw
    use DDP { deparse => 1 };
    p 

Data::Printerでデバッグしたいと思った時は, このスニペットからData::Printer用のコードを展開して使っています.

これに引っかかりました。
ス、スニペット? is... なに……?

まあ、よくはわからないけれど、とにかく便利であることには違いないはず……という直感をもとにいろいろ検索してみたところ、以下のような記事が見つかりました。

これらの記事にしても、最初のpublishからそれなりに時間が経っている都合上、今ではコピペしてすぐ動くというものではなく、結構あれこれと再解釈なり手を加えたりしなければならないのですが、ともあれ調べながらわかったのは、

  • snippet とは
    • いちいち毎回手で書くのが面倒な、よく使う「おまじない」的なものは、スニペットファイルというものに設定しておいて、そこからショートカットで呼び出すことができる
    • そのために、専用のプラグインを使う

というようなことでした。

上記のpapixさんの記事内の例で言うと、スニペットファイルなるものに以下のように書いておくと、

snippet dd
    use DDP { deparse => 1 };

「dd」と打鍵して、その後に任意の呼び出しキー(Controlキーを押しながらk、など)を押すと、対象のファイルに

use DDP { deparse => 1 };

が挿入される、ということです。(「呼び出しキー」の設定については後述)

snippetの設定

肝心の設定方法ですが、暗黒美夢王様こと @Shougo さんによる以下のプラグインを使います。
Shougo/neosnippet.vim · GitHub

具体的には、.vimrcに以下のような記述をします。

※免責事項(再): 以下はある程度の汎用性を意識してはいますが、環境によって過不足やズレがあると思いますので、最終的には上記リンク先(@Shougoさんのリポジトリ)を参照してください。

NeoBundle 'Shougo/neocomplete'
NeoBundle 'Shougo/neosnippet'
NeoBundle 'Shougo/neosnippet-snippets'

imap <C-k>     <Plug>(neosnippet_expand_or_jump)
smap <C-k>     <Plug>(neosnippet_expand_or_jump)
xmap <C-k>     <Plug>(neosnippet_expand_target)

imap <expr><TAB> neosnippet#expandable_or_jumpable() ?
\ "\<Plug>(neosnippet_expand_or_jump)"
\: pumvisible() ? "\<C-n>" : "\<TAB>"
smap <expr><TAB> neosnippet#expandable_or_jumpable() ?
\ "\<Plug>(neosnippet_expand_or_jump)"
\: "\<TAB>"

if has('conceal')
  set conceallevel=2 concealcursor=i
endif

ここまで入れたら、.vimrcを開き直して、これ。

:NeoBundleInstall

すると、 .vim/bundle/neosnippet-snippets/neosnippets の中にある perl.snip というファイル(これがスニペットファイル)に書かれた設定に従って、任意のコードの集合体を呼び出せる、という寸法です。

この時、上記設定内の「< C-k >」というのが、前述の「呼び出しキー」にあたります。ぼくは「< C-k >」は別の設定で使っているので、「< C-j >」にしています。

また、このスニペットファイルはデフォルトで提供されている「neosnippet-snippets」内のものですが、別のファイル(群)を使うこともできます。これについては以下に説明があります。
Shougo/neosnippet.vim · GitHub

とはいえ、ぼくの場合はさほどのこだわりもない(というかカスタマイズするほどの知識もない)ので、このデフォルトファイルにそのまま自分用のスニペットを追加したりしています。

そしてこの際、手を入れるたびに毎回、上記の階層までファイルを開きに行くのは大変なので、vimrcに以下のように書いて、

nnoremap <Space><Space>pl :sp $HOME/.vim/bundle/neosnippet-snippets/neosnippets/perl.snip<CR>

ノーマルモードで< Space >2回と「pl」を続けて押した時、ウィンドウの下半分にスニペットファイルが出てくるようにしています。

f:id:note103:20150311233140p:plain

ということで、Perlに限った手法ではありませんが、最初の質問にあった「快適さ」の追求には多少見合った何かであるかもしれません。


templateとは

すでにけっこう長くなりましたが、似たような話なのでこちらも書いておきます。

これは冒頭の回答にあった「テンプレートでuse strict等お約束系の記述を雛形化する」という方法の一つかなと思いますが、まず.vimディレクトリの中に、templateというディレクトリを作成し、その中にたとえば perl-script.txt というファイルを作って、以下のように記述しておきます。

#!/usr/bin/env perl
use strict;
use warnings;

「おまじない」とも「お約束」とも言われるPerlの頭の3行ですね。
これは毎回必ず書きますから(とくに下のプラグマ2行)、毎回手で書いていると人生の時間も体力もそれなりに奪われていきます。

ということで、.vimrcに以下のように入れておきます。

autocmd BufNewFile *.pl 0r $HOME/.vim/template/perl-script.txt

すると、拡張子が.plのファイルを開いた時、最初から上記の3行が入っている、という便利な状況が生まれます。
魅惑の自動化、効率化を一つ果たしました。

この辺りの方法については、冒頭で示したtokuhiromさんの記事で詳細&バリエーション豊かに解説されているので、リンクを再掲します。
その他のPerlVimなお役立ち情報も数多く載っていますので、ぜひどうぞ。

ちなみに、これも前記のsnippetの応用で、templateファイルに手軽にアクセスできるよう、ぼくのvimrcでは以下のような記述も併記していますが、

nnoremap <Space><Space><Space>pl :sp $HOME/.vim/template/perl-script.txt<CR>

さすがにあまり良い方法ではない気もします。
でも、現状自分には役立っているので、もう少しスマートな方法が見つかるまでは使うでしょう。

次回予告

冒頭の引用ツイートで、

ファイルの構文エラーチェックとしてscrooloose/syntasric、コードの即時実行としてthinca/vim-quickrunを利用しています。

という話がありました。

一緒に紹介されている「thinca/vim-quickrun」については、以前にも何度か紹介しましたが、

「scrooloose/syntasric」というのは、聞いたことはあったものの試したことはなかったので、軽い気持ちでこの記事を書く前に手を出したのでしたが、めちゃくちゃハマりまして(笑)何とかその後、1〜2時間格闘して使えるようにはなったので、今度時間ができたらそれについても備忘録がてらご紹介したいと思っています。

以上です!