未验证 提交 342f8123 编写于 作者: D Daniel Imms 提交者: GitHub

Merge pull request #83175 from jmbockhorst/link

Change terminal link hover widget position to be consistent
......@@ -7,13 +7,13 @@ import * as nls from 'vs/nls';
import { URI } from 'vs/base/common/uri';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager';
import { TerminalWidgetManager, WidgetVerticalAlignment } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ITerminalProcessManager, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal';
import { ITextEditorSelection } from 'vs/platform/editor/common/editor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IFileService } from 'vs/platform/files/common/files';
import { Terminal, ILinkMatcherOptions } from 'xterm';
import { Terminal, ILinkMatcherOptions, IViewportRange } from 'xterm';
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
import { posix, win32 } from 'vs/base/common/path';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
......@@ -71,7 +71,7 @@ export class TerminalLinkHandler {
private _processCwd: string | undefined;
private _gitDiffPreImagePattern: RegExp;
private _gitDiffPostImagePattern: RegExp;
private readonly _tooltipCallback: (event: MouseEvent, uri: string) => boolean | void;
private readonly _tooltipCallback: (event: MouseEvent, uri: string, location: IViewportRange) => boolean | void;
private readonly _leaveCallback: () => void;
constructor(
......@@ -89,15 +89,38 @@ export class TerminalLinkHandler {
// Matches '+++ b/src/file1', capturing 'src/file1' in group 1
this._gitDiffPostImagePattern = /^\+\+\+ b\/(\S*)/;
this._tooltipCallback = (e: MouseEvent) => {
this._tooltipCallback = (e: MouseEvent, uri: string, location: IViewportRange) => {
if (!this._widgetManager) {
return;
}
// Get the row bottom up
let offsetRow = this._xterm.rows - location.start.row + 1;
let verticalAlignment = WidgetVerticalAlignment.Bottom;
// Show the tooltip on the top of the next row to avoid obscuring the first row
if (location.start.row === 1) {
offsetRow--;
verticalAlignment = WidgetVerticalAlignment.Top;
}
if (this._configHelper.config.rendererType === 'dom') {
const target = (e.target as HTMLElement);
this._widgetManager.showMessage(target.offsetLeft, target.offsetTop, this._getLinkHoverString());
const font = this._configHelper.getFont();
const charWidth = font.charWidth;
const charHeight = font.charHeight;
const leftPosition = (location.start.col - 1) * (charWidth! + (font.letterSpacing / window.devicePixelRatio));
const bottomPosition = offsetRow * (Math.ceil(charHeight! * window.devicePixelRatio) * font.lineHeight) / window.devicePixelRatio;
this._widgetManager.showMessage(leftPosition, bottomPosition, this._getLinkHoverString(), verticalAlignment);
} else {
this._widgetManager.showMessage(e.offsetX, e.offsetY, this._getLinkHoverString());
const target = (e.target as HTMLElement);
const colWidth = target.offsetWidth / this._xterm.cols;
const rowHeight = target.offsetHeight / this._xterm.rows;
const leftPosition = (location.start.col - 1) * colWidth;
const bottomPosition = offsetRow * rowHeight;
this._widgetManager.showMessage(leftPosition, bottomPosition, this._getLinkHoverString(), verticalAlignment);
}
};
this._leaveCallback = () => {
......
......@@ -5,6 +5,11 @@
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
export enum WidgetVerticalAlignment {
Bottom,
Top
}
const WIDGET_HEIGHT = 29;
export class TerminalWidgetManager implements IDisposable {
......@@ -43,13 +48,13 @@ export class TerminalWidgetManager implements IDisposable {
mutationObserver.observe(this._xtermViewport, { attributes: true, attributeFilter: ['style'] });
}
public showMessage(left: number, top: number, text: string): void {
public showMessage(left: number, y: number, text: string, verticalAlignment: WidgetVerticalAlignment = WidgetVerticalAlignment.Bottom): void {
if (!this._container) {
return;
}
dispose(this._messageWidget);
this._messageListeners.clear();
this._messageWidget = new MessageWidget(this._container, left, top, text);
this._messageWidget = new MessageWidget(this._container, left, y, text, verticalAlignment);
}
public closeMessage(): void {
......@@ -71,9 +76,10 @@ class MessageWidget {
private _domNode: HTMLDivElement;
public get left(): number { return this._left; }
public get top(): number { return this._top; }
public get y(): number { return this._y; }
public get text(): string { return this._text; }
public get domNode(): HTMLElement { return this._domNode; }
public get verticalAlignment(): WidgetVerticalAlignment { return this._verticalAlignment; }
public static fadeOut(messageWidget: MessageWidget): IDisposable {
let handle: any;
......@@ -91,13 +97,22 @@ class MessageWidget {
constructor(
private _container: HTMLElement,
private _left: number,
private _top: number,
private _text: string
private _y: number,
private _text: string,
private _verticalAlignment: WidgetVerticalAlignment
) {
this._domNode = document.createElement('div');
this._domNode.style.position = 'absolute';
this._domNode.style.left = `${_left}px`;
this._domNode.style.bottom = `${_container.offsetHeight - Math.max(_top, WIDGET_HEIGHT)}px`;
if (this.verticalAlignment === WidgetVerticalAlignment.Top) {
// Y position is to the top of the widget
this._domNode.style.bottom = `${Math.max(_y, WIDGET_HEIGHT) - WIDGET_HEIGHT}px`;
} else {
// Y position is to the bottom of the widget
this._domNode.style.bottom = `${Math.min(_y, _container.offsetHeight - WIDGET_HEIGHT)}px`;
}
this._domNode.classList.add('terminal-message-widget', 'fadeIn');
this._domNode.textContent = _text;
this._container.appendChild(this._domNode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册