Merge from vscode 31e03b8ffbb218a87e3941f2b63a249f061fe0e4 (#4986)

This commit is contained in:
Anthony Dresser
2019-04-10 16:29:23 -07:00
committed by GitHub
parent 18c54f41bd
commit 8315dacda4
320 changed files with 5540 additions and 3822 deletions

View File

@@ -264,6 +264,11 @@ configurationRegistry.registerConfiguration({
type: 'boolean',
default: true
},
'terminal.integrated.enableLatencyMitigation': {
description: nls.localize('terminal.integrated.enableLatencyMitigation', "Whether to enable the latency mitigation feature for high-latency terminals."),
type: 'boolean',
default: false
},
'terminal.integrated.experimentalRefreshOnResume': {
description: nls.localize('terminal.integrated.experimentalRefreshOnResume', "An experimental setting that will refresh the terminal renderer when the system is resumed."),
type: 'boolean',

View File

@@ -587,6 +587,19 @@ export class TerminalInstance implements ITerminalInstance {
if (this._processManager) {
this._widgetManager = new TerminalWidgetManager(this._wrapperElement);
this._processManager.onProcessReady(() => this._linkHandler.setWidgetManager(this._widgetManager));
this._processManager.onProcessReady(() => {
if (this._configHelper.config.enableLatencyMitigation) {
if (!this._processManager) {
return;
}
this._processManager.getLatency().then(latency => {
if (latency > 20 && (this._xterm as any).typeAheadInit) {
(this._xterm as any).typeAheadInit(this._processManager, this._themeService);
}
});
}
});
}
const computedStyle = window.getComputedStyle(this._container);

View File

@@ -6,7 +6,7 @@
import * as platform from 'vs/base/common/platform';
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ProcessState, ITerminalProcessManager, IShellLaunchConfig, ITerminalConfigHelper, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal';
import { ProcessState, ITerminalProcessManager, IShellLaunchConfig, ITerminalConfigHelper, ITerminalChildProcess, IBeforeProcessDataEvent } from 'vs/workbench/contrib/terminal/common/terminal';
import { ILogService } from 'vs/platform/log/common/log';
import { Emitter, Event } from 'vs/base/common/event';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
@@ -14,11 +14,10 @@ import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/commo
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { Schemas } from 'vs/base/common/network';
import { REMOTE_HOST_SCHEME, getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
import { sanitizeProcessEnvironment } from 'vs/base/common/processes';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IProductService } from 'vs/platform/product/common/product';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -57,6 +56,8 @@ export class TerminalProcessManager implements ITerminalProcessManager {
private readonly _onProcessReady = new Emitter<void>();
public get onProcessReady(): Event<void> { return this._onProcessReady.event; }
private readonly _onBeforeProcessData = new Emitter<IBeforeProcessDataEvent>();
public get onBeforeProcessData(): Event<IBeforeProcessDataEvent> { return this._onBeforeProcessData.event; }
private readonly _onProcessData = new Emitter<string>();
public get onProcessData(): Event<string> { return this._onProcessData.event; }
private readonly _onProcessTitle = new Emitter<string>();
@@ -72,9 +73,8 @@ export class TerminalProcessManager implements ITerminalProcessManager {
@ILogService private readonly _logService: ILogService,
@IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService,
@IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService,
@IWindowService private readonly _windowService: IWindowService,
@IConfigurationService private readonly _workspaceConfigurationService: IConfigurationService,
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
@IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService,
@IProductService private readonly _productService: IProductService,
@ITerminalInstanceService private readonly _terminalInstanceService: ITerminalInstanceService,
@IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService
@@ -114,7 +114,7 @@ export class TerminalProcessManager implements ITerminalProcessManager {
if (shellLaunchConfig.cwd && typeof shellLaunchConfig.cwd === 'object') {
this.remoteAuthority = getRemoteAuthority(shellLaunchConfig.cwd);
} else {
this.remoteAuthority = this._windowService.getConfiguration().remoteAuthority;
this.remoteAuthority = this._environmentService.configuration.remoteAuthority;
}
const hasRemoteAuthority = !!this.remoteAuthority;
let launchRemotely = hasRemoteAuthority || forceExtHostProcess;
@@ -183,7 +183,11 @@ export class TerminalProcessManager implements ITerminalProcessManager {
const p = this._process!;
p.onProcessData(data => {
this._onProcessData.fire(data);
const beforeProcessDataEvent: IBeforeProcessDataEvent = { data };
this._onBeforeProcessData.fire(beforeProcessDataEvent);
if (beforeProcessDataEvent.data && beforeProcessDataEvent.data.length > 0) {
this._onProcessData.fire(beforeProcessDataEvent.data);
}
});
p.onProcessIdReady(pid => {

View File

@@ -17,7 +17,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { TerminalTab } from 'vs/workbench/contrib/terminal/browser/terminalTab';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IFileService } from 'vs/platform/files/common/files';
import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance';
@@ -35,7 +35,7 @@ export abstract class TerminalService extends CommonTerminalService implements I
@INotificationService notificationService: INotificationService,
@IDialogService dialogService: IDialogService,
@IInstantiationService protected readonly _instantiationService: IInstantiationService,
@IWindowService private _windowService: IWindowService,
@IWorkbenchEnvironmentService private _environmentService: IWorkbenchEnvironmentService,
@IExtensionService extensionService: IExtensionService,
@IFileService fileService: IFileService,
) {
@@ -76,7 +76,7 @@ export abstract class TerminalService extends CommonTerminalService implements I
return;
}
if (this._windowService.getConfiguration().remoteAuthority) {
if (this._environmentService.configuration.remoteAuthority) {
// Don't suggest if the opened workspace is remote
return;
}
@@ -87,7 +87,7 @@ export abstract class TerminalService extends CommonTerminalService implements I
return;
}
if (this._windowService.getConfiguration().remoteAuthority) {
if (this._environmentService.configuration.remoteAuthority) {
// Don't suggest if the opened workspace is remote
return;
}

View File

@@ -0,0 +1,136 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Terminal as XTermTerminal } from 'vscode-xterm';
import { ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal';
import { IThemeService } from 'vs/platform/theme/common/themeService';
export interface ITerminalCore {
buffer: any;
}
export interface ITypeAheadAddonTerminal {
_core: ITerminalCore;
on: any;
write(data: string): void;
cols: number;
__typeAheadQueue: string[];
__typeAheadState: TypeAheadState;
__typeAheadCurrentYBase: number;
__typeAheadCurrentY: number;
}
enum TypeAheadState {
/**
* The normal state, ready to type if it starts.
*/
Normal,
/**
* Something happens such that we cannot make a good guess on what to print,
* wait until the cursor row changes before proceeding.
*/
AwaitingRowChange
}
function isCharPrintable(data: string): boolean {
const code = data.charCodeAt(0);
return data.length === 1 && code >= 32 && code <= 126;
}
function init(terminal: any, processManager: ITerminalProcessManager, themeService: IThemeService): void {
const t = terminal as ITypeAheadAddonTerminal;
t.__typeAheadQueue = [];
t.__typeAheadState = TypeAheadState.Normal;
t.__typeAheadCurrentYBase = 0;
t.__typeAheadCurrentY = 0;
function typeAhead(data: string): void {
for (let i = 0; i < data.length; i++) {
t.__typeAheadQueue.push(data[i]);
}
t.write(data);
}
t.on('cursormove', () => {
// Reset if the cursor row changed
if (t._core.buffer.ybase !== t.__typeAheadCurrentYBase || t._core.buffer.y !== t.__typeAheadCurrentY) {
t.__typeAheadCurrentYBase = t._core.buffer.ybase;
t.__typeAheadCurrentY = t._core.buffer.y;
t.__typeAheadState = TypeAheadState.Normal;
}
});
t.on('data', (data: string) => {
// Exit if we're waiting for a row change
if (t.__typeAheadState === TypeAheadState.AwaitingRowChange) {
return;
}
// Only enable in the normal buffer
if (!t._core.buffer._hasScrollback) {
return;
}
// // Handle enter
// if (data === '\r') {
// typeAhead('\r\n');
// return;
// }
// // Left arrow
// if (data === '\x1b[D') {
// // TODO: How to stop it from going beyond prompt?
// typeAhead(String.fromCharCode(8));
// }
// // Right arrow
// if (data === '\x1b[C') {
// // TODO: How to stop it from going beyond prompt?
// typeAhead('\x1b[C');
// }
// // Backspace (DEL)
// if (data.charCodeAt(0) === 127) {
// // TODO: This would require knowing the prompt length to be able to shift everything
// }
if (!isCharPrintable(data)) {
t.__typeAheadState = TypeAheadState.AwaitingRowChange;
return;
}
if (t._core.buffer.x === t.cols - 1) {
// TODO: Does the space get added on Windows/Linux too?
data += ' \r';
}
typeAhead(data);
});
processManager.onBeforeProcessData(event => {
let consumeCount = 0;
for (let i = 0; i < event.data.length; i++) {
if (t.__typeAheadQueue[0] === event.data[i]) {
t.__typeAheadQueue.shift();
consumeCount++;
} else {
t.__typeAheadQueue.length = 0;
break;
}
}
if (consumeCount === event.data.length) {
event.data = '';
} else if (consumeCount > 0) {
event.data = event.data.substr(consumeCount);
}
});
}
export function apply(terminalConstructor: typeof XTermTerminal) {
(<any>terminalConstructor.prototype).typeAheadInit = function (processManager: ITerminalProcessManager, themeService: IThemeService): void {
init(this, processManager, themeService);
};
}