cniggeler
cniggeler

Reputation: 113

VSCode hyperlink between results in one file to different file:line

I have some search results stored in a file, say results.foo. These results provide the file name and line number of each matching result. They look something like this:

bar1.c@123, bar2.c@678,
bar2.c@2345, bar3.c@444

What I'd like to do is, open results.foo in VSCode, have it scan the file (based on the extension), and "know" that clicking on the "123" in results.foo should open file bar1.c to line 123.

problemMatcher gets very close, but this seems action oriented (must invoke an external tool?) and would probably rely on the output window inside VS Code. I have created/used that type of operation inside Visual Studio IDE, but was hoping for simpler, file-to-file linking... Thanks!

Upvotes: 3

Views: 2233

Answers (2)

Mark
Mark

Reputation: 182121

I greatly simplified this via a new option I added to an extension I wrote: Find and Transform.

Here is a working keybinding:

{
  "key": "alt+q",
  "command": "findInCurrentFile",
  "args": {
    "description": "Open file at line number",

    "find": "([.\\w\\\\/]+?)@(\\d*)",
    "isRegex": true,
    "restrictFind": "matchAroundCursor",
    
    "postCommands": [
      {
        "command": "workbench.action.terminal.sendSequence",
        "args": {
          // send the filename:lineNumber to the terminal
          // the capture groups and variables are resolved
          "text": "code -g '${workspaceFolder}${pathSeparator}$1:$2'\u000D"
        }
      }
    ]
  }
}

This will look for the find regex that matches around the cursor position, thanks to the matchAroundCursor option.

Then it will run the postCommand which is sendSequence - but the $1 and $2 in it will be replaced by the capture groups from the find regex.


If you want another approach that uses the full power of the vscode extension api and not a postCommand consider this:

{
  "key": "alt+q",
  "command": "findInCurrentFile",
  "args": {
    "description": "Open file at line number",

    "find": "([.\\w\\\\/]+?)@(\\d*)",
    "isRegex": true,
    "restrictFind": "matchAroundCursor",

    "run": [
      "$${",
        "const pos = new vscode.Position($2-1, 0);",  // Position and thus Range is 0-based, so subtract 1
        "const range = new vscode.Range(pos, pos);",
        "const options = { selection:range, preview:false };",  // 
        "const wsFolderUri = await vscode.workspace.workspaceFolders[0].uri;", // relative to first workspaceFolder
        "const uri = await vscode.Uri.joinPath(wsFolderUri, '$1');",
        "await vscode.commands.executeCommand('vscode.open', uri, options);",
        
        //  or use the simpler below. quickOpen is 1-based
        // "await vscode.commands.executeCommand('workbench.action.quickOpen', `$1:$2`);",  // works but opens the quickOpen
      "}$$",
    ]
  }
}

Upvotes: 2

rioV8
rioV8

Reputation: 28763

You can use the extension HTML Related Links v0.7.0. It does more than only HTML files.

To create a view with the links you can add the following setting (Global or Workspace)

  "html-related-links.include": {
    "all": [
      { "find": "([-\\w.]+)@(\\d+)", "lineNr": "$2" },
      { "find": "([-\\w.]+):(\\d+):(\\d+)", "lineNr": "$2", "charPos": "$3" }
    ]
  }

I also added a case if there is also a character position avaiable.

You have to set html-related-links.alwaysShow to true.

With a next release you can lock the content to a file.

Upvotes: 1

Related Questions