Peggyスクリプト二つ登録しました
アンカーシステムズさんのスクリプトライブラリに、「menuComplete」と「doxygenTool」を登録しました。
doxygenToolの方は結構前からできていたのですが、menuCompleteの方にDoxygenのコマンドを補完する機能があって、これがないとちょっと使いにくいので、一緒に公開できるようになるまで待っていた次第です。
menuCompleteは、単語補完スクリプトなのですが、前々からずっとできないかなあと思っていた「構造体のメンバ名を補完する」機能がやっと実現できました。
人にPeggyを薦めるときに、「でもVisualStudioみたいに補完できないんでしょ?」と言われることがあって、何とかして部分的にでもできないものかと思っていたのです。(自分でも欲しかったんですけどね。)
今のところC/C++の構造体のメンバしか補完できないのですが、できればC++のクラスのメンバも補完できるようにしたいですね。継承とかの問題があって、現実的な速度を実現するのがかなり難しそうですが…。
以下に構造体メンバ補完とプログラムの仕様に関する考察(というか言い訳)をメモしておきます。
◇TAGSについて
このスクリプトでは、シンボル検索の際に生成されるTAGSファイルを利用しています。よって、「定義位置ブラウザ」ダイアログで「TAGSファイルを残す」設定をしておく必要があります。
スクリプトで構文解析をするのには限度があるので、どうしてもTAGSファイルを利用する必要があるのです。
「TAGSファイルを残す」設定なんて使うことないだろうと思っていたのですが、まさかこんな用途に使えるとは…。Junさんはこういうのを予測してたんでしょうか?
◇MocaScriptについて
このスクリプトはかなり重い処理をしてます。なにせ、とてつもなく膨大になりうるTAGSアウトプットウィンドウから、一つずつ候補を探してくるわけですから…。(ちなみに、動作のテストはrubyのソースでやってました。)
それでも現実的な速度で動くMocaScriptは本当にスゴイです。おそらく世界最速のJavaScriptの実装でしょう(^^
◇補完の仕方について
構造体メンバの補完には、大きく分けて3つのステップがあります。
・変数名を取得する
変数名は、普通 . か -> の左にあります…が、キャストしていたりすると取得するのが難しくなります。現状は、変数が配列だったときに配慮しているくらいです。
キャストに関しては型名が書いてあるわけだから、逆になんとかなるかもしれないですね。
・型名を取得する
型名を取得するには、変数の宣言を見つける必要があります。変数の宣言は、
(1)ローカルで宣言されているとき
(2)関数の引数になっているとき
(3)グローバル変数のとき
の3つが考えられます。このスクリプトではあまり真面目に構文解析をしているわけではなくて、補完する位置から一行ずつ順番に見ていって、「宣言っぽい」ところを見つけた時点でそれを型名であると判断します。ただ、
return variable_name;
や
else variable_name = 0
みたいになっていることがあるので、これらのキーワードは型名ではないと判断します。っていうか、Cのキーワードリストを持っておいた方がいいのかもしれないですね。
(3)の場合は他のファイルにあるかもしれないので、TAGSファイルをgrepして探します。どちらかというとこっちの方が単純です。
プロジェクトに登録してある静的なTAGSは検索していないのですが、これはどちらかというと、実行速度のためです。
・型のメンバを取得する
最後はメンバ名の取得なのですが、これは完全にTAGSファイルに頼っています。構造体の型名を、前後64行も一緒に出力するオプションでgrepして、その中からメンバ名を探します。メンバ名であるかの判断は、インデントに頼っています。
これによって、取得できるメンバ名が64個までという制限が出てしまっているのですが。
こちらの方は、プロジェクトに登録してある静的なTAGSからも検索します。
プロジェクトに多数TAGSが登録してある場合は、探すのにかなり時間がかかってしまいます。
◇Rubyの場合
Rubyの場合、シンボル名が、最初に@や$があったり、最後に!や?があったりと特殊なので、特別な処理をしています。そのせいで正規表現にORを使う必要があって、実行速度が他より若干遅いんですけどね。
◇Doxygenのコマンド名補完
Ruby以外では、@から始まる語はDoxygenのキーワードと見なして補完します。これは静的なリストを使って行っています。
◇カーソルの右にも語が続いている場合について
hoge|moge
のように、カーソルの右側にも語が続いている場合は、それを削除して(この場合はmogeを削除して)選んだ語を入れます。例えば「hogepiyo」という語を選んだ場合は、
hogepiyo|
となります。この辺りの動作はVisualStudioにできるだけ似せています。
追記…Javaでもほとんど似たような方法で、クラスのメンバ補完ができるんじゃないかという気がしてきました。(言語機能がシンプルなぶん、C++より簡単そうです。)こっちを先にやってみようかな。Javaについては、もう補完スクリプトを作られている方がいるんですけどね…。
| 固定リンク
「パソコン・インターネット」カテゴリの記事
- 初音ミクの曲(動画)個人的な十選(2009.02.15)
- 2008年ニコニコ動画個人的ベスト10(2008.12.06)
- menucomplete.msのクラスメンバ補完を強化する(2008.07.21)
- ctagsをWin32環境でビルドする(2008.07.21)
- EeePC901の初期設定(2008.07.21)
この記事へのコメントは終了しました。
コメント