Ver código fonte

Add fetcher for completion items instead of attaching items to IReply

Edward Zhao 5 anos atrás
pai
commit
c377a32908
2 arquivos alterados com 107 adições e 25 exclusões
  1. 99 25
      packages/completer/src/handler.ts
  2. 8 0
      packages/completer/src/tokens.ts

+ 99 - 25
packages/completer/src/handler.ts

@@ -44,6 +44,7 @@ export class CompletionHandler implements IDisposable {
     this.completer.selected.connect(this.onCompletionSelected, this);
     this.completer.visibilityChanged.connect(this.onVisibilityChanged, this);
     this._connector = options.connector;
+    this._fetchItems = options.fetchItems;
   }
 
   /**
@@ -354,6 +355,16 @@ export class CompletionHandler implements IDisposable {
     const state = this.getState(editor, position);
     const request: CompletionHandler.IRequest = { text, offset };
 
+    if (this._fetchItems) {
+      return this._fetchItems(request)
+        .then(reply => {
+          this._onFetchItemsReply(state, reply);
+        })
+        .catch(_ => {
+          this._onFailure();
+        });
+    }
+
     return this._connector
       .fetch(request)
       .then(reply => {
@@ -372,44 +383,49 @@ export class CompletionHandler implements IDisposable {
 
         this._onReply(state, reply);
       })
-      .catch(reason => {
-        // Completion request failures or negative results fail silently.
-        const model = this.completer.model;
-
-        if (model) {
-          model.reset(true);
-        }
+      .catch(_ => {
+        this._onFailure();
       });
   }
 
   /**
-   * Receive a completion reply from the connector.
-   *
-   * @param state - The state of the editor when completion request was made.
-   *
-   * @param reply - The API response returned for a completion request.
+   * Updates model with text state and current cursor position.
    */
-  private _onReply(
+  private _updateModel(
     state: Completer.ITextState,
-    reply: CompletionHandler.IReply
-  ): void {
+    start: number,
+    end: number
+  ): Completer.IModel | null {
     const model = this.completer.model;
     const text = state.text;
 
     if (!model) {
-      return;
+      return null;
     }
 
     // Update the original request.
     model.original = state;
     // Update the cursor.
     model.cursor = {
-      start: Text.charIndexToJsIndex(reply.start, text),
-      end: Text.charIndexToJsIndex(reply.end, text)
+      start: Text.charIndexToJsIndex(start, text),
+      end: Text.charIndexToJsIndex(end, text)
     };
+    return model;
+  }
 
-    if (reply.items && model.setCompletionItems) {
-      model.setCompletionItems(reply.items);
+  /**
+   * Receive a completion reply from the connector.
+   *
+   * @param state - The state of the editor when completion request was made.
+   *
+   * @param reply - The API response returned for a completion request.
+   */
+  private _onReply(
+    state: Completer.ITextState,
+    reply: CompletionHandler.IReply
+  ): void {
+    const model = this._updateModel(state, reply.start, reply.end);
+    if (!model) {
       return;
     }
 
@@ -451,11 +467,49 @@ export class CompletionHandler implements IDisposable {
     model.setOptions(matches, typeMap);
   }
 
+  /**
+   * Receive completion items from provider.
+   *
+   * @param state - The state of the editor when completion request was made.
+   *
+   * @param reply - The API response returned for a completion request.
+   */
+  private _onFetchItemsReply(
+    state: Completer.ITextState,
+    reply: CompletionHandler.ICompletionItemsReply
+  ) {
+    const model = this._updateModel(state, reply.start, reply.end);
+    if (!model) {
+      return;
+    }
+    if (reply.items && model.setCompletionItems) {
+      model.setCompletionItems(reply.items);
+    }
+  }
+
+  /**
+   * If completion requets fails, reset model and fail silently.
+   */
+  private _onFailure() {
+    const model = this.completer.model;
+
+    if (model) {
+      model.reset(true);
+    }
+  }
+
   private _connector: IDataConnector<
     CompletionHandler.IReply,
     void,
     CompletionHandler.IRequest
   >;
+  private _fetchItems?: (
+    request: CompletionHandler.IRequest
+  ) => Promise<{
+    start: number;
+    end: number;
+    items: CompletionHandler.ICompletionItems;
+  }>;
   private _editor: CodeEditor.IEditor | null = null;
   private _enabled = false;
   private _pending = 0;
@@ -484,6 +538,13 @@ export namespace CompletionHandler {
      * rejected promises.
      */
     connector: IDataConnector<IReply, void, IRequest>;
+    /**
+     * Fetcher for ICompletionItems.
+     * If this is set, it'll be used in lieu of the data connector.
+     */
+    fetchItems?: (
+      request: CompletionHandler.IRequest
+    ) => Promise<CompletionHandler.ICompletionItemsReply>;
   }
 
   /**
@@ -536,6 +597,24 @@ export namespace CompletionHandler {
     deprecated?: boolean;
   }
 
+  /**
+   * A reply to a completion items fetch request.
+   */
+  export interface ICompletionItemsReply {
+    /**
+     * The starting index for the substring being replaced by completion.
+     */
+    start: number;
+    /**
+     * The end index for the substring being replaced by completion.
+     */
+    end: number;
+    /**
+     * A list of completion items.
+     */
+    items: CompletionHandler.ICompletionItems;
+  }
+
   /**
    * A reply to a completion request.
    */
@@ -559,11 +638,6 @@ export namespace CompletionHandler {
      * Any metadata that accompanies the completion reply.
      */
     metadata: ReadonlyJSONObject;
-
-    /**
-     * Hook for extensions to send ICompletionItems.
-     */
-    items?: ICompletionItems;
   }
 
   /**

+ 8 - 0
packages/completer/src/tokens.ts

@@ -55,6 +55,14 @@ export namespace ICompletionManager {
       void,
       CompletionHandler.IRequest
     >;
+
+    /**
+     * Set this to output enhanced completions (see CompletionHandler.ICompletionItem).
+     * If this is set, it'll be used in lieu of the data connector.
+     */
+    fetchItems?: (
+      request: CompletionHandler.IRequest
+    ) => Promise<CompletionHandler.ICompletionItemsReply>;
   }
 
   /**