0

I am trying to build a VSCode extension with dynamic snippets. I have looked into this StackOverflow answer: Dynamic snippet evaluation in VSCode and then tried with the CompletionItemProvider (https://code.visualstudio.com/api/references/vscode-api#CompletionItemProvider) and looked into this example by Microsoft https://github.com/microsoft/vscode-extension-samples/tree/master/completions-sample/src

Now my dynamic snippet extension calls a API (which i made and works fine) and then the data is retrieved. But the CompletionItem doesn't show up on VSCode

Here is the code for the extension

const provider1 = vscode.languages.registerCompletionItemProvider('plaintext', {

        async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext) {
            const linePrefix = document.lineAt(position).text.substr(0, position.character);

            console.log(linePrefix);

            console.log("in provide")
            
            const val = await callToAPIAndRetrieve("sa")
            console.log(val)



            // a simple completion item which inserts `Hello World!`
            const simpleCompletion = new vscode.CompletionItem(val);
            return [simpleCompletion];

        }
    },'');
context.subscriptions.push(provider1);

The extension is registered and all the other functionality works. Only issue is with this completion

here the variable val is populated with the string i want to add. My assumption is that it is something with the async functions. If i hardcode it, it works fine. So i suspect async await maybe the issue Any help is appreciated

EDIT Here is the code for callToAPIAndRetrieve:

async function callToAPIAndRetrieve(term: string): Promise<string> {
    const apiKey = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1OTU0MTI5NTQsIm5iZiI6MTU5NTQxMjk1NCwianRpIjoiY2EzOThjZDctMmEzOS00NzNjLTlmMGEtM2RjNTEyMTkwOTdiIiwiZXhwIjoxNjI2OTQ4OTU0LCJpZGVudGl0eSI6IkdldENvZGVUZXN0IiwiZnJlc2giOmZhbHNlLCJ0eXBlIjoiYWNjZXNzIn0.Rmjxa4zfzuGGW-DrHEasGfBJ0xZZdVmHGuDyemrrn6s";

    var url = "https://getcode.herokuapp.com/api/snippets/2";


    const response = await fetch(url,{
        method:"GET",
        headers:{
            "Authorization":"Bearer "+apiKey
        }
    });

    const json = await response.json();
    console.log(json.snippet.code)
    return (json.snippet.code)
    

}

EDIT I edited the code according to the answer and now i get these logs (which means it works) but still the problem of the completionitem not showing up is still present

ex
Object
sdfg

Here ex is the string i typed, sdfg is the code snippet to be suggested

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
DevHyperCoder
  • 895
  • 1
  • 9
  • 22

1 Answers1

0

I can't reproduce with the following code and VSC 1.44

    const callToAPIAndRetrieve = msg => new Promise(resolve => { setTimeout(() => resolve(msg), 1000); });
    context.subscriptions.push(vscode.languages.registerCompletionItemProvider('plaintext', {
      async provideCompletionItems(document, position, token, context) {
        const val = await callToAPIAndRetrieve('Async Await!!');
        console.log(val);
        const simpleCompletion = new vscode.CompletionItem(val);
        return [simpleCompletion];
      }
    },''));

It shows a Loading... until the timer calls the resolve method.


Edit:

Don't assume the fetch will succeed.

Remove this api-key and create a new one.

function callToAPIAndRetrieve(term) {
  return new Promise(resolve => {
    const apiKey = "eyJ0eX....";
    var url = "https://getcode.herokuapp.com/api/snippets/2";
    fetch(url,{
      method:"GET",
      headers:{ "Authorization":"XXX "+apiKey }
    })
    .then(response => {
      if (!response.ok) { resolve(undefined); return; }
      const contentType = response.headers.get('content-type');
      if (!contentType || !contentType.includes('application/json')) { resolve(undefined); return; }
      return response.json();
    })
    .then(json => {
      if (!(json.hasOwnProperty('snippet') && json.snippet.hasOwnProperty('code'))) { resolve(undefined); return; }
      resolve(json.snippet.code);
    })
    .catch( () => resolve(undefined));
  });
}

// ...

context.subscriptions.push(vscode.languages.registerCompletionItemProvider('plaintext', {
  async provideCompletionItems(document, position, token, context) {
    const val = await callToAPIAndRetrieve('sa');
    console.log(val);
    if (!val) return undefined;
    const simpleCompletion = new vscode.CompletionItem(val);
    return [simpleCompletion];
  }
},''));
rioV8
  • 24,506
  • 3
  • 32
  • 49