Peggyで単語補完スクリプトがC++に対応しました
つい二週間くらい前に更新したばかりなのですが、Peggyの単語補完スクリプトをまたまた更新しました。今回の修正は、長年の懸案であった、C++のクラスメンバ補完への対応です。
二週間前には「C++の文法は難しすぎるんですよねえ」と言っていたのに、なぜできるようになったのかと言いますと、結局のところ仕様を妥協したからです。実際、メンバをTAGSから拾うだけならCの構造体補完とさほど変わりないんです。
private等の可視性をきちんと反映するのは難しいなあ…と思っていたのが、実際に作ってみたら、別に反映しなくても十分使えるじゃないか、と気付いたのが最大の進展でした。
今回対応した補完の仕方は三種類あります。まず、従来の構造体メンバ補完と同様に、
SomeClass instance;として補完を行うと、SomeClassクラスのメンバとメソッドがリストとして表示されます。リストに含まれるのは、クラス内で定義されている定数や、メンバ変数、メソッド等です。本来はprivateなメンバ変数が出てきたりしたらおかしいのですが、このスクリプトでは全部出てきてしまいます。「出てこないよりは出過ぎた方がいい」という方向で作成しているためです。
instance->|
(|はカーソルです)
次に、
SomeClass::|となっているときに補完を行った場合、SomeClassを型名と見なして候補を表示します。この時は、クラス内で定義されているenumやスタティックな変数のみが出てくるべきなのですが、残念ながら出てくるリストは一つ目の例と同じです。
最後の例は、
SomeFunction()->|のように、関数の返値から直接メンバを参照している場合です。このようなときは、SomeFunction関数の返値の型を探し、その型のメンバをリストアップします。
このように、VisualStudioのインテリセンスと比較すると、全く不完全な機能です。ただ、使えないというわけでもないレベルに来たと思ったので、公開させていただきました。
他に問題だと思っている点は以下の通りです。
・マクロやtypedefが絡むとうまく動作しない。これはやればできると思うのですが、自分があまり必要性を感じていないので対応していません(^^;
・namespaceに対応していない。本当は
Namespace::|みたいな場合にも対応したかったのですが、namespaceの情報をTAGSから取得するのは不可能に近いのです…。
・コーディングスタイルによってはうまく動作しない。例えばTAGSの解析をインデントに頼っていますので、クラスのメンバ定義をインデントしていなかったりすると、うまく補完候補を取得できません。また、返値を関数の定義と別の行に書いている場合は関数の返値を取得できない、継承しているクラスをクラスの宣言と別の行に書いている場合は継承先をうまく取得できない、等があります。
・動作が遅くなることがある。特にクラスの継承関係が深くて、その上多重継承が絡んだりすると、何回も検索を繰り返すのでどんどん遅くなります。
・名前の重複に弱い。例えばNamespace1::SomeClassとNamespace2::SomeClassがある場合、どちらのSomeClassのメンバを補完した場合も、名前空間関係なしに最初に見付けた方のメンバをリストアップしてしまいます。
こうして見ると欠点だらけですね…。頑張れば対応できるものもあるのですが、現在の、Peggyが作成したTAGSを解析する方法では、これらに対応することは難しそうです。ただ、現在の方法はPeggy本体と協調しやすいので、単純に構文解析の方法を変えても使い勝手の向上に繋がらないかなあと思ってます。
このスクリプトを作りだしたのは二年半くらい前で、そのころからC++のクラスに対応したいなあと思っていたので、不完全ではありますが対応できたのは嬉しいです。
昔は無理だと思っていたのですが、やっぱりモチベーションの違いでしょうね。昔と違って今の仕事はC++が中心なので、なんとかしなくちゃと気持ちが大きくなったんだと思います。
そもそも昔はC++のことが全然わかってなかったというのもあるのですが(^^;
| 固定リンク
「パソコン・インターネット」カテゴリの記事
- 初音ミクの曲(動画)個人的な十選(2009.02.15)
- 2008年ニコニコ動画個人的ベスト10(2008.12.06)
- menucomplete.msのクラスメンバ補完を強化する(2008.07.21)
- ctagsをWin32環境でビルドする(2008.07.21)
- EeePC901の初期設定(2008.07.21)
この記事へのコメントは終了しました。
コメント