やりたいこと
Sencha Touchプロジェクトでvimのタグジャンプを利用した際、関数などに飛んでくれて便利。
でも、当然Sencha Touchの定義には飛んでくれない。
なのでもちろん自作のクラス定義に飛ばないのも辛いが、
Sencha Touchのソースを見ることが多いのでこれはなんとかしたい。
- Sencha Touch のclass定義にもタグジャンプしてほしい
- ライブラリのtagsは同じなので共有したい
- 自分のアプリのtagsは個別に管理したい
- Sencha Touchの定義へ飛ぶ場合は各ワークスペース内の定義へ飛びたい
最終的には以下のような構成になる予定。
~
├─.vim
│ └─tags
│ └─touch.tags ← Sencha Touch のtags(共有)
│
├─Workspace
│ ├─MyApp1 ← 自分のアプリケーション
│ │ ├─app
│ │ ├─resources
│ │ └─.tags ← MyApp1のtags
│ └─touch ← Sencha Touch ライブラリ
│
└─Workspace2
├─MyApp2 ← 自分のアプリケーション
│ ├─app
│ ├─resources
│ └─.tags ← MyApp2のtags
└─touch ← Sencha Touch ライブラリ
Sencha Touch に対応したtagsの作成
tagsファイルの作成にはctags(Exuberant Ctags)を用いたが、.ctags
設定ファイルにより生成されるタグをカスタマイズできる。
とりあえずSencha Touchのクラス名とxtypeのタグを生成するようにしてみた。
実際には関数や変数の定義、storeId
なども記述している。
--recurse=yes
--langmap=JavaScript:.js
--regex-JavaScript=/Ext.define\(['"]([^"']+)/\1/c,classes/
--regex-JavaScript=/^\s{4}xtype: ?['"]([^"']+)/\1/c,classes/
xtypeの判定
xtype
は定義部分以外にも使用されるため、定義部分のみを判定する必要がある。
ただ、どうやら複数行の正規表現に対応して いないらしく、
結局xtype
の判定は空白の数(タブ1つ分の空白)で行った。悲しい…
ところがこんなふざけた書き方でも、今のところうまく判定できている。
Ext.define('Ext.Button',{extend:'Ext.Component',xtype:'button',
tagsの生成
.ctags
の設定を行ったうえで、SecchaTouchのtagsファイルを出力する。
cd ~/Workspace/MyApp1
ctags -f .tags --format=2 --language-force=javascript --tag-relative=no --exclude=resources .
ctags -f sencha.tags --format=2 --language-force=javascript --tag-relative=yes ../touch/src
- 名称を
tags
ではなく.tags
にするしているのは好みの問題(非表示扱いになって便利) - excludeにワイルドカードは使用できない(後述)
-R
オプションは.ctags
にrecurse
を定義しているので不要sencha.tags
に--tag-relative=yes
を指定して相対参照にしている点がポイント
実際にはtouch.tags
の中で、明らかに不要そうな定義は適当に削除して使用している。
vimからtagsの参照設定
" tags定義settags+=.tagssettags+=~/.vim/tags/touch.tagssetnotagrelative
notagrelative
によりカレントディレクトリからの相対パスとみなされる.ctags
を追加- Sencha Touch の定義
touch.ctags
を追加
Senchaプロジェクトの判定
上記設定の問題点として
- すべての場合に上記設定が適用されてしまう
- カレントディレクトリをSencha Touchのワークスペースにする必要がある
これには.sencha
フォルダの有無を判定することで、
Sencah Touchプロジェクトを判定し、同時にルートディレクトリを設定することができる。
詳細は省くが、よくある.git
フォルダを判定するロジックをまねれば良い。
vimからtagsを生成できるようにする
" 半自動生成function! CreateTags()
execute ':silent !find '.getcwd().' -name ''*.js''|grep -v ''/\.''|ctags -L - -f .tags --format=2 --language-force='.&filetype.' --tag-relative=yes'endfunctionnnoremap<Space>tags :call CreateTags()<CR>
find
とgrep
を組み合わせれば有効なJavascriptファイルのみを対象にできる
実際にはvimからの生成は、有志による便利なプラグインを使えば良いと思う。
【おまけ】tagbarで表示
少なくとも.ctags
で定義したc
を定義してやればクラス定義が見えました。
letg:tagbar_type_javascript = {
\ 'ctagstype' : 'javascript',
\ 'kinds' : [
\ 'c:classes:0:1',
\ 'o:object:0:0',
\ 'f:functions:0:1',
\ 'm:methods:0:1',
\ 'p:properties:0:0',
\ 'v:global variables:0:0',
\ 'r:variables:0:0',
\ ],
\ }
まとめ
私の場合、アプリ内で飛ぶことよりSencha Touchソースへ飛ぶことが多いためか、
Senchat Touchの設定だけでも十分便利になりました。