Unite-autojumpをつくった

Vim
Comments

この記事は Vim Advent Calendar 2013 46日目の記事になります. # 46日目とは

私事ですが,諸般の事情によりエディタを Sublime Text から Vim に変えました. Vim を使い始めて数ヶ月,そろそろプラグインでも作ってみたいなーと思っていたところ,昨年の12月に Vim プラグイン読書会なるものが Lingr の Vim 部屋にて行われました.

参考: Vimプラグイン読書会を行いました – C++でゲームプログラミング

これは!と思って参加したのですが,そういえば普段お世話になっている unite.vim の拡張方法とか理解してないよなーってなりました. そこで勉強がてら Vim から unite.vim のインターフェースを通して autojump を使う的な簡単プラグインを作ってみました.

zoncoen/unite-autojump – Github

autojump は,cdで移動したディレクトリを記録して,カレントディレクトリに関係なく過去に移動したディレクトリに移動できるコマンドです. 導入などは以下参照.

ライフチェンジングなpercolとautojumpの紹介 – 404 Engineer Logs

今回は普段 Terminal 上で使い倒してるautojumpを Vim から使えるようにしてみました.

導入

NeoBundle で簡単にインストール.

1
NeoBundle 'zoncoen/unite-autojump'

当然ですが unite.vim と autojump が必要です.

使い方

Vim 上で以下のコマンドを実行すると,unite.vim のインターフェースで autojump ライクな機能が使えます.

1
:Unite autojump

.vimrcに以下のように書いておけば,:jで呼び出せて便利(かもしれない).

1
nnoremap :j :<C-u>Unite autojump<CR>

簡単な解説

unite source と unite action を追加する簡単なプラグインです. autojump は過去に移動したディレクトリ履歴と各ディレクトリの重みがautojump --statで取得できるので,その結果を unite.vim に渡しています.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let s:autojump_command = 'autojump -s'

let s:unite_source = {
\     'name': 'autojump',
\     'description': 'candidates from autojump database',
\     'default_action' : 'cd_autojump',
\ }

function! s:unite_source.gather_candidates(args, context)
    let l:directories = reverse(split(unite#util#system(s:autojump_command),"\n"))[7:]
    return map(directories,
    \         '{
    \             "word": split(v:val, "\t")[1],
    \             "source": "autojump",
    \             "kind": "cdable",
    \             "action__directory": split(v:val, "\t")[1],
    \         }')
endfunction

function! unite#sources#autojump#define()
    return exists('s:autojump_command') ? s:unite_source : []
endfunction

また,cdしたらその結果をautojump --addで autojump のデータベースに反映するcd_autojumpという unite action を定義しています.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let s:autojump_add_command = 'autojump -a %s'

let s:action = {
\     'description': 'change current working directory with adding path to autojump database',
\     'is_selectable': 0,
\ }

function! s:action.func(candidate)
    if a:candidate.action__directory != ''
        execute g:unite_kind_cdable_cd_command a:candidate.action__directory
        echo a:candidate.action__directory
        call unite#util#system(printf('autojump -a %s', a:candidate.action__directory))
    endif
endfunction

call unite#custom#action('cdable', 'cd_autojump', s:action)

TODO

Terminal上でのcdコマンドのように,Vim 上での:cdでも移動先のパスを autojump のデータベースに反映できたらなぁと思ってます. :cdにhookして処理を行うことができればよさそう( autocmd のオレオレ event を作る?). Vim 力高い方アドバイスお願いします :–)

まとめ

初 Vim プラグイン作成でしたが,autojump に便利オプションがあったため割と簡単にできてしまいました. unite source や unite action の作り方は,unite.vim の:helpや ujihisa さんの unite-locate を参考にさせていただきました.

あと余談ですが,vim script のテストに関して現時点でのベストプラクティスとかはあるんでしょうか? テストフレームワークがたくさんあって悩ましい…

このエントリーをはてなブックマークに追加

Comments

Gmail ライクにメールを検索する Alfred Workflow をつくった ライフチェンジングなpercolとautojumpの紹介