mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-15 00:14:20 +01:00
align terminal link commands with internal link types (#142216)
This commit is contained in:
@@ -12,6 +12,7 @@ import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { TerminalLinkType } from 'vs/workbench/contrib/terminal/browser/links/links';
|
||||
import { IHoverAction } from 'vs/workbench/services/hover/browser/hover';
|
||||
|
||||
export const OPEN_FILE_LABEL = localize('openFile', 'Open file in editor');
|
||||
@@ -28,6 +29,8 @@ export class TerminalLink extends DisposableStore implements ILink {
|
||||
private readonly _onInvalidated = new Emitter<void>();
|
||||
get onInvalidated(): Event<void> { return this._onInvalidated.event; }
|
||||
|
||||
get type(): TerminalLinkType { return this._type; }
|
||||
|
||||
constructor(
|
||||
private readonly _xterm: Terminal,
|
||||
readonly range: IBufferRange,
|
||||
@@ -38,6 +41,7 @@ export class TerminalLink extends DisposableStore implements ILink {
|
||||
private readonly _tooltipCallback: (link: TerminalLink, viewportRange: IViewportRange, modifierDownCallback?: () => void, modifierUpCallback?: () => void) => void,
|
||||
private readonly _isHighConfidenceLink: boolean,
|
||||
readonly label: string | undefined,
|
||||
private readonly _type: TerminalLinkType,
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -99,7 +99,8 @@ export class TerminalLinkDetectorAdapter extends Disposable implements ILinkProv
|
||||
modifierUpCallback
|
||||
}),
|
||||
l.type !== TerminalBuiltinLinkType.Search, // Only search is low confidence
|
||||
l.label || this._getLabel(l.type)
|
||||
l.label || this._getLabel(l.type),
|
||||
l.type
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ export class TerminalLinkManager extends DisposableStore {
|
||||
await opener.open(link);
|
||||
}
|
||||
|
||||
async openRecentLink(type: 'file' | 'web'): Promise<ILink | undefined> {
|
||||
async openRecentLink(type: 'localFile' | 'url'): Promise<ILink | undefined> {
|
||||
let links;
|
||||
let i = this._xterm.buffer.active.length;
|
||||
while ((!links || links.length === 0) && i >= this._xterm.buffer.active.viewportY) {
|
||||
@@ -163,8 +163,8 @@ export class TerminalLinkManager extends DisposableStore {
|
||||
|
||||
private async _getLinksForLine(y: number): Promise<IDetectedLinks | undefined> {
|
||||
let unfilteredWordLinks = await this._getLinksForType(y, 'word');
|
||||
const webLinks = await this._getLinksForType(y, 'web');
|
||||
const fileLinks = await this._getLinksForType(y, 'file');
|
||||
const webLinks = await this._getLinksForType(y, 'url');
|
||||
const fileLinks = await this._getLinksForType(y, 'localFile');
|
||||
const words = new Set();
|
||||
let wordLinks;
|
||||
if (unfilteredWordLinks) {
|
||||
@@ -179,14 +179,16 @@ export class TerminalLinkManager extends DisposableStore {
|
||||
return { wordLinks, webLinks, fileLinks };
|
||||
}
|
||||
|
||||
protected async _getLinksForType(y: number, type: 'word' | 'web' | 'file'): Promise<ILink[] | undefined> {
|
||||
protected async _getLinksForType(y: number, type: 'word' | 'url' | 'localFile'): Promise<ILink[] | undefined> {
|
||||
switch (type) {
|
||||
case 'word':
|
||||
return (await new Promise<ILink[] | undefined>(r => this._standardLinkProviders.get(TerminalWordLinkDetector.id)?.provideLinks(y, r)));
|
||||
case 'web':
|
||||
case 'url':
|
||||
return (await new Promise<ILink[] | undefined>(r => this._standardLinkProviders.get(TerminalUriLinkDetector.id)?.provideLinks(y, r)));
|
||||
case 'file':
|
||||
return (await new Promise<ILink[] | undefined>(r => this._standardLinkProviders.get(TerminalLocalLinkDetector.id)?.provideLinks(y, r)));
|
||||
case 'localFile': {
|
||||
const links = (await new Promise<ILink[] | undefined>(r => this._standardLinkProviders.get(TerminalLocalLinkDetector.id)?.provideLinks(y, r)));
|
||||
return links?.filter(link => (link as TerminalLink).type === TerminalBuiltinLinkType.LocalFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,20 +20,20 @@ export class TerminalLinkQuickpick {
|
||||
const filePicks = links.fileLinks ? await this._generatePicks(links.fileLinks) : undefined;
|
||||
const webPicks = links.webLinks ? await this._generatePicks(links.webLinks) : undefined;
|
||||
const options = {
|
||||
placeHolder: localize('terminal.integrated.openWebLink', "Select the link to open"),
|
||||
placeHolder: localize('terminal.integrated.openDetectedLink', "Select the link to open"),
|
||||
canPickMany: false
|
||||
};
|
||||
const picks: LinkQuickPickItem[] = [];
|
||||
if (webPicks) {
|
||||
picks.push({ type: 'separator', label: localize('terminal.integrated.webLinks', "Web") });
|
||||
picks.push({ type: 'separator', label: localize('terminal.integrated.urlLinks', "Url") });
|
||||
picks.push(...webPicks);
|
||||
}
|
||||
if (filePicks) {
|
||||
picks.push({ type: 'separator', label: localize('terminal.integrated.fileLinks', "File") });
|
||||
picks.push({ type: 'separator', label: localize('terminal.integrated.localFileLinks', "Local File") });
|
||||
picks.push(...filePicks);
|
||||
}
|
||||
if (wordPicks) {
|
||||
picks.push({ type: 'separator', label: localize('terminal.integrated.wordLinks', "Word") });
|
||||
picks.push({ type: 'separator', label: localize('terminal.integrated.searchLinks', "Workspace Search") });
|
||||
picks.push(...wordPicks);
|
||||
}
|
||||
|
||||
|
||||
@@ -818,7 +818,7 @@ export interface ITerminalInstance {
|
||||
/**
|
||||
* Activates the most recent link of the given type.
|
||||
*/
|
||||
openRecentLink(type: 'file' | 'web'): Promise<void>;
|
||||
openRecentLink(type: 'localFile' | 'url'): Promise<void>;
|
||||
}
|
||||
|
||||
export interface IXtermTerminal {
|
||||
|
||||
@@ -1955,14 +1955,14 @@ export function registerTerminalActions() {
|
||||
constructor() {
|
||||
super({
|
||||
id: TerminalCommandId.OpenWebLink,
|
||||
title: { value: localize('workbench.action.terminal.openLastWebLink', "Open Last Web Link"), original: 'Open Last Web Link' },
|
||||
title: { value: localize('workbench.action.terminal.openLastUrlLink', "Open Last Url Link"), original: 'Open Last Url Link' },
|
||||
f1: true,
|
||||
category,
|
||||
precondition: TerminalContextKeys.terminalHasBeenCreated,
|
||||
});
|
||||
}
|
||||
run(accessor: ServicesAccessor) {
|
||||
accessor.get(ITerminalService).doWithActiveInstance(t => t.openRecentLink('web'));
|
||||
accessor.get(ITerminalService).doWithActiveInstance(t => t.openRecentLink('url'));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1970,14 +1970,14 @@ export function registerTerminalActions() {
|
||||
constructor() {
|
||||
super({
|
||||
id: TerminalCommandId.OpenFileLink,
|
||||
title: { value: localize('workbench.action.terminal.openLastFileLink', "Open Last File Link"), original: 'Open Last File Link' },
|
||||
title: { value: localize('workbench.action.terminal.openLastLocalFileLink', "Open Last Local File Link"), original: 'Open Last Local File Link' },
|
||||
f1: true,
|
||||
category,
|
||||
precondition: TerminalContextKeys.terminalHasBeenCreated,
|
||||
});
|
||||
}
|
||||
run(accessor: ServicesAccessor) {
|
||||
accessor.get(ITerminalService).doWithActiveInstance(t => t.openRecentLink('file'));
|
||||
accessor.get(ITerminalService).doWithActiveInstance(t => t.openRecentLink('localFile'));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -743,7 +743,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||
return this._linkManager.getLinks();
|
||||
}
|
||||
|
||||
async openRecentLink(type: 'file' | 'web'): Promise<void> {
|
||||
async openRecentLink(type: 'localFile' | 'url'): Promise<void> {
|
||||
if (!this.areLinksReady || !this._linkManager) {
|
||||
throw new Error('terminal links are not ready, cannot open a link');
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ export const enum TerminalCommandId {
|
||||
OpenDetectedLink = 'workbench.action.terminal.openDetectedLink',
|
||||
OpenWordLink = 'workbench.action.terminal.openWordLink',
|
||||
OpenFileLink = 'workbench.action.terminal.openFileLink',
|
||||
OpenWebLink = 'workbench.action.terminal.openWebLink',
|
||||
OpenWebLink = 'workbench.action.terminal.openUrlLink',
|
||||
RunRecentCommand = 'workbench.action.terminal.runRecentCommand',
|
||||
GoToRecentDirectory = 'workbench.action.terminal.goToRecentDirectory',
|
||||
CopySelection = 'workbench.action.terminal.copySelection',
|
||||
|
||||
@@ -34,13 +34,13 @@ const defaultTerminalConfig: Partial<ITerminalConfiguration> = {
|
||||
|
||||
class TestLinkManager extends TerminalLinkManager {
|
||||
private _links: IDetectedLinks | undefined;
|
||||
protected override async _getLinksForType(y: number, type: 'word' | 'web' | 'file'): Promise<ILink[] | undefined> {
|
||||
protected override async _getLinksForType(y: number, type: 'word' | 'url' | 'localFile'): Promise<ILink[] | undefined> {
|
||||
switch (type) {
|
||||
case 'word':
|
||||
return this._links?.wordLinks?.[y] ? [this._links?.wordLinks?.[y]] : undefined;
|
||||
case 'web':
|
||||
case 'url':
|
||||
return this._links?.webLinks?.[y] ? [this._links?.webLinks?.[y]] : undefined;
|
||||
case 'file':
|
||||
case 'localFile':
|
||||
return this._links?.fileLinks?.[y] ? [this._links?.fileLinks?.[y]] : undefined;
|
||||
}
|
||||
}
|
||||
@@ -91,9 +91,9 @@ suite('TerminalLinkManager', () => {
|
||||
equals(links.webLinks, []);
|
||||
equals(links.wordLinks, []);
|
||||
equals(links.fileLinks, []);
|
||||
const webLink = await linkManager.openRecentLink('web');
|
||||
const webLink = await linkManager.openRecentLink('url');
|
||||
strictEqual(webLink, undefined);
|
||||
const fileLink = await linkManager.openRecentLink('file');
|
||||
const fileLink = await linkManager.openRecentLink('localFile');
|
||||
strictEqual(fileLink, undefined);
|
||||
});
|
||||
test('should return word links in order', async () => {
|
||||
@@ -115,9 +115,9 @@ suite('TerminalLinkManager', () => {
|
||||
const links = await linkManager.getLinks();
|
||||
deepStrictEqual(links.wordLinks?.[0].text, link2.text);
|
||||
deepStrictEqual(links.wordLinks?.[1].text, link1.text);
|
||||
const webLink = await linkManager.openRecentLink('web');
|
||||
const webLink = await linkManager.openRecentLink('url');
|
||||
strictEqual(webLink, undefined);
|
||||
const fileLink = await linkManager.openRecentLink('file');
|
||||
const fileLink = await linkManager.openRecentLink('localFile');
|
||||
strictEqual(fileLink, undefined);
|
||||
});
|
||||
test('should return web links in order', async () => {
|
||||
@@ -135,9 +135,9 @@ suite('TerminalLinkManager', () => {
|
||||
const links = await linkManager.getLinks();
|
||||
deepStrictEqual(links.webLinks?.[0].text, link2.text);
|
||||
deepStrictEqual(links.webLinks?.[1].text, link1.text);
|
||||
const webLink = await linkManager.openRecentLink('web');
|
||||
const webLink = await linkManager.openRecentLink('url');
|
||||
strictEqual(webLink, link2);
|
||||
const fileLink = await linkManager.openRecentLink('file');
|
||||
const fileLink = await linkManager.openRecentLink('localFile');
|
||||
strictEqual(fileLink, undefined);
|
||||
});
|
||||
test('should return file links in order', async () => {
|
||||
@@ -155,10 +155,10 @@ suite('TerminalLinkManager', () => {
|
||||
const links = await linkManager.getLinks();
|
||||
deepStrictEqual(links.fileLinks?.[0].text, link2.text);
|
||||
deepStrictEqual(links.fileLinks?.[1].text, link1.text);
|
||||
const webLink = await linkManager.openRecentLink('web');
|
||||
const webLink = await linkManager.openRecentLink('url');
|
||||
strictEqual(webLink, undefined);
|
||||
linkManager.setLinks({ fileLinks: [link2] });
|
||||
const fileLink = await linkManager.openRecentLink('file');
|
||||
const fileLink = await linkManager.openRecentLink('localFile');
|
||||
strictEqual(fileLink, link2);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user