Use custom command to open JS doc links (#180737)

Fixes #162507

Prevents incorrect auto transform of the uri
This commit is contained in:
Matt Bierner
2023-04-24 15:05:14 -07:00
committed by GitHub
parent 7c07ee8949
commit 42fbc2f784
5 changed files with 47 additions and 9 deletions

View File

@@ -3,14 +3,15 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { PluginManager } from '../tsServer/plugins';
import TypeScriptServiceClientHost from '../typeScriptServiceClientHost';
import { ActiveJsTsEditorTracker } from '../ui/activeJsTsEditorTracker';
import { Lazy } from '../utils/lazy';
import { PluginManager } from '../tsServer/plugins';
import { CommandManager } from './commandManager';
import { ConfigurePluginCommand } from './configurePlugin';
import { JavaScriptGoToProjectConfigCommand, TypeScriptGoToProjectConfigCommand } from './goToProjectConfiguration';
import { LearnMoreAboutRefactoringsCommand } from './learnMoreAboutRefactorings';
import { OpenJsDocLinkCommand } from './openJsDocLink';
import { OpenTsServerLogCommand } from './openTsServerLog';
import { ReloadJavaScriptProjectsCommand, ReloadTypeScriptProjectsCommand } from './reloadProject';
import { RestartTsServerCommand } from './restartTsServer';
@@ -33,4 +34,5 @@ export function registerBaseCommands(
commandManager.register(new ConfigurePluginCommand(pluginManager));
commandManager.register(new LearnMoreAboutRefactoringsCommand());
commandManager.register(new TSServerRequestCommand(lazyClientHost));
commandManager.register(new OpenJsDocLinkCommand());
}

View File

@@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { Command } from './commandManager';
export interface OpenJsDocLinkCommand_Args {
readonly file: vscode.Uri;
readonly position: vscode.Position;
}
/**
* Proxy command for opening links in jsdoc comments.
*
* This is needed to avoid incorrectly rewriting uris.
*/
export class OpenJsDocLinkCommand implements Command {
public static readonly id = '_typescript.openJsDocLink';
public readonly id = OpenJsDocLinkCommand.id;
public async execute(args: OpenJsDocLinkCommand_Args): Promise<void> {
await vscode.commands.executeCommand('vscode.open', vscode.Uri.from(args.file), <vscode.TextDocumentShowOptions>{
selection: new vscode.Range(args.position, args.position),
});
}
}

View File

@@ -4,7 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { OpenJsDocLinkCommand, OpenJsDocLinkCommand_Args } from '../../commands/openJsDocLink';
import type * as Proto from '../../tsServer/protocol/protocol';
import * as typeConverters from '../../typeConverters';
export interface IFilePathToResourceConverter {
/**
@@ -160,13 +162,15 @@ function convertLinkTags(
case 'link':
if (currentLink) {
if (currentLink.target) {
const link = filePathConverter.toResource(currentLink.target.file)
.with({
fragment: `L${currentLink.target.start.line},${currentLink.target.start.offset}`
});
const file = filePathConverter.toResource(currentLink.target.file);
const args: OpenJsDocLinkCommand_Args = {
file: { ...file.toJSON(), $mid: undefined }, // Prevent VS Code from trying to transform the uri,
position: typeConverters.Position.fromLocation(currentLink.target.start)
};
const command = `command:${OpenJsDocLinkCommand.id}?${encodeURIComponent(JSON.stringify([args]))}`;
const linkText = currentLink.text ? currentLink.text : escapeMarkdownSyntaxTokensForCode(currentLink.name ?? '');
out.push(`[${currentLink.linkcode ? '`' + linkText + '`' : linkText}](${link.toString()})`);
out.push(`[${currentLink.linkcode ? '`' + linkText + '`' : linkText}](${command})`);
} else {
const text = currentLink.text ?? currentLink.name;
if (text) {
@@ -232,6 +236,7 @@ export function documentationToMarkdown(
const out = new vscode.MarkdownString();
appendDocumentationAsMarkdown(out, documentation, tags, filePathConverter);
out.baseUri = baseUri;
out.isTrusted = { enabledCommands: [OpenJsDocLinkCommand.id] };
return out;
}
@@ -251,5 +256,8 @@ export function appendDocumentationAsMarkdown(
out.appendMarkdown('\n\n' + tagsPreview);
}
}
out.isTrusted = { enabledCommands: [OpenJsDocLinkCommand.id] };
return out;
}

View File

@@ -152,7 +152,7 @@ suite('typescript.previewer', () => {
{ "text": "}", "kind": "link" },
{ "text": " b", "kind": "text" }
], noopToResource),
'a [`dog`](file:///path/file.ts#L7%2C5) b');
'a [`dog`](command:_typescript.openJsDocLink?%5B%7B%22file%22%3A%7B%22path%22%3A%22%2Fpath%2Ffile.ts%22%2C%22scheme%22%3A%22file%22%7D%2C%22position%22%3A%7B%22line%22%3A6%2C%22character%22%3A4%7D%7D%5D) b');
});
test('Should render @linkcode text as code', async () => {
@@ -173,6 +173,6 @@ suite('typescript.previewer', () => {
{ "text": "}", "kind": "link" },
{ "text": " b", "kind": "text" }
], noopToResource),
'a [`husky`](file:///path/file.ts#L7%2C5) b');
'a [`husky`](command:_typescript.openJsDocLink?%5B%7B%22file%22%3A%7B%22path%22%3A%22%2Fpath%2Ffile.ts%22%2C%22scheme%22%3A%22file%22%7D%2C%22position%22%3A%7B%22line%22%3A6%2C%22character%22%3A4%7D%7D%5D) b');
});
});