Deniteに移行した時点から、ctags検索に不満があり
https://qiita.com/hisawa/items/3498951e84eac77ac890
fzfなどを使ってみましたが、nvimに移行してからctags検索だけfloatingではないのが気になってました。
https://qiita.com/hisawa/items/fc5300a526cb926aef08
探してもDeniteでctagsを検索する方法がみつからなかったので
Deniteのsourceを自作して、ctags検索ができるようにしました。
https://github.com/hsawaji/denite-ctags
DeniteのSourceを初めて作ったので、メモを残しておきます。
準備
まずはDeniteのhelpをみます。
:help denite-create-source
rplugin/python3/denite/source/*/.py.
にファイルを置くと、Sourceとして読み込まれると書いてあります。
すでに実装されている他のSourceを参考に、最低限__init__
とgather_candidates
があれば動きそうなのがわかりました。
ここで簡単に動きを検証してみました。
from .base import Base
from denite import util
class Source(Base):
def __init__(self, vim: util.Nvim) -> None:
super().__init__(vim)
self.name = 'test'
self.kind = 'file'
def gather_candidates(self, context: util.UserContext) -> util.Candidates:
return [
{'word' : 'hoge'},
{'word' : 'fuga'}
]
:Denite test
=> hoge
fuga
gather_candidates
で返した配列が表示されるようになりました。
これで、後はctagsの候補を返してやれば完了するはず。。
ctagsの候補を表示する
vimにはtaglist
というタグの検索結果を返してくれるやつがあるのでそれを使います。
:help taglist
既存のtag.pyをみると
-
__init__
でvim
をインスタンス変数に入れる -
self.vim.call('command', '引数')
で呼び出す
とすれば行けそうです。
今回はtaglist
なので
self.vim.call('taglist', 'word')
を追加しました。
ここまでで、こんなソースになります。
from .base import Base
from denite import util
class Source(Base):
def __init__(self, vim: util.Nvim) -> None:
super().__init__(vim)
self.name = 'test'
self.kind = 'file'
self.vim = vim
def gather_candidates(self, context: util.UserContext) -> util.Candidates:
taglist = self.vim.call('taglist', context['args'][0])
return [ {'word' : t['cmd']} for t in taglist]
下記のようにしてhogehoge
を検索します。
:Denite test:hogehoge
候補先に飛ぶ
Deniteのhelpを見ると
:help denite-kind-file
action__path
とaction__pattern
があれば目的地に飛べる感じがします。
それらを追加したソースがこちら。
taglist['cmd']
には正規表現のように/^
と$/
が入っていたのでre.sub
で削除しています。
import re
from .base import Base
from denite import util
class Source(Base):
def __init__(self, vim: util.Nvim) -> None:
super().__init__(vim)
self.name = 'test'
self.kind = 'file'
self.vim = vim
def gather_candidates(self, context: util.UserContext) -> util.Candidates:
taglist = self.vim.call('taglist', context['args'][0])
return [ {
'word' : t['cmd'],
'action__path' : t['filename'],
'action__pattern' : re.sub('\/\^|\$\/', '', t['cmd'])
} for t in taglist]
ここまでほとんど完成です。
以上のソースの見た目などを調整したものがdenite-ctagsになります。
まとめ
Deniteのsourceを初めて作りましたが、簡単に作れることがわかりました。
ドキュメントや既存ソースがわかりやすかったので、それを参考に作ると良いと思います。