Search code examples
vscode-extensions

vscode extension completion: how to replace the original text?


const scarlingProvider = vscode.languages.registerCompletionItemProvider(
        'javascript',
        {
            provideCompletionItems(document, position, token, context) {
                const linePrefix = document.lineAt(position).text.substr(0, position.character);
                if (!hasChinese(linePrefix)) {
                    return undefined;
                }
                const reminds = starling.match(linePrefix)
                console.log('reminds: ', reminds);
                return [reminds].map(val => {
                    try {
                        const item = new vscode.CompletionItem(val, vscode.CompletionItemKind.Method)
                        item.insertText = `$t('${val}', '${linePrefix.trim()}')`
                        return item
                    } catch(err) {
                        console.log('err: ', err);
                    }
                })
            }
        },
        ' '

As above, it's a snippet of a completion extension. I want the selected text to replace the original text instead of inserting that after the original text. What should I do?


Solution

  • You have to specify a range with your completion item. The model can give you the position of the original text for which the provider has been invoked:

    const scarlingProvider = vscode.languages.registerCompletionItemProvider(
            'javascript',
            {
                provideCompletionItems(document, position, token, context) {
                    const linePrefix = document.lineAt(position).text.substr(0, position.character);
                    if (!hasChinese(linePrefix)) {
                        return undefined;
                    }
    
                    const info = model.getWordUntilPosition(position);
                    const range = {
                        startLineNumber: position.lineNumber,
                        startColumn: info.startColumn - 1,
                        endLineNumber: position.lineNumber,
                        endColumn: info.endColumn,
                    };
    
    
                    const reminds = starling.match(linePrefix)
                    console.log('reminds: ', reminds);
                    return [reminds].map(val => {
                        try {
                            return {
                                label: "<a label>",
                                kind: CompletionItemKind.Method,
                                range,
                                insertText: `$t('${val}', '${linePrefix.trim()}')`,
                                detail: "<a description>",
                            }
                        } catch(err) {
                            console.log('err: ', err);
                        }
                    })
                }
            },
            ' '