Home > OS >  How to delete trigger character when using vscode api completion feature?
How to delete trigger character when using vscode api completion feature?

Time:07-08

I'm creating a vscode extension that requires some custom completion for json files. Is it possible to not show the trigger character when using autocompletions.

Here is what I mean :

Let's say the trigger character is '.' In your json file you type '.' which suggests you a list of items that I defined in the code. When i press tab or enter, the normal behavior would be to display .item (item being the selected item when i pressed enter) Is it possible to only have 'item' and remove the trigger character '.' ?

Here is my code so far :

context.subscriptions.push(languages.registerCompletionItemProvider (
            { language: 'json', scheme: 'file' },
            // 'json',
            {
                provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext) {
        
                let myitem = (text:string) => {
                    let item = new CompletionItem(text, CompletionItemKind.Text);
                    item.range = new Range(position, position);
                    return item;
                };

                const linePrefix = document.lineAt(position).text.substring(0, position.character);
                if (linePrefix.match(/name/g)) {
                    return [
                        myitem('log'),
                        myitem('warn'),
                        myitem('error'),
                        ];
                } else {
                    return undefined;
                }
            }
            },
            '?' // trigger
        ));

CodePudding user response:

In general the trigger characters would be removed automatically but I believe because your trigger character ? is a non-word character (at least in json files) that vscode returns undefined when trying to get the wordRangeAtPosition(position) and so does not replace the trigger character.

So you will have to take matters into your hands. One way is to get the wordRangeAtPosition() using a custom regex that includes ?. And then use that range in the CompletionItem.range.

After playing around unsuccessfully trying to set the range to a value that would include and thus replace that ? like the link in my comment above, I found success with a different method. Thanks to https://github.com/microsoft/vscode/issues/75237

Try adding this to your CompletionItems:

const rangeToRemove = new vscode.Range(position.line, position.character-1, position.line, position.character);

item.additionalTextEdits = [vscode.TextEdit.delete(rangeToRemove)];

In my testing with the code above you do not need the following line since you will be using the default:

item.range = new Range(position, position);

{I showed the non-typescript version with vscode. added to the calls for general use.]

  • Related