5

ご存知の方もいらっしゃると思いますが、私は自分のIDEを開発しています。あなたは「ああ、もう一つ?!」と思うかもしれません。-心配しないでください。誰もあなたにそれを使用するように強制することはありません。とにかく真剣に公開されるとは思えません。

それでは、メインの問題に進みます。オートコンプリートシステムを実装しようとしています。正確なUIは問題ではありません。ただし、言語/ライブラリトークンを柔軟に保存することが私の主な問題です。

CSSセレクターまたは属性をユーザーに提案しているとしましょう。次のようなものがあります。

- css/core
  - a                      // anchor tag
  - etc                    // all valid html tags
  - .stuff                 // class name parsed from user project
  - ?etc                   // more stuff parsed from user project (ids, classes...)
- css/properties
  - border                 // regular css properties - we also need to associate
                           // <border-style> and <color> value tokens
  - etc                    // the rest of them
- css/values/border-style  // property value tokens
  - solid
  - dotted
- css/values/color
  - red
  - green
  - fucshia

したがって、各トークンは名前空間を取得するため、トークン間を追跡できます。BNFと同様に、一部のトークン値は、境界線や色の場合などのサブトークンで構成されています。

1.エキゾチックな構文の言語に関連する可能性のあるものをすべて保存する必要があることを忘れないでください。2.また、上記の情報を、プロジェクトのファイルから収集されたクラス名のリストなど、コンテキストに依存する情報と何らかの方法でマージする必要があることに注意することが重要です。これは、重複トークンなどを発生させることなく、高速かつ効率的である必要があります。

したがって、結論として、ここでのことは非常に複雑であり、一般的で柔軟なソリューションを取得する方法を正直に考えることはできません。IDEはあらゆる種類の言語に対応する必要があるため、これはさらに複雑になることに注意してください。

この質問が、たとえばプログラマーに適しているかどうかはわかりません。そのため、modに任せて決定します。

4

4 に答える 4

8

私はSharpDevelopと呼ばれるIDEに取り組みました。ストレージの質問に入る前に、より一般的な議論から始めましょう。

一般的な方法でオートコンプリートを適切に解決できるとは思いません。ほとんどのIDEは、言語ごとにプラグインを用意することでさまざまな言語をサポートしており、ドキュメント内のカーソルの現在の位置に基づいて完了リストがどのように表示されるかを判断するのはプラグイン次第です。

IDEは、プラグインが実装する単純なインターフェースのみを提供します。たとえば、オートコンプリートを示すIDEのコードは次のようになります。

getAutocompletionList(editor) {
  plugin = editor.languagePlugin;
  plugin.getAutocompletionList(editor.cursorPosition, editor.parsedDocument);
}

ACSSLanguagePluginPHPLanguagePluginは、完全に別個の実装にgetAutocompletionListなります。1つはCSSの編集時に使用され、もう1つはPHPの編集時に使用されます。

他の人が指摘したように、カーソルの周りのコンテキストは重要です。たとえば、次のCSSを編集する場合:

