未验证 提交 67b30c0c 编写于 作者: D Daniel Imms 提交者: GitHub

Merge pull request #67828 from hhu94/git-diff-links-simple

Add git diff terminal link handler
......@@ -63,6 +63,9 @@ export class TerminalLinkHandler {
private _widgetManager: TerminalWidgetManager;
private _processCwd: string;
private _localLinkPattern: RegExp;
private _gitDiffPreImagePattern: RegExp;
private _gitDiffPostImagePattern: RegExp;
private readonly _tooltipCallback: (event: MouseEvent, uri: string) => boolean | void;
constructor(
private _xterm: any,
......@@ -75,8 +78,23 @@ export class TerminalLinkHandler {
const baseLocalLinkClause = _platform === platform.Platform.Windows ? winLocalLinkClause : unixLocalLinkClause;
// Append line and column number regex
this._localLinkPattern = new RegExp(`${baseLocalLinkClause}(${lineAndColumnClause})`);
// Matches '--- a/src/file1', capturing 'src/file1' in group 1
this._gitDiffPreImagePattern = /^--- a\/(\S*)/;
// Matches '+++ b/src/file1', capturing 'src/file1' in group 1
this._gitDiffPostImagePattern = /^\+\+\+ b\/(\S*)/;
this._tooltipCallback = (e: MouseEvent) => {
if (this._terminalService && this._terminalService.configHelper.config.rendererType === 'dom') {
const target = (e.target as HTMLElement);
this._widgetManager.showMessage(target.offsetLeft, target.offsetTop, this._getLinkHoverString());
} else {
this._widgetManager.showMessage(e.offsetX, e.offsetY, this._getLinkHoverString());
}
};
this.registerWebLinkHandler();
this.registerLocalLinkHandler();
this.registerGitDiffLinkHandlers();
}
public setWidgetManager(widgetManager: TerminalWidgetManager): void {
......@@ -90,14 +108,7 @@ export class TerminalLinkHandler {
public registerCustomLinkHandler(regex: RegExp, handler: (uri: string) => void, matchIndex?: number, validationCallback?: XtermLinkMatcherValidationCallback): number {
const options: ILinkMatcherOptions = {
matchIndex,
tooltipCallback: (e: MouseEvent) => {
if (this._terminalService && this._terminalService.configHelper.config.rendererType === 'dom') {
const target = (e.target as HTMLElement);
this._widgetManager.showMessage(target.offsetLeft, target.offsetTop, this._getLinkHoverString());
} else {
this._widgetManager.showMessage(e.offsetX, e.offsetY, this._getLinkHoverString());
}
},
tooltipCallback: this._tooltipCallback,
leaveCallback: () => this._widgetManager.closeMessage(),
willLinkActivate: (e: MouseEvent) => this._isLinkActivationModifierDown(e),
priority: CUSTOM_LINK_PRIORITY
......@@ -114,14 +125,7 @@ export class TerminalLinkHandler {
});
this._xterm.webLinksInit(wrappedHandler, {
validationCallback: (uri: string, callback: (isValid: boolean) => void) => this._validateWebLink(uri, callback),
tooltipCallback: (e: MouseEvent) => {
if (this._terminalService && this._terminalService.configHelper.config.rendererType === 'dom') {
const target = (e.target as HTMLElement);
this._widgetManager.showMessage(target.offsetLeft, target.offsetTop, this._getLinkHoverString());
} else {
this._widgetManager.showMessage(e.offsetX, e.offsetY, this._getLinkHoverString());
}
},
tooltipCallback: this._tooltipCallback,
leaveCallback: () => this._widgetManager.closeMessage(),
willLinkActivate: (e: MouseEvent) => this._isLinkActivationModifierDown(e)
});
......@@ -133,20 +137,29 @@ export class TerminalLinkHandler {
});
this._xterm.registerLinkMatcher(this._localLinkRegex, wrappedHandler, {
validationCallback: (uri: string, callback: (isValid: boolean) => void) => this._validateLocalLink(uri, callback),
tooltipCallback: (e: MouseEvent) => {
if (this._terminalService && this._terminalService.configHelper.config.rendererType === 'dom') {
const target = (e.target as HTMLElement);
this._widgetManager.showMessage(target.offsetLeft, target.offsetTop, this._getLinkHoverString());
} else {
this._widgetManager.showMessage(e.offsetX, e.offsetY, this._getLinkHoverString());
}
},
tooltipCallback: this._tooltipCallback,
leaveCallback: () => this._widgetManager.closeMessage(),
willLinkActivate: (e: MouseEvent) => this._isLinkActivationModifierDown(e),
priority: LOCAL_LINK_PRIORITY
});
}
public registerGitDiffLinkHandlers(): void {
const wrappedHandler = this._wrapLinkHandler(url => {
this._handleLocalLink(url);
});
const options = {
matchIndex: 1,
validationCallback: (uri: string, callback: (isValid: boolean) => void) => this._validateLocalLink(uri, callback),
tooltipCallback: this._tooltipCallback,
leaveCallback: () => this._widgetManager.closeMessage(),
willLinkActivate: (e: MouseEvent) => this._isLinkActivationModifierDown(e),
priority: LOCAL_LINK_PRIORITY
};
this._xterm.registerLinkMatcher(this._gitDiffPreImagePattern, wrappedHandler, options);
this._xterm.registerLinkMatcher(this._gitDiffPostImagePattern, wrappedHandler, options);
}
public dispose(): void {
this._xterm = null;
this._hoverDisposables = dispose(this._hoverDisposables);
......@@ -172,6 +185,14 @@ export class TerminalLinkHandler {
return this._localLinkPattern;
}
protected get _gitDiffPreImageRegex(): RegExp {
return this._gitDiffPreImagePattern;
}
protected get _gitDiffPostImageRegex(): RegExp {
return this._gitDiffPostImagePattern;
}
private _handleLocalLink(link: string): PromiseLike<any> {
return this._resolvePath(link).then(resolvedLink => {
if (!resolvedLink) {
......
......@@ -14,6 +14,12 @@ class TestTerminalLinkHandler extends TerminalLinkHandler {
public get localLinkRegex(): RegExp {
return this._localLinkRegex;
}
public get gitDiffLinkPreImageRegex(): RegExp {
return this._gitDiffPreImageRegex;
}
public get gitDiffLinkPostImageRegex(): RegExp {
return this._gitDiffPostImageRegex;
}
public preprocessPath(link: string): string | null {
return this._preprocessPath(link);
}
......@@ -217,4 +223,30 @@ suite('Workbench - TerminalLinkHandler', () => {
assert.equal(linkHandler.preprocessPath('/absolute/path/file3'), '/absolute/path/file3');
});
});
test('gitDiffLinkRegex', () => {
// The platform is irrelevant because the links generated by Git are the same format regardless of platform
const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Linux, null!, null!, null!, null!);
function assertAreGoodMatches(matches: RegExpMatchArray | null) {
if (matches) {
assert.equal(matches.length, 2);
assert.equal(matches[1], 'src/file1');
} else {
assert.fail();
}
}
// Happy cases
assertAreGoodMatches('--- a/src/file1'.match(linkHandler.gitDiffLinkPreImageRegex));
assertAreGoodMatches('--- a/src/file1 '.match(linkHandler.gitDiffLinkPreImageRegex));
assertAreGoodMatches('+++ b/src/file1'.match(linkHandler.gitDiffLinkPostImageRegex));
assertAreGoodMatches('+++ b/src/file1 '.match(linkHandler.gitDiffLinkPostImageRegex));
// Make sure /dev/null isn't a match
assert.equal(linkHandler.gitDiffLinkPreImageRegex.test('--- /dev/null'), false);
assert.equal(linkHandler.gitDiffLinkPreImageRegex.test('--- /dev/null '), false);
assert.equal(linkHandler.gitDiffLinkPostImageRegex.test('+++ /dev/null'), false);
assert.equal(linkHandler.gitDiffLinkPostImageRegex.test('+++ /dev/null '), false);
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册