未验证 提交 51daee5d 编写于 作者: P Pine 提交者: GitHub

Merge branch 'master' into misolori/settings-editor-add

...@@ -35,5 +35,5 @@ export interface ITerminalInstanceService { ...@@ -35,5 +35,5 @@ export interface ITerminalInstanceService {
} }
export interface IBrowserTerminalConfigHelper extends ITerminalConfigHelper { export interface IBrowserTerminalConfigHelper extends ITerminalConfigHelper {
panelContainer: HTMLElement; panelContainer: HTMLElement | undefined;
} }
...@@ -1168,7 +1168,7 @@ export class ScrollToPreviousCommandAction extends Action { ...@@ -1168,7 +1168,7 @@ export class ScrollToPreviousCommandAction extends Action {
public run(): Promise<any> { public run(): Promise<any> {
const instance = this.terminalService.getActiveInstance(); const instance = this.terminalService.getActiveInstance();
if (instance) { if (instance && instance.commandTracker) {
instance.commandTracker.scrollToPreviousCommand(); instance.commandTracker.scrollToPreviousCommand();
instance.focus(); instance.focus();
} }
...@@ -1189,7 +1189,7 @@ export class ScrollToNextCommandAction extends Action { ...@@ -1189,7 +1189,7 @@ export class ScrollToNextCommandAction extends Action {
public run(): Promise<any> { public run(): Promise<any> {
const instance = this.terminalService.getActiveInstance(); const instance = this.terminalService.getActiveInstance();
if (instance) { if (instance && instance.commandTracker) {
instance.commandTracker.scrollToNextCommand(); instance.commandTracker.scrollToNextCommand();
instance.focus(); instance.focus();
} }
...@@ -1210,7 +1210,7 @@ export class SelectToPreviousCommandAction extends Action { ...@@ -1210,7 +1210,7 @@ export class SelectToPreviousCommandAction extends Action {
public run(): Promise<any> { public run(): Promise<any> {
const instance = this.terminalService.getActiveInstance(); const instance = this.terminalService.getActiveInstance();
if (instance) { if (instance && instance.commandTracker) {
instance.commandTracker.selectToPreviousCommand(); instance.commandTracker.selectToPreviousCommand();
instance.focus(); instance.focus();
} }
...@@ -1231,7 +1231,7 @@ export class SelectToNextCommandAction extends Action { ...@@ -1231,7 +1231,7 @@ export class SelectToNextCommandAction extends Action {
public run(): Promise<any> { public run(): Promise<any> {
const instance = this.terminalService.getActiveInstance(); const instance = this.terminalService.getActiveInstance();
if (instance) { if (instance && instance.commandTracker) {
instance.commandTracker.selectToNextCommand(); instance.commandTracker.selectToNextCommand();
instance.focus(); instance.focus();
} }
...@@ -1252,7 +1252,7 @@ export class SelectToPreviousLineAction extends Action { ...@@ -1252,7 +1252,7 @@ export class SelectToPreviousLineAction extends Action {
public run(): Promise<any> { public run(): Promise<any> {
const instance = this.terminalService.getActiveInstance(); const instance = this.terminalService.getActiveInstance();
if (instance) { if (instance && instance.commandTracker) {
instance.commandTracker.selectToPreviousLine(); instance.commandTracker.selectToPreviousLine();
instance.focus(); instance.focus();
} }
...@@ -1273,7 +1273,7 @@ export class SelectToNextLineAction extends Action { ...@@ -1273,7 +1273,7 @@ export class SelectToNextLineAction extends Action {
public run(): Promise<any> { public run(): Promise<any> {
const instance = this.terminalService.getActiveInstance(); const instance = this.terminalService.getActiveInstance();
if (instance) { if (instance && instance.commandTracker) {
instance.commandTracker.selectToNextLine(); instance.commandTracker.selectToNextLine();
instance.focus(); instance.focus();
} }
......
...@@ -26,11 +26,11 @@ const MAXIMUM_FONT_SIZE = 25; ...@@ -26,11 +26,11 @@ const MAXIMUM_FONT_SIZE = 25;
* specific test cases can be written. * specific test cases can be written.
*/ */
export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
public panelContainer: HTMLElement; public panelContainer: HTMLElement | undefined;
private _charMeasureElement: HTMLElement; private _charMeasureElement: HTMLElement | undefined;
private _lastFontMeasurement: ITerminalFont; private _lastFontMeasurement: ITerminalFont | undefined;
public config: ITerminalConfiguration; public config!: ITerminalConfiguration;
private readonly _onWorkspacePermissionsChanged = new Emitter<boolean>(); private readonly _onWorkspacePermissionsChanged = new Emitter<boolean>();
public get onWorkspacePermissionsChanged(): Event<boolean> { return this._onWorkspacePermissionsChanged.event; } public get onWorkspacePermissionsChanged(): Event<boolean> { return this._onWorkspacePermissionsChanged.event; }
...@@ -55,49 +55,55 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { ...@@ -55,49 +55,55 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
} }
public configFontIsMonospace(): boolean { public configFontIsMonospace(): boolean {
this._createCharMeasureElementIfNecessary();
const fontSize = 15; const fontSize = 15;
const fontFamily = this.config.fontFamily || this._configurationService.getValue<IEditorOptions>('editor').fontFamily || EDITOR_FONT_DEFAULTS.fontFamily; const fontFamily = this.config.fontFamily || this._configurationService.getValue<IEditorOptions>('editor').fontFamily || EDITOR_FONT_DEFAULTS.fontFamily;
const i_rect = this._getBoundingRectFor('i', fontFamily, fontSize); const i_rect = this._getBoundingRectFor('i', fontFamily, fontSize);
const w_rect = this._getBoundingRectFor('w', fontFamily, fontSize); const w_rect = this._getBoundingRectFor('w', fontFamily, fontSize);
const invalidBounds = !i_rect.width || !w_rect.width; // Check for invalid bounds, there is no reason to believe the font is not monospace
if (invalidBounds) { if (!i_rect || !w_rect || !i_rect.width || !w_rect.width) {
// There is no reason to believe the font is not Monospace.
return true; return true;
} }
return i_rect.width === w_rect.width; return i_rect.width === w_rect.width;
} }
private _createCharMeasureElementIfNecessary() { private _createCharMeasureElementIfNecessary(): HTMLElement {
if (!this.panelContainer) {
throw new Error('Cannot measure element when terminal is not attached');
}
// Create charMeasureElement if it hasn't been created or if it was orphaned by its parent // Create charMeasureElement if it hasn't been created or if it was orphaned by its parent
if (!this._charMeasureElement || !this._charMeasureElement.parentElement) { if (!this._charMeasureElement || !this._charMeasureElement.parentElement) {
this._charMeasureElement = document.createElement('div'); this._charMeasureElement = document.createElement('div');
this.panelContainer.appendChild(this._charMeasureElement); this.panelContainer.appendChild(this._charMeasureElement);
} }
return this._charMeasureElement;
} }
private _getBoundingRectFor(char: string, fontFamily: string, fontSize: number): ClientRect | DOMRect { private _getBoundingRectFor(char: string, fontFamily: string, fontSize: number): ClientRect | DOMRect | undefined {
const style = this._charMeasureElement.style; let charMeasureElement: HTMLElement;
try {
charMeasureElement = this._createCharMeasureElementIfNecessary();
} catch {
return undefined;
}
const style = charMeasureElement.style;
style.display = 'inline-block'; style.display = 'inline-block';
style.fontFamily = fontFamily; style.fontFamily = fontFamily;
style.fontSize = fontSize + 'px'; style.fontSize = fontSize + 'px';
style.lineHeight = 'normal'; style.lineHeight = 'normal';
this._charMeasureElement.innerText = char; charMeasureElement.innerText = char;
const rect = this._charMeasureElement.getBoundingClientRect(); const rect = charMeasureElement.getBoundingClientRect();
style.display = 'none'; style.display = 'none';
return rect; return rect;
} }
private _measureFont(fontFamily: string, fontSize: number, letterSpacing: number, lineHeight: number): ITerminalFont { private _measureFont(fontFamily: string, fontSize: number, letterSpacing: number, lineHeight: number): ITerminalFont {
this._createCharMeasureElementIfNecessary();
const rect = this._getBoundingRectFor('X', fontFamily, fontSize); const rect = this._getBoundingRectFor('X', fontFamily, fontSize);
// Bounding client rect was invalid, use last font measurement if available. // Bounding client rect was invalid, use last font measurement if available.
if (this._lastFontMeasurement && !rect.width && !rect.height) { if (this._lastFontMeasurement && (!rect || !rect.width || !rect.height)) {
return this._lastFontMeasurement; return this._lastFontMeasurement;
} }
...@@ -106,8 +112,8 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { ...@@ -106,8 +112,8 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
fontSize, fontSize,
letterSpacing, letterSpacing,
lineHeight, lineHeight,
charWidth: rect.width, charWidth: rect && rect.width ? rect.width : 0,
charHeight: Math.ceil(rect.height) charHeight: rect && rect.height ? Math.ceil(rect.height) : 0
}; };
return this._lastFontMeasurement; return this._lastFontMeasurement;
} }
......
...@@ -185,22 +185,22 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { ...@@ -185,22 +185,22 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
private _wrapperElement: (HTMLElement & { xterm?: XTermTerminal }) | undefined; private _wrapperElement: (HTMLElement & { xterm?: XTermTerminal }) | undefined;
private _xterm: XTermTerminal | undefined; private _xterm: XTermTerminal | undefined;
private _xtermSearch: SearchAddon | undefined; private _xtermSearch: SearchAddon | undefined;
private _xtermElement: HTMLDivElement; private _xtermElement: HTMLDivElement | undefined;
private _terminalHasTextContextKey: IContextKey<boolean>; private _terminalHasTextContextKey: IContextKey<boolean>;
private _terminalA11yTreeFocusContextKey: IContextKey<boolean>; private _terminalA11yTreeFocusContextKey: IContextKey<boolean>;
private _cols: number; private _cols: number = 0;
private _rows: number; private _rows: number = 0;
private _dimensionsOverride: ITerminalDimensions | undefined; private _dimensionsOverride: ITerminalDimensions | undefined;
private _windowsShellHelper: IWindowsShellHelper | undefined; private _windowsShellHelper: IWindowsShellHelper | undefined;
private _xtermReadyPromise: Promise<XTermTerminal>; private _xtermReadyPromise: Promise<XTermTerminal>;
private _titleReadyPromise: Promise<string>; private _titleReadyPromise: Promise<string>;
private _titleReadyComplete: (title: string) => any; private _titleReadyComplete: ((title: string) => any) | undefined;
private _messageTitleDisposable: IDisposable | undefined; private _messageTitleDisposable: IDisposable | undefined;
private _widgetManager: TerminalWidgetManager; private _widgetManager: TerminalWidgetManager | undefined;
private _linkHandler: TerminalLinkHandler; private _linkHandler: TerminalLinkHandler | undefined;
private _commandTrackerAddon: CommandTrackerAddon; private _commandTrackerAddon: CommandTrackerAddon | undefined;
private _navigationModeAddon: INavigationMode & ITerminalAddon | undefined; private _navigationModeAddon: INavigationMode & ITerminalAddon | undefined;
public disableLayout: boolean; public disableLayout: boolean;
...@@ -228,7 +228,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { ...@@ -228,7 +228,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
public get hadFocusOnExit(): boolean { return this._hadFocusOnExit; } public get hadFocusOnExit(): boolean { return this._hadFocusOnExit; }
public get isTitleSetByProcess(): boolean { return !!this._messageTitleDisposable; } public get isTitleSetByProcess(): boolean { return !!this._messageTitleDisposable; }
public get shellLaunchConfig(): IShellLaunchConfig { return this._shellLaunchConfig; } public get shellLaunchConfig(): IShellLaunchConfig { return this._shellLaunchConfig; }
public get commandTracker(): CommandTrackerAddon { return this._commandTrackerAddon; } public get commandTracker(): CommandTrackerAddon | undefined { return this._commandTrackerAddon; }
public get navigationMode(): INavigationMode | undefined { return this._navigationModeAddon; } public get navigationMode(): INavigationMode | undefined { return this._navigationModeAddon; }
private readonly _onExit = new Emitter<number>(); private readonly _onExit = new Emitter<number>();
...@@ -494,7 +494,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { ...@@ -494,7 +494,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._xterm.onData(data => this._processManager!.write(data)); this._xterm.onData(data => this._processManager!.write(data));
// TODO: How does the cwd work on detached processes? // TODO: How does the cwd work on detached processes?
this.processReady.then(async () => { this.processReady.then(async () => {
this._linkHandler.processCwd = await this._processManager!.getInitialCwd(); if (this._linkHandler) {
this._linkHandler.processCwd = await this._processManager!.getInitialCwd();
}
}); });
// Init winpty compat and link handler after process creation as they rely on the // Init winpty compat and link handler after process creation as they rely on the
// underlying process OS // underlying process OS
...@@ -661,11 +663,16 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { ...@@ -661,11 +663,16 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._container.appendChild(this._wrapperElement); this._container.appendChild(this._wrapperElement);
if (this._processManager) { if (this._processManager) {
this._widgetManager = new TerminalWidgetManager(this._wrapperElement); const widgetManager = new TerminalWidgetManager(this._wrapperElement);
this._processManager.onProcessReady(() => this._linkHandler.setWidgetManager(this._widgetManager)); this._widgetManager = widgetManager;
this._processManager.onProcessReady(() => {
if (this._linkHandler) {
this._linkHandler.setWidgetManager(widgetManager);
}
});
} else if (this._shellLaunchConfig.isRendererOnly) { } else if (this._shellLaunchConfig.isRendererOnly) {
this._widgetManager = new TerminalWidgetManager(this._wrapperElement); this._widgetManager = new TerminalWidgetManager(this._wrapperElement);
this._linkHandler.setWidgetManager(this._widgetManager); this._linkHandler!.setWidgetManager(this._widgetManager);
} }
const computedStyle = window.getComputedStyle(this._container); const computedStyle = window.getComputedStyle(this._container);
...@@ -736,7 +743,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { ...@@ -736,7 +743,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
} }
public registerLinkMatcher(regex: RegExp, handler: (url: string) => void, matchIndex?: number, validationCallback?: (uri: string, callback: (isValid: boolean) => void) => void): number { public registerLinkMatcher(regex: RegExp, handler: (url: string) => void, matchIndex?: number, validationCallback?: (uri: string, callback: (isValid: boolean) => void) => void): number {
return this._linkHandler.registerCustomLinkHandler(regex, handler, matchIndex, validationCallback); return this._linkHandler!.registerCustomLinkHandler(regex, handler, matchIndex, validationCallback);
} }
public deregisterLinkMatcher(linkMatcherId: number): void { public deregisterLinkMatcher(linkMatcherId: number): void {
...@@ -1252,7 +1259,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { ...@@ -1252,7 +1259,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
private async _updateProcessCwd(): Promise<string> { private async _updateProcessCwd(): Promise<string> {
// reset cwd if it has changed, so file based url paths can be resolved // reset cwd if it has changed, so file based url paths can be resolved
const cwd = await this.getCwd(); const cwd = await this.getCwd();
if (cwd) { if (cwd && this._linkHandler) {
this._linkHandler.processCwd = cwd; this._linkHandler.processCwd = cwd;
} }
return cwd; return cwd;
...@@ -1417,11 +1424,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { ...@@ -1417,11 +1424,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._windowsShellHelper = undefined; this._windowsShellHelper = undefined;
} }
const didTitleChange = title !== this._title; const didTitleChange = title !== this._title;
const oldTitle = this._title;
this._title = title; this._title = title;
if (didTitleChange) { if (didTitleChange) {
if (!oldTitle) { if (this._titleReadyComplete) {
this._titleReadyComplete(title); this._titleReadyComplete(title);
this._titleReadyComplete = undefined;
} }
this._onTitleChanged.fire(this); this._onTitleChanged.fire(this);
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { DisposableStore } from 'vs/base/common/lifecycle';
import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IOpenerService } from 'vs/platform/opener/common/opener';
import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
...@@ -67,7 +67,6 @@ interface IPath { ...@@ -67,7 +67,6 @@ interface IPath {
export class TerminalLinkHandler { export class TerminalLinkHandler {
private readonly _hoverDisposables = new DisposableStore(); private readonly _hoverDisposables = new DisposableStore();
private _mouseMoveDisposable: IDisposable;
private _widgetManager: TerminalWidgetManager | undefined; private _widgetManager: TerminalWidgetManager | undefined;
private _processCwd: string | undefined; private _processCwd: string | undefined;
private _gitDiffPreImagePattern: RegExp; private _gitDiffPreImagePattern: RegExp;
...@@ -184,7 +183,6 @@ export class TerminalLinkHandler { ...@@ -184,7 +183,6 @@ export class TerminalLinkHandler {
public dispose(): void { public dispose(): void {
this._hoverDisposables.dispose(); this._hoverDisposables.dispose();
this._mouseMoveDisposable = dispose(this._mouseMoveDisposable);
} }
private _wrapLinkHandler(handler: (uri: string) => boolean | void): XtermLinkMatcherHandler { private _wrapLinkHandler(handler: (uri: string) => boolean | void): XtermLinkMatcherHandler {
......
...@@ -483,7 +483,7 @@ export interface ITerminalInstance { ...@@ -483,7 +483,7 @@ export interface ITerminalInstance {
* An object that tracks when commands are run and enables navigating and selecting between * An object that tracks when commands are run and enables navigating and selecting between
* them. * them.
*/ */
readonly commandTracker: ICommandTracker; readonly commandTracker: ICommandTracker | undefined;
readonly navigationMode: INavigationMode | undefined; readonly navigationMode: INavigationMode | undefined;
......
...@@ -19,7 +19,7 @@ import { findExecutable } from 'vs/workbench/contrib/terminal/node/terminalEnvir ...@@ -19,7 +19,7 @@ import { findExecutable } from 'vs/workbench/contrib/terminal/node/terminalEnvir
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
export class TerminalProcess extends Disposable implements ITerminalChildProcess { export class TerminalProcess extends Disposable implements ITerminalChildProcess {
private _exitCode: number; private _exitCode: number | undefined;
private _closeTimeout: any; private _closeTimeout: any;
private _ptyProcess: pty.IPty | undefined; private _ptyProcess: pty.IPty | undefined;
private _currentTitle: string = ''; private _currentTitle: string = '';
...@@ -188,7 +188,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess ...@@ -188,7 +188,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
} catch (ex) { } catch (ex) {
// Swallow, the pty has already been killed // Swallow, the pty has already been killed
} }
this._onProcessExit.fire(this._exitCode); this._onProcessExit.fire(this._exitCode || 0);
this.dispose(); this.dispose();
}); });
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册