Warm tip: This article is reproduced from stackoverflow.com, please click
typescript visual-studio-code vscode-extensions

Custom Extension for JSON Completion Does Not Work in Double Quotes

发布于 2020-03-30 21:13:53

I'm developing a VSCode extension that should enhance JSON editing with additional code completion. Therefore I added four dummy suggestions (foo, foo1, foo2, foo3) to start testing. When typing a colon after a JSON key it works as expected:

expected behavior

Also when I trigger completion in an empty object it works as I want it (including suggestions from other extensions):

enter image description here

However when I trigger completion within double quotes (no matter if they contain text or not) my suggestions are missing:

enter image description here enter image description here

When I set a breakpoint in my CompletionItemProvider execution pauses as expected in both cases. So it is called correctly and it returns my suggestions for sure. I looked in existing JSON editor extensions (even VSCodes default one) to get advice how to implement it correctly and to see if the default JSON extension maybe overwrites all suggestions within double quotes (even though that would break the whole extensibility idea in my opinion) but couldn't find anything.

To reproduce it is enough to scaffold an empty extension as described here.

Here is my extension.ts:

// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

class OpenApiCompletionItemProvider implements vscode.CompletionItemProvider {
    public provideCompletionItems(
        document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
        Thenable<vscode.CompletionItem[]> {
        return Promise.resolve([
            new vscode.CompletionItem('foo', vscode.CompletionItemKind.Class),
            new vscode.CompletionItem('foo1', vscode.CompletionItemKind.Property),
            new vscode.CompletionItem('foo2', vscode.CompletionItemKind.Interface),
            new vscode.CompletionItem('foo3', vscode.CompletionItemKind.Class),
        ]);
    }
}

export function activate(ctx: vscode.ExtensionContext): void {
    ctx.subscriptions.push(
        vscode.languages.registerCompletionItemProvider(
            { pattern: '**/*.openapi.json' },
            new OpenApiCompletionItemProvider(),
            ':',
            '"'
        )
    );
}

// this method is called when your extension is deactivated
export function deactivate() { }
Questioner
Corristo
Viewed
67
Gama11 2020-01-31 19:17

The starting quote " is part of what VSCode considers the current "word". Consequently, the completion items you return don't match the current filter string " and are not displayed.

This can be fixed by including the full word (with quotes) in the insert text:

new vscode.CompletionItem('"foo"', vscode.CompletionItemKind.Class)

(keep the label string the same and use insertText if you don't want the quotes to be displayed in the completion popup)

Alternatively, you could adjust the range accordingly:

var item = new vscode.CompletionItem('foo', vscode.CompletionItemKind.Class);
item.range = new vscode.Range(position, position);

Note: you may find document.getWordRangeAtPosition() useful. You can find the definition of a "word" in JSON here.