skip to Main Content

I’m working on a vscode extension using the HoverProvider to supply some HTML links for the MarkdownString, the links themselves are my own commands that work fine (they are being registered and their function hits). Unfortunately I’m unable to pass any querystring values/arguments into the command function.

Is it possible to pass args via the MarkdownString so that the command function receives them?

package.json

{
  "name": "hover-command",

.. snip snip ...
 "contributes": {
    "commands": [
      {
        "command": "hover-command.say_hello",
        "title": "greetz"
      }
    ]
  },

In the extension.ts file

  context.subscriptions.push(
    vscode.commands.registerCommand("say_hello", async (hi: string) => {
      vscode.window.showInformationMessage(hi + ' greetz at ' + new Date());
    })
  );

and


  const selector: vscode.DocumentSelector = {
    scheme: "file",
    language: "*",
  };

  vscode.languages.registerHoverProvider(selector, {
    provideHover(
      doc: vscode.TextDocument,
      pos: vscode.Position,
      token: vscode.CancellationToken
    ): vscode.ProviderResult<vscode.Hover> {
      return new Promise<vscode.Hover>((resolve, reject) => {
        const hoverMarkup = "[Greetings...](command:say_hello?hi=world)";
        if (hoverMarkup) {
          const mdstring = new vscode.MarkdownString(hoverMarkup);
          mdstring.isTrusted = true; // NOTE: this is needed to execute commands!!
          resolve(new vscode.Hover(mdstring));
        } else {
          reject();
        }
      }
      );
    },
  });

but the registered command vscode.window.showInformationMessage is not getting any arguments/query string values. I have tried looking at arguments but still at a loss.

2

Answers


  1. Chosen as BEST ANSWER

    Thanks again @rioV8, after a few failed attempts there are a few steps to get command hover markdown links to work with arguments.

    I'm using TypeScript, so I'll add an interface to define the shape of the args

    interface ISayHelloArgs {
      msg: string;
    }
    

    The registered command then uses this interface (you get a single object 'args')

      context.subscriptions.push(
        vscode.commands.registerCommand("say_hello", async (args: ISayHelloArgs) => {
          vscode.window.showInformationMessage(args.msg + ' greetz at ' + new Date());
        })
      );
    

    The registered HoverProvider then build the args using encodeURI version of a JSON string.

     vscode.languages.registerHoverProvider(selector, {
        provideHover(
          doc: vscode.TextDocument,
          pos: vscode.Position,
          token: vscode.CancellationToken
        ): vscode.ProviderResult<vscode.Hover> {
          return new Promise<vscode.Hover>((resolve, reject) => {
            const args: ISayHelloArgs = { msg: 'hello' };
            const jsonArgs = JSON.stringify(args);
            const hoverMarkup = `[Greetings...](command:say_hello?${encodeURI(jsonArgs)})`;
            if (hoverMarkup) {
              const mdstring = new vscode.MarkdownString(hoverMarkup);
              mdstring.isTrusted = true; // NOTE: this is needed to execute commands!!
              resolve(new vscode.Hover(mdstring));
            } else {
              reject();
            }
          }
          );
        },
      });
    

    This worked for me, hope it helps others.


  2. A few examples from the VSC source code

    [search the Marketplace](command:workbench.extensions.search?%22%40category%3A%5C%22scm%20providers%5C%22%22)
    
    [Initialize Repository](command:git.init?%5Btrue%5D)
    
    [configure](command:workbench.action.openSettings?%5B%22editor.formatOnSave%22%5D)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search