Convert validated links provider to new model

pull/97065/head
Daniel Imms 2020-05-06 04:32:01 -07:00
parent a685ac69d5
commit 2feae028dd
6 changed files with 55 additions and 41 deletions

View File

@ -56,6 +56,7 @@ export class TerminalLink extends DisposableStore implements ILink {
}
hover(event: MouseEvent, text: string): void {
console.log('hover ' + this.range.end.y, new Error().stack);
// Listen for modifier before handing it off to the hover to handle so it gets disposed correctly
this.add(dom.addDisposableListener(document, 'keydown', e => {
if (this._isModifierDown(e)) {
@ -70,12 +71,16 @@ export class TerminalLink extends DisposableStore implements ILink {
const timeout = this._configurationService.getValue<number>('editor.hover.delay');
this._tooltipScheduler = new RunOnceScheduler(() => {
console.log('tooltip trigger ' + this.range.end.y);
this._tooltipCallback(
this,
convertBufferRangeToViewport(this.range, this._viewportY),
this._isHighConfidenceLink ? () => this._enableDecorations() : undefined,
this._isHighConfidenceLink ? () => this._disableDecorations() : undefined
);
// Clear out scheduler until next hover event
this._tooltipScheduler?.dispose();
this._tooltipScheduler = undefined;
// this.dispose();
}, timeout);
this.add(this._tooltipScheduler);
@ -105,6 +110,7 @@ export class TerminalLink extends DisposableStore implements ILink {
this._hoverListeners = undefined;
this._tooltipScheduler?.dispose();
this._tooltipScheduler = undefined;
console.log('TerminalLink.onLeave fire (' + this.range.end.y + ')');
this._onLeave.fire();
}

View File

@ -301,18 +301,18 @@ export class TerminalLinkManager extends DisposableStore {
const protocolProvider = this._instantiationService.createInstance(TerminalProtocolLinkProvider, this._xterm, wrappedActivateCallback, this._tooltipCallback2.bind(this));
this._linkProviders.push(this._xterm.registerLinkProvider(protocolProvider));
// // Validated local links
// if (this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION).enableFileLinks) {
// const wrappedTextLinkActivateCallback = this._wrapLinkHandler((_, link) => this._handleLocalLink(link));
// const validatedProvider = this._instantiationService.createInstance(TerminalValidatedLocalLinkProvider,
// this._xterm,
// this._processManager.os || OS,
// wrappedTextLinkActivateCallback,
// this._wrapLinkHandler.bind(this),
// this._tooltipCallback2.bind(this),
// async (link, cb) => cb(await this._resolvePath(link)));
// this._linkProviders.push(this._xterm.registerLinkProvider(validatedProvider));
// }
// Validated local links
if (this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION).enableFileLinks) {
const wrappedTextLinkActivateCallback = this._wrapLinkHandler((_, link) => this._handleLocalLink(link));
const validatedProvider = this._instantiationService.createInstance(TerminalValidatedLocalLinkProvider,
this._xterm,
this._processManager.os || OS,
wrappedTextLinkActivateCallback,
this._wrapLinkHandler.bind(this),
this._tooltipCallback2.bind(this),
async (link, cb) => cb(await this._resolvePath(link)));
this._linkProviders.push(this._xterm.registerLinkProvider(validatedProvider));
}
// Word links
const wordProvider = this._instantiationService.createInstance(TerminalWordLinkProvider, this._xterm, this._wrapLinkHandler.bind(this), this._tooltipCallback2.bind(this));

View File

@ -3,8 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Terminal, ILinkProvider, IViewportRange, IBufferCellPosition, ILink, IBufferLine } from 'xterm';
import { getXtermLineContent, convertLinkRangeToBuffer, positionIsInRange } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkHelpers';
import { Terminal, IViewportRange, IBufferLine } from 'xterm';
import { getXtermLineContent, convertLinkRangeToBuffer } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkHelpers';
import { OperatingSystem } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
import { TerminalLink, OPEN_FILE_LABEL, FOLDER_IN_WORKSPACE_LABEL, FOLDER_NOT_IN_WORKSPACE_LABEL } from 'vs/workbench/contrib/terminal/browser/links/terminalLink';
@ -14,6 +14,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { XtermLinkMatcherHandler } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager';
import { TerminalBaseLinkProvider } from 'vs/workbench/contrib/terminal/browser/links/terminalBaseLinkProvider';
const pathPrefix = '(\\.\\.?|\\~)';
const pathSeparatorClause = '\\/';
@ -41,7 +42,7 @@ const lineAndColumnClause = [
'(([^:\\s\\(\\)<>\'\"\\[\\]]*)(:(\\d+))?(:(\\d+))?)' // (file path):336, (file path):336:9
].join('|').replace(/ /g, `[${'\u00A0'} ]`);
export class TerminalValidatedLocalLinkProvider implements ILinkProvider {
export class TerminalValidatedLocalLinkProvider extends TerminalBaseLinkProvider {
constructor(
private readonly _xterm: Terminal,
private readonly _processOperatingSystem: OperatingSystem,
@ -54,10 +55,12 @@ export class TerminalValidatedLocalLinkProvider implements ILinkProvider {
@IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService,
@IHostService private readonly _hostService: IHostService
) {
super();
}
async provideLink(position: IBufferCellPosition, callback: (link: ILink | undefined) => void) {
let startLine = position.y - 1;
protected async _provideLinks(y: number): Promise<TerminalLink[]> {
const result: TerminalLink[] = [];
let startLine = y - 1;
let endLine = startLine;
const lines: IBufferLine[] = [
@ -121,34 +124,31 @@ export class TerminalValidatedLocalLinkProvider implements ILinkProvider {
endLineNumber: 1
}, startLine);
if (positionIsInRange(position, bufferRange)) {
const validatedLink = await new Promise<ILink | undefined>(r => {
this._validationCallback(link, (result) => {
if (result) {
const label = result.isDirectory
? (this._isDirectoryInsideWorkspace(result.uri) ? FOLDER_IN_WORKSPACE_LABEL : FOLDER_NOT_IN_WORKSPACE_LABEL)
: OPEN_FILE_LABEL;
const activateCallback = this._wrapLinkHandler((event: MouseEvent | undefined, text: string) => {
if (result.isDirectory) {
this._handleLocalFolderLink(result.uri);
} else {
this._activateFileCallback(event, text);
}
});
r(this._instantiationService.createInstance(TerminalLink, bufferRange, link, this._xterm.buffer.active.viewportY, activateCallback, this._tooltipCallback, true, label));
} else {
r(undefined);
}
});
const validatedLink = await new Promise<TerminalLink | undefined>(r => {
this._validationCallback(link, (result) => {
if (result) {
const label = result.isDirectory
? (this._isDirectoryInsideWorkspace(result.uri) ? FOLDER_IN_WORKSPACE_LABEL : FOLDER_NOT_IN_WORKSPACE_LABEL)
: OPEN_FILE_LABEL;
const activateCallback = this._wrapLinkHandler((event: MouseEvent | undefined, text: string) => {
if (result.isDirectory) {
this._handleLocalFolderLink(result.uri);
} else {
this._activateFileCallback(event, text);
}
});
r(this._instantiationService.createInstance(TerminalLink, bufferRange, link, this._xterm.buffer.active.viewportY, activateCallback, this._tooltipCallback, true, label));
} else {
r(undefined);
}
});
if (validatedLink) {
callback(validatedLink);
return;
}
});
if (validatedLink) {
result.push(validatedLink);
}
}
callback(undefined);
return result;
}
protected get _localLinkRegex(): RegExp {

View File

@ -173,6 +173,7 @@ export class HoverWidget extends Widget {
}
public dispose(): void {
console.log('HoverWidget.dispose');
if (!this._isDisposed) {
this._onDispose.fire();
this._containerDomNode.parentElement?.removeChild(this.domNode);
@ -225,6 +226,7 @@ class CompositeMouseTracker extends Widget {
private _fireIfMouseOutside(): void {
if (!this._isMouseIn) {
console.log('mouse tracker fire mouse out');
this._onMouseOut.fire();
}
}

View File

@ -34,6 +34,11 @@ export class TerminalHover extends Disposable implements ITerminalWidget {
super();
}
dispose() {
console.log('TerminalHover.dispose');
super.dispose();
}
attach(container: HTMLElement): void {
const target = new CellHoverTarget(container, this._targetOptions);
this._register(this._instantiationService.createInstance(HoverWidget, container, target, this._text, this._linkHandler, []));

View File

@ -29,6 +29,7 @@ export class TerminalWidgetManager implements IDisposable {
if (!this._container) {
return;
}
console.log('attach new widget');
this._attached.get(widget.id)?.dispose();
widget.attach(this._container);
this._attached.set(widget.id, widget);