h1 {
    text-align: <cursor>

コンテキストは次のようになります。

[cssTopLevelContext] {
    [cssPropertyContext]: [cssPropertyValueContext]
}

CSSプラグインの実装は、次のようになります。

// CSSLanguageBinding
getAutocompletionList(cursorPosition, document) {
    completionContext = this.getCompletionContext(cursorPosition, document);
    // completionContext is { 
    //     'name': 'cssPropertyValueContext', 
    //     'propertyName': 'text-align' 
    // }
    return this.completionDatabase.getCompletionList(completionContext);
    // returns ['left', 'center', 'right'];
}

今、私たちはあなたの質問に行きます-完了データベース。繰り返しになりますが、言語プラグインごとに異なる実装になる可能性があります(おそらくそうすべきです)。PHPでは、クラス、メソッド、変数を操作し、可視性(プライベート、パブリック、保護)に注意する必要があります。CSSでは、タグ、クラス、およびプロパティを操作します。

正しく指摘したように、完了データベースは次のもので構成されている必要があります。

  • 共通トークン
  • 現在のプロジェクトによってインポートされたトークン
  • 現在のプロジェクト自体のトークン

SharpDevelopでは、どのプロジェクトも標準ライブラリをインポートするため、「共通トークン」の部分はありません。したがって、プロジェクトを開くときに、インポートされたすべてのライブラリを分析するだけで十分です。

PHPでも同じことができ、すでに見たライブラリのトークンデータベースをキャッシュできます。

次に、ストレージ形式について説明します。PHPでオートコンプリートを提供するには、現在のクラス、その基本クラスとインターフェイス階層、すべての基本クラスとインターフェイスのメソッドとその可視性、現在のコンテキストで表示される変数とそのタイプ(PHPでは常に可能とは限りません)を知る必要があります。すぐ。

このため、リレーショナルデータベースは適切な選択ではないと思います。すべてのクラス、インターフェイス、メソッドをそこに保存し、継承階層をナビゲートするにはどうすればよいですか?SharpDevelopは、これらすべてをオブジェクトモデルとしてメモリに格納します(クラスには、基本タイプ、インターフェイスのリスト、メンバーのリストなどがあります)。8000アイテムはそれほど多くはありません。また、8000アイテムをリレーショナルデータベースに格納した場合、データベースエンジンがすべてをRAMに保持するほど小さくなります。

SharpDevelopはすべての完了情報をメモリに保持し、SharpDevelopで700Kラインプロジェクトを開いた場合でも、メモリ消費量はかなり低くなります。プロジェクトを開いたときにオートコンプリートデータ構造を初期化し、それらをメモリに保持することをお勧めします。他の人が言ったように、ユーザーが入力しているときにバックグラウンドでそれらを更新する必要があります(新しいメソッドの導入、フィールドの名前変更など)。

PHPについては以上です。CSSの場合、質問で概説したものと同様のデータ構造は非常に合理的と思われます。これは、IDEの起動時/プロジェクトの起動時/最初のCSSファイルの起動時に構造化ファイルからメモリにロードできます。


最後に、CSSに適切なオートコンプリートを実装することはそれほど難しいことではありません。PHPの場合、それははるかに困難であり、単純なものから始めることができます。標準ライブラリから8000トークンを提供し、さらにユーザーがプロジェクトのどこかで入力した単語を提供します。このようなアプローチは、Sublime Textのような編集者によって使用されており、驚くほどうまく機能します。

于 2012-06-16T20:41:47.493 に答える
3

さまざまな人々からの慎重な考えとアドバイスの後、データベースはオートコンプリート情報を格納するための唯一の論理的なソリューションです。

この演習では、コード/仕様を解析してオートコンプリートコードを生成するスクリプトをいくつか作成しました。

ここで、たとえば、PHPには少なくとも8000を超える関数(=>オートコンプリートアイテム)があることに気づきました。

そのため、この情報をPHPファイル内に保存し、IDEの起動時にロードするのは悪いことです。代わりに、データベースにこの情報が保存されます。

プロジェクト固有の自動完了は、個別のDBテーブルに保存されるため、メインのドキュメントテーブルの目詰まりを防ぐことができます。

于 2012-06-13T14:54:23.830 に答える
1

一般的に言って、難しいのは、提供するトークンを収集し、それらを適切なタイピングコンテキストに一致させることです。(部分的に入力された行のどの文字をwhatでアクティブ化するかを入力することと、言語型システムのように入力することの両方。)比較すると、オプションのリストの表現とクエリは簡単で、それほど重要ではありません。素朴なアプローチはかなり問題ありません。

既存のIDEが行うことの1つは、定期的にコードを取得し、コンパイラの特別なバージョンまたはモードを使用してバックグラウンドスレッドでコンパイルし、プログラムに存在する関数/変数などのリストを生成することです。このリストは、「タグファイル」、「情報の閲覧」、「プログラムデータベース」のいずれかとも呼ばれます。プロジェクト内のすべての関数の名前、パス、タイプ、および場合によっては自動抽出されたドキュメントも保存されます。また、パフォーマンスのために、段階的に機能する必要があります。つまり、少なくとも個々のファイルの粒度で、変更されていないものを再コンパイルしないようにする必要があります。また、部分的に型指定されたコードで動作するため、実際のコンパイラよりもエラーに対する耐性が高い必要があります。

次に、入力しているときに、コンパイラはオートコンプリートが表示されるコンテキストを認識します。「。」を入力した後です。関数の場合、CSS属性名の一部を入力した場合など。これらは、部分的に入力されたコードのパターンマッチングに依存します。これらに統一の原則はありません。これは、言語ごとに異なる特殊なケースの集まりにすぎません。たとえば、「case SomeEnum.Foo:」にスペースを入力すると、一部のIDEは、囲んでいるswitchステートメントを検索し、そのタイプを推測し、その列挙型の定義を検索し、その値をオプションとして提供します。

これらすべての実際的な結果は、オートコンプリートが提供できるものの優れた均一な表現を得ることができないということです。代わりに、言語固有のコンテキスト識別ハック、さまざまなコンテキストのリスト、および解析によって抽出されたより多くのリストが混在しています。多くのコンテキストは、いくつかのリストを一緒にマージします。たとえば、CSSセレクターには任意のHTMLタグ名、または抽出クラス名/ IDを含めることができ、HTMLを入力するときにHTMLタグ名リストも使用されます。

于 2012-06-16T02:55:39.590 に答える
1

私の昔の仕事では、私たちはひどいウェブサイトで工業製品を販売していました(私はエンジニアなので、このひどいことは私のせいではなかったと誓います)。ある日、上層部は私たちのすべての製品に「おすすめ商品」ボックスが欲しいと決めました。

これに対する常識的なアプローチは、各製品と他のすべての製品との間に本当にクールで興味深い関係を構築し、実際に関連した製品に関する関連する最新の情報を顧客に提供することです。残念ながら、私の職場では、構築済みのWebサイトでそれを実行する方法を誰も知りませんでした。

代わりに、5つの製品IDの配列を各製品に添付しました。これらの製品IDは、経験豊富なセールスマンと常識による推奨に基づいてハードコーディングされており、派手なアルゴリズムはありません。

この話の教訓は、IDEのエンドユーザーには約10の推奨事項しか表示されないという事実に焦点を当てたいと思うかもしれないということです。したがって、「かなり良い」につながるいくつかのルールを考えるべきかもしれません。潜在的な変数のトップ10リスト:いくつかの基本的な文法規則を取り、コード内の近接性、各変数の頻度などに基づいて予測します。次に、これをベッドに置いて、IDEのより重要な部分に集中することができます。

于 2012-06-15T21:16:17.353 に答える