Open
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",
]);
Metadata
Assignees
Labels
Type
Projects
Status
Backlog
Milestone
Relationships
Development
No branches or pull requests
Activity