Skip to content

[🚀 Request] Add support for additional code-completion fields such as detail and documentation #1650

@dylon

Description

Describe the request

I am implementing an LSP plugin to add support for a new language to VSCode. Once completed, it will support all the features described by this document: Programmatic Language Features. I will need support for testing all of them, but this specific request is to add additional information to the ContentAssistItem model, particularly the detail and documentation fields of the respective CompletionItem. Below is a POC that demonstrates one way to obtain the additional information. I am sure it can be greatly improved upon, but I needed to get unblocked for now:

/**
 * Details about a code completion item.
 */
interface UICompletionItem {

  /** Completion symbol provided by the server. */
  label: string;

  /**
   * Description of the completion item (independent of its documentation, e.g.
   * its definition).
   */
  detail?: string;

  /** One-liner preview of the detail string. */
  compressedDetail?: string;

  /** Additional documentation provided by the server (not supported yet). */
  documentation?: string;

  /** Whether this item is the one highlighted in the completion list. */
  isSelected: boolean;
}

async function getCompletionItems(): Promise<void | UICompletionItem[]> {
  const options: void | WebElement[] =
    await driver.findElements(By.css('[widgetid="editor.widget.suggestWidget"] div[role="option"]'));
  if (options) {
    const items: UICompletionItem[] = [];
    for (let i = 0, k = options.length; i < k; i++) {
      const option: WebElement = options[i];
      const label: WebElement = await option.findElement(By.className("label-name"));
      const cssClasses: string = await option.getAttribute("class");
      const isSelected: boolean = /(?:^| )focused(?: |$)/.test(cssClasses);
      const item: UICompletionItem = {
        label: await label.getText(),
        isSelected: isSelected,
      };
      if (isSelected) {
        const compressedDetail: WebElement = await option.findElement(By.className("details-label"));
        item.compressedDetail = await compressedDetail.getText();
        const details: WebElement[] =
          await driver.findElements(By.css('[widgetid="suggest.details"]'));
        if (details.length > 0) {
          item.detail = await details[0].getText();
        }
      }
      items.push(item);
    }
    return items;
  }
}

Usage

function assertHasLines(item: UICompletionItem, lines: string[]): void {
  assert.isTrue(!!(item.compressedDetail || item.detail),
    "expected either the item compressedDetail or detail to be defined");
  if (item.compressedDetail) {
    assert.equal(item.compressedDetail, lines.join("").replace(/[ \t]+/g, " "));
  }
  if (item.detail) {
    assert.equal(item.detail, lines.join("\n"));
  }
}

await editor.typeTextAt(20, 33, '\ne');
await editor.toggleContentAssist(true);  // for for the completion panel to open
let items: UICompletionItem[] = await getCompletionItems() as UICompletionItem[];
assert.isDefined(items);
assert.lengthOf(items, 2);

let item: UICompletionItem = items[0];
assert.equal(item.label, "eval_1d");
assert.isTrue(item.isSelected);
assertHasLines(item, [
  "pure function eval_1d(self, x) result(res)",
  "      class(softmax), intent(in) :: self",
  "      real, intent(in) :: x(:)",
  "      real :: res(size(x))",
  "    end function eval_1d",
]);

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    • Status

      Backlog

    Relationships

    None yet

    Development

    No branches or pull requests

      Participants

      @dylon@djelinek

      Issue actions

        [🚀 Request] Add support for additional code-completion fields such as `detail` and `documentation` · Issue #1650 · redhat-developer/vscode-extension-tester