Search code examples
vscode-extensionsvscode-snippets

VSCode TextEditorDecoration API not rendering white spaces


I am trying to create copilot like ghost snippet suggestion using vs code TextEditorDecoration, but I am not able to figure out how to fix below issues

  1. White spaces not getting rendered

enter image description here

  1. Not rendering decorations after the last line. Currently, all are shown on the last line only.

enter image description here

My code look something like below.

        const editorDecoration = vscode.window.createTextEditorDecorationType({
            isWholeLine: false,
        });

        vscode.window.activeEditor!.setDecorations(editorDecoration, getDecoration(`let timeout;
    return function() {
        let context = this, args = arguments;
        let later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        let callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
     };
   }`));


 function getDecoration(snippet: string): vscode.DecorationOptions[] {
        const editor = this.activeEditor;
        if (!editor) {
            return [];
        }

        const currentLine = editor.selection.active.line;
        const currentColumn = editor.selection.active.character;

        return snippet.split('\n').map((line, index) => {
            const decoration: vscode.DecorationOptions = {
                range: new vscode.Range(currentLine + index, currentColumn, currentLine + index, currentColumn + line.length),
                renderOptions: {
                    light: {
                        after: {
                            contentText: line,
                            color: 'rgba(0 ,0 , 0, 0.5)'
                        },
                    },
                    dark: {
                        after: {
                            contentText: line,
                            color: 'rgba(255, 255, 255, 0.5)'
                        },
                    },
                },
            };
            return decoration;
        });
    }


Solution

  • What I found by reverse engineering copilot implementation and digging into vs code source code. Copilot using the InlineCompletionItem instead of TextEditorDecoration.

    This is how we can use it. First add InlineCompletionItem Provider as below shown code.

    
    vscode.languages.registerInlineCompletionItemProvider('*', {
                provideInlineCompletionItems: async (document, position, context, cancellationToken) => {
                    
    const suggestions =[ "function sum(a,b) \n { return a+b }" ]
    
                    return suggestions.map((suggestion) => {
                        const endPosition = new vscode.Position(position.line, position.character + suggestion.length);
                        return new vscode.InlineCompletionItem(suggestion, new vscode.Range(position, endPosition));
                    });
                }
            });
    
    

    And then you invoke it on the cursor change event using the below command

    vscode.window.onDidChangeTextEditorSelection(()=>{
     
    vscode.commands.executeCommand('editor.action.inlineSuggest.trigger');
    });
    

    Hope this helps someone who trying for something similar.