LoginSignup
0
0

More than 3 years have passed since last update.

Deniteでctags検索のSourceを作ってみる

Last updated at Posted at 2020-10-07

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があれば動きそうなのがわかりました。

ここで簡単に動きを検証してみました。

test.py
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__pathaction__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を初めて作りましたが、簡単に作れることがわかりました。
ドキュメントや既存ソースがわかりやすかったので、それを参考に作ると良いと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0