align terminal link commands with internal link types (#142216)

This commit is contained in:
Megan Rogge
2022-02-04 17:35:05 -06:00
committed by GitHub
parent b32cd76c67
commit 2517c1f4b2
9 changed files with 37 additions and 30 deletions
@@ -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);
});
});