未验证 提交 a23c5697 编写于 作者: M Megan Rogge 提交者: GitHub

#132774 (#132808)

上级 c62f59fc
......@@ -176,6 +176,17 @@ export enum TerminalIpcChannels {
}
export const IPtyService = createDecorator<IPtyService>('ptyService');
export const enum TerminalPropertyType {
cwd,
initialCwd
}
export interface TerminalProperty {
type: TerminalPropertyType,
value: any
}
export interface IPtyService {
readonly _serviceBrand: undefined;
......@@ -196,6 +207,7 @@ export interface IPtyService {
readonly onProcessOrphanQuestion: Event<{ id: number }>;
readonly onDidRequestDetach: Event<{ requestId: number, workspaceId: string, instanceId: number }>;
readonly onProcessDidChangeHasChildProcesses: Event<{ id: number, event: boolean }>;
readonly onDidChangeProperty: Event<{ id: number, event: TerminalProperty }>
restartPtyHost?(): Promise<void>;
shutdownAll?(): Promise<void>;
......@@ -471,6 +483,7 @@ export interface ITerminalChildProcess {
onProcessOverrideDimensions?: Event<ITerminalDimensionsOverride | undefined>;
onProcessResolvedShellLaunchConfig?: Event<IShellLaunchConfig>;
onDidChangeHasChildProcesses?: Event<boolean>;
onDidChangeProperty: Event<TerminalProperty>;
/**
* Starts the process.
......
......@@ -15,7 +15,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { LogLevelChannelClient } from 'vs/platform/log/common/logIpc';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { RequestStore } from 'vs/platform/terminal/common/requestStore';
import { HeartbeatConstants, IHeartbeatService, IProcessDataEvent, IPtyService, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, TerminalIcon, TerminalIpcChannels, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal';
import { HeartbeatConstants, IHeartbeatService, IProcessDataEvent, IPtyService, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, TerminalIcon, TerminalIpcChannels, TerminalProperty, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal';
import { registerTerminalPlatformConfiguration } from 'vs/platform/terminal/common/terminalPlatformConfiguration';
import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
import { detectAvailableProfiles } from 'vs/platform/terminal/node/terminalProfiles';
......@@ -83,6 +83,8 @@ export class PtyHostService extends Disposable implements IPtyService {
readonly onDidRequestDetach = this._onDidRequestDetach.event;
private readonly _onProcessDidChangeHasChildProcesses = this._register(new Emitter<{ id: number, event: boolean }>());
readonly onProcessDidChangeHasChildProcesses = this._onProcessDidChangeHasChildProcesses.event;
private readonly _onDidChangeProperty = this._register(new Emitter<{ id: number, event: TerminalProperty }>());
readonly onDidChangeProperty = this._onDidChangeProperty.event;
constructor(
private readonly _reconnectConstants: IReconnectConstants,
......@@ -166,6 +168,7 @@ export class PtyHostService extends Disposable implements IPtyService {
this._register(proxy.onProcessOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e)));
this._register(proxy.onProcessResolvedShellLaunchConfig(e => this._onProcessResolvedShellLaunchConfig.fire(e)));
this._register(proxy.onProcessDidChangeHasChildProcesses(e => this._onProcessDidChangeHasChildProcesses.fire(e)));
this._register(proxy.onDidChangeProperty(e => this._onDidChangeProperty.fire(e)));
this._register(proxy.onProcessReplay(e => this._onProcessReplay.fire(e)));
this._register(proxy.onProcessOrphanQuestion(e => this._onProcessOrphanQuestion.fire(e)));
this._register(proxy.onDidRequestDetach(e => this._onDidRequestDetach.fire(e)));
......
......@@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri';
import { getSystemShell } from 'vs/base/node/shell';
import { ILogService } from 'vs/platform/log/common/log';
import { RequestStore } from 'vs/platform/terminal/common/requestStore';
import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal';
import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, TerminalProperty, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal';
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment';
import { Terminal as XtermTerminal } from 'xterm-headless';
......@@ -60,6 +60,8 @@ export class PtyService extends Disposable implements IPtyService {
readonly onDidRequestDetach = this._onDidRequestDetach.event;
private readonly _onProcessDidChangeHasChildProcesses = this._register(new Emitter<{ id: number, event: boolean }>());
readonly onProcessDidChangeHasChildProcesses = this._onProcessDidChangeHasChildProcesses.event;
private readonly _onDidChangeProperty = this._register(new Emitter<{ id: number, event: TerminalProperty }>());
readonly onDidChangeProperty = this._onDidChangeProperty.event;
constructor(
private _lastPtyId: number,
......@@ -138,6 +140,7 @@ export class PtyService extends Disposable implements IPtyService {
persistentProcess.onProcessReplay(event => this._onProcessReplay.fire({ id, event }));
persistentProcess.onProcessReady(event => this._onProcessReady.fire({ id, event }));
persistentProcess.onProcessTitleChanged(event => this._onProcessTitleChanged.fire({ id, event }));
persistentProcess.onDidChangeProperty(event => this._onDidChangeProperty.fire({ id, event }));
persistentProcess.onProcessShellTypeChanged(event => this._onProcessShellTypeChanged.fire({ id, event }));
persistentProcess.onProcessOrphanQuestion(() => this._onProcessOrphanQuestion.fire({ id }));
this._ptys.set(id, persistentProcess);
......@@ -339,6 +342,8 @@ export class PersistentTerminalProcess extends Disposable {
readonly onProcessData = this._onProcessData.event;
private readonly _onProcessOrphanQuestion = this._register(new Emitter<void>());
readonly onProcessOrphanQuestion = this._onProcessOrphanQuestion.event;
private readonly _onDidChangeProperty = this._register(new Emitter<TerminalProperty>());
readonly onDidChangeProperty = this._onDidChangeProperty.event;
private _inReplay = false;
......@@ -409,6 +414,7 @@ export class PersistentTerminalProcess extends Disposable {
}));
this._register(this._terminalProcess.onProcessTitleChanged(e => this._onProcessTitleChanged.fire(e)));
this._register(this._terminalProcess.onProcessShellTypeChanged(e => this._onProcessShellTypeChanged.fire(e)));
this._register(this._terminalProcess.onDidChangeProperty(e => this._onDidChangeProperty.fire(e)));
// Data buffering to reduce the amount of messages going to the renderer
this._bufferer = new TerminalDataBufferer((_, data) => this._onProcessData.fire(data));
......
......@@ -15,7 +15,7 @@ import { URI } from 'vs/base/common/uri';
import { Promises } from 'vs/base/node/pfs';
import { localize } from 'vs/nls';
import { ILogService } from 'vs/platform/log/common/log';
import { FlowControlConstants, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { FlowControlConstants, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalProperty, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { ChildProcessMonitor } from 'vs/platform/terminal/node/childProcessMonitor';
import { findExecutable, getWindowsBuildNumber } from 'vs/platform/terminal/node/terminalEnvironment';
import { WindowsShellHelper } from 'vs/platform/terminal/node/windowsShellHelper';
......@@ -114,6 +114,8 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
private readonly _onDidChangeHasChildProcesses = this._register(new Emitter<boolean>());
readonly onDidChangeHasChildProcesses = this._onDidChangeHasChildProcesses.event;
private readonly _onDidChangeProperty = this._register(new Emitter<TerminalProperty>());
readonly onDidChangeProperty = this._onDidChangeProperty.event;
onProcessOverrideDimensions?: Event<ITerminalDimensionsOverride | undefined> | undefined;
onProcessResolvedShellLaunchConfig?: Event<IShellLaunchConfig> | undefined;
......
......@@ -18,7 +18,7 @@ import { serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/ter
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { generateUuid } from 'vs/base/common/uuid';
import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { ICreateContributedTerminalProfileOptions, IProcessReadyEvent, IShellLaunchConfigDto, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, TerminalIcon, TerminalLocation, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { ICreateContributedTerminalProfileOptions, IProcessReadyEvent, IShellLaunchConfigDto, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, TerminalIcon, TerminalLocation, TerminalProperty, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
import { ThemeColor } from 'vs/platform/theme/common/themeService';
import { withNullAsUndefined } from 'vs/base/common/types';
......@@ -250,6 +250,8 @@ export class ExtHostPseudoterminal implements ITerminalChildProcess {
public get onProcessOverrideDimensions(): Event<ITerminalDimensionsOverride | undefined> { return this._onProcessOverrideDimensions.event; }
private readonly _onProcessShellTypeChanged = new Emitter<TerminalShellType>();
public readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
private readonly _onDidChangeProperty = new Emitter<TerminalProperty>();
public readonly onDidChangeProperty = this._onDidChangeProperty.event;
constructor(private readonly _pty: vscode.Pseudoterminal) { }
......
......@@ -8,13 +8,14 @@ import { Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { ILogService } from 'vs/platform/log/common/log';
import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalProperty, TerminalPropertyType, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/terminalProcess';
import { RemoteTerminalChannelClient } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
export class RemotePty extends Disposable implements ITerminalChildProcess {
initialCwd: string | undefined = undefined;
cwd: string | undefined = undefined;
private readonly _onProcessData = this._register(new Emitter<string | IProcessDataEvent>());
readonly onProcessData = this._onProcessData.event;
private readonly _onProcessExit = this._register(new Emitter<number | undefined>());
......@@ -31,6 +32,8 @@ export class RemotePty extends Disposable implements ITerminalChildProcess {
readonly onProcessResolvedShellLaunchConfig = this._onProcessResolvedShellLaunchConfig.event;
private readonly _onDidChangeHasChildProcesses = this._register(new Emitter<boolean>());
readonly onDidChangeHasChildProcesses = this._onDidChangeHasChildProcesses.event;
private readonly _onDidChangeProperty = this._register(new Emitter<TerminalProperty>());
readonly onDidChangeProperty = this._onDidChangeProperty.event;
private _startBarrier: Barrier;
......@@ -117,13 +120,21 @@ export class RemotePty extends Disposable implements ITerminalChildProcess {
}
async getInitialCwd(): Promise<string> {
await this._startBarrier.wait();
return this._remoteTerminalChannel.getInitialCwd(this._id);
if (!this.initialCwd) {
await this._startBarrier.wait();
this.initialCwd = await this._remoteTerminalChannel.getInitialCwd(this._id);
}
return this.initialCwd;
}
async getCwd(): Promise<string> {
await this._startBarrier.wait();
return this._remoteTerminalChannel.getCwd(this._id);
const cwd = await this._remoteTerminalChannel.getCwd(this._id);
if (this.cwd !== cwd) {
this.cwd = cwd;
this.handleDidChangeProperty({ type: TerminalPropertyType.cwd, value: this.cwd });
}
return this.cwd;
}
handleData(e: string | IProcessDataEvent) {
......@@ -157,6 +168,9 @@ export class RemotePty extends Disposable implements ITerminalChildProcess {
handleDidChangeHasChildProcesses(e: boolean) {
this._onDidChangeHasChildProcesses.fire(e);
}
handleDidChangeProperty(e: TerminalProperty) {
this._onDidChangeProperty.fire(e);
}
async handleReplay(e: IPtyHostProcessReplayEvent) {
try {
......
......@@ -79,6 +79,7 @@ export class RemoteTerminalService extends Disposable implements IRemoteTerminal
channel.onProcessOrphanQuestion(e => this._ptys.get(e.id)?.handleOrphanQuestion());
channel.onDidRequestDetach(e => this._onDidRequestDetach.fire(e));
channel.onProcessDidChangeHasChildProcesses(e => this._ptys.get(e.id)?.handleDidChangeHasChildProcesses(e.event));
channel.onDidChangeProperty(e => this._ptys.get(e.id)?.handleDidChangeProperty(e.event));
const allowedCommands = ['_remoteCLI.openExternal', '_remoteCLI.windowOpen', '_remoteCLI.getSystemStatus', '_remoteCLI.manageExtensions'];
channel.onExecuteCommand(async e => {
......
......@@ -46,7 +46,7 @@ import { TypeAheadAddon } from 'vs/workbench/contrib/terminal/browser/terminalTy
import { BrowserFeatures } from 'vs/base/browser/canIUse';
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType, TerminalSettingId, TitleEventSource, TerminalIcon, TerminalSettingPrefix, ITerminalProfileObject, TerminalLocation } from 'vs/platform/terminal/common/terminal';
import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType, TerminalSettingId, TitleEventSource, TerminalIcon, TerminalSettingPrefix, ITerminalProfileObject, TerminalLocation, TerminalPropertyType } from 'vs/platform/terminal/common/terminal';
import { IProductService } from 'vs/platform/product/common/productService';
import { formatMessageForTerminal } from 'vs/workbench/contrib/terminal/common/terminalStrings';
import { AutoOpenBarrier } from 'vs/base/common/async';
......@@ -137,6 +137,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
private _terminalA11yTreeFocusContextKey: IContextKey<boolean>;
private _cols: number = 0;
private _rows: number = 0;
private _cwd: string | undefined = undefined;
private _initialCwd: string | undefined = undefined;
private _dimensionsOverride: ITerminalDimensionsOverride | undefined;
private _xtermReadyPromise: Promise<XTermTerminal>;
private _titleReadyPromise: Promise<string>;
......@@ -1151,10 +1153,18 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
protected _createProcessManager(): void {
this._processManager = this._instantiationService.createInstance(TerminalProcessManager, this._instanceId, this._configHelper);
this._processManager.onProcessReady(() => {
this._processManager.onProcessReady(async () => {
this._onProcessIdReady.fire(this);
this._initialCwd = await this.getInitialCwd();
// Set the initial name based on the _resolved_ shell launch config, this will also
// ensure the resolved icon gets shown
this._processManager.onDidChangeProperty(e => {
if (e.type === TerminalPropertyType.cwd || e.type === TerminalPropertyType.initialCwd) {
this._cwd = e.value;
this.setTitle(this.title, TitleEventSource.Api);
}
});
if (this._shellLaunchConfig.name) {
this.setTitle(this._shellLaunchConfig.name, TitleEventSource.Api);
} else {
......@@ -1492,10 +1502,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
// reset cwd if it has changed, so file based url paths can be resolved
const cwd = await this.getCwd();
if (cwd && this._linkManager) {
if (this._linkManager.processCwd !== cwd) {
this._linkManager.processCwd = cwd;
this.setTitle(this.title, TitleEventSource.Api);
}
this._linkManager.processCwd = cwd;
}
return cwd;
}
......@@ -1781,33 +1788,32 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
// Remove special characters that could mess with rendering
title = title.replace(/[\n\r\t]/g, '');
this?.getCwd().then(cwd => {
const properties = {
cwd,
cwdFolder: path.basename(cwd),
local: this.shellLaunchConfig.description === 'Local' ? 'Local' : undefined,
process: this._processName || title,
sequence: this._sequence,
task: this.shellLaunchConfig.description === 'Task' ? 'Task' : undefined,
separator: { label: this._configHelper.config.tabs.separator }
};
title = template(this._configHelper.config.tabs.title, properties);
const description = template(this._configHelper.config.tabs.description, properties);
const titleChanged = title !== this._title || description !== this.description || eventSource === TitleEventSource.Config;
if (!title || !titleChanged) {
return;
}
this._title = title;
this._description = description;
this._titleSource = eventSource;
this._setAriaLabel(this._xterm, this._instanceId, this._title);
if (this._titleReadyComplete) {
this._titleReadyComplete(title);
this._titleReadyComplete = undefined;
}
this._onTitleChanged.fire(this);
});
const cwd = this._cwd || this._initialCwd || '';
const properties = {
cwd,
cwdFolder: path.basename(cwd),
local: this.shellLaunchConfig.description === 'Local' ? 'Local' : undefined,
process: this._processName || title,
sequence: this._sequence,
task: this.shellLaunchConfig.description === 'Task' ? 'Task' : undefined,
separator: { label: this._configHelper.config.tabs.separator }
};
title = template(this._configHelper.config.tabs.title, properties);
const description = template(this._configHelper.config.tabs.description, properties);
const titleChanged = title !== this._title || description !== this.description || eventSource === TitleEventSource.Config;
if (!title || !titleChanged) {
return;
}
this._title = title;
this._description = description;
this._titleSource = eventSource;
this._setAriaLabel(this._xterm, this._instanceId, this._title);
if (this._titleReadyComplete) {
this._titleReadyComplete(title);
this._titleReadyComplete = undefined;
}
this._onTitleChanged.fire(this);
}
waitForTitle(): Promise<string> {
......@@ -1946,8 +1952,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
xterm.setOption('logLevel', isDebug ? 'info' : 'debug');
}
getInitialCwd(): Promise<string> {
return this._processManager.getInitialCwd();
async getInitialCwd(): Promise<string> {
if (!this._initialCwd) {
this._initialCwd = await this._processManager.getInitialCwd();
}
return this._initialCwd;
}
getCwd(): Promise<string> {
......
......@@ -5,7 +5,7 @@
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalProperty, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal';
......@@ -46,6 +46,8 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal
readonly onRequestLatency: Event<void> = this._onRequestLatency.event;
private readonly _onProcessShellTypeChanged = this._register(new Emitter<TerminalShellType>());
readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
private readonly _onDidChangeProperty = this._register(new Emitter<TerminalProperty>());
readonly onDidChangeProperty = this._onDidChangeProperty.event;
private _pendingInitialCwdRequests: ((value: string | PromiseLike<string>) => void)[] = [];
......
......@@ -22,7 +22,7 @@ import { withNullAsUndefined } from 'vs/base/common/types';
import { EnvironmentVariableInfoChangesActive, EnvironmentVariableInfoStale } from 'vs/workbench/contrib/terminal/browser/environmentVariableInfo';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { IEnvironmentVariableInfo, IEnvironmentVariableService, IMergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { IProcessDataEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalEnvironment, ITerminalLaunchError, FlowControlConstants, TerminalShellType, ITerminalDimensions, TerminalSettingId, IProcessReadyEvent } from 'vs/platform/terminal/common/terminal';
import { IProcessDataEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalEnvironment, ITerminalLaunchError, FlowControlConstants, TerminalShellType, ITerminalDimensions, TerminalSettingId, IProcessReadyEvent, TerminalProperty } from 'vs/platform/terminal/common/terminal';
import { TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder';
import { localize } from 'vs/nls';
import { formatMessageForTerminal } from 'vs/workbench/contrib/terminal/common/terminalStrings';
......@@ -96,6 +96,8 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
readonly onProcessData = this._onProcessData.event;
private readonly _onProcessTitle = this._register(new Emitter<string>());
readonly onProcessTitle = this._onProcessTitle.event;
private readonly _onDidChangeProperty = this._register(new Emitter<TerminalProperty>());
readonly onDidChangeProperty = this._onDidChangeProperty.event;
private readonly _onProcessShellTypeChanged = this._register(new Emitter<TerminalShellType>());
readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
private readonly _onProcessExit = this._register(new Emitter<number | undefined>());
......@@ -323,7 +325,8 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
}),
newProcess.onProcessTitleChanged(title => this._onProcessTitle.fire(title)),
newProcess.onProcessShellTypeChanged(type => this._onProcessShellTypeChanged.fire(type)),
newProcess.onProcessExit(exitCode => this._onExit(exitCode))
newProcess.onProcessExit(exitCode => this._onExit(exitCode)),
newProcess.onDidChangeProperty(property => this._onDidChangeProperty.fire(property))
];
if (newProcess.onProcessOverrideDimensions) {
this._processListeners.push(newProcess.onProcessOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e)));
......
......@@ -18,7 +18,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { Schemas } from 'vs/base/common/network';
import { ILabelService } from 'vs/platform/label/common/label';
import { IEnvironmentVariableService, ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { IProcessDataEvent, IRequestResolveVariablesEvent, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensionsOverride, ITerminalEnvironment, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IProcessDataEvent, IRequestResolveVariablesEvent, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensionsOverride, ITerminalEnvironment, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, TerminalProperty, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
......@@ -124,6 +124,9 @@ export class RemoteTerminalChannelClient {
get onDidRequestDetach(): Event<{ requestId: number, workspaceId: string, instanceId: number }> {
return this._channel.listen<{ requestId: number, workspaceId: string, instanceId: number }>('$onDidRequestDetach');
}
get onDidChangeProperty(): Event<{ id: number, event: TerminalProperty }> {
return this._channel.listen<{ id: number, event: TerminalProperty }>('$onDidChangeProperty');
}
constructor(
private readonly _remoteAuthority: string,
......
......@@ -8,7 +8,7 @@ import { Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
import { IExtensionPointDescriptor } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, TerminalLocationString, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal';
import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, TerminalLocationString, TerminalProperty, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal';
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { URI } from 'vs/base/common/uri';
......@@ -291,6 +291,7 @@ export interface ITerminalProcessManager extends IDisposable {
readonly onBeforeProcessData: Event<IBeforeProcessDataEvent>;
readonly onProcessData: Event<IProcessDataEvent>;
readonly onProcessTitle: Event<string>;
readonly onDidChangeProperty: Event<TerminalProperty>;
readonly onProcessShellTypeChanged: Event<TerminalShellType>;
readonly onProcessExit: Event<number | undefined>;
readonly onProcessOverrideDimensions: Event<ITerminalDimensionsOverride | undefined>;
......
......@@ -6,7 +6,7 @@
import { Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal';
import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalProperty, TerminalPropertyType, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/terminalProcess';
/**
......@@ -15,7 +15,8 @@ import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/terminal
*/
export class LocalPty extends Disposable implements ITerminalChildProcess {
private _inReplay = false;
initialCwd: string | undefined = undefined;
cwd: string | undefined = undefined;
private readonly _onProcessData = this._register(new Emitter<IProcessDataEvent | string>());
readonly onProcessData = this._onProcessData.event;
private readonly _onProcessReplay = this._register(new Emitter<IPtyHostProcessReplayEvent>());
......@@ -34,6 +35,8 @@ export class LocalPty extends Disposable implements ITerminalChildProcess {
readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
private readonly _onDidChangeHasChildProcesses = this._register(new Emitter<boolean>());
readonly onDidChangeHasChildProcesses = this._onDidChangeHasChildProcesses.event;
private readonly _onDidChangeProperty = this._register(new Emitter<TerminalProperty>());
readonly onDidChangeProperty = this._onDidChangeProperty.event;
constructor(
readonly id: number,
......@@ -70,11 +73,19 @@ export class LocalPty extends Disposable implements ITerminalChildProcess {
}
this._localPtyService.resize(this.id, cols, rows);
}
getInitialCwd(): Promise<string> {
return this._localPtyService.getInitialCwd(this.id);
async getInitialCwd(): Promise<string> {
if (!this.initialCwd) {
this.initialCwd = await this._localPtyService.getInitialCwd(this.id);
}
return this.initialCwd;
}
getCwd(): Promise<string> {
return this._localPtyService.getCwd(this.id);
async getCwd(): Promise<string> {
const cwd = await this._localPtyService.getCwd(this.id);
if (this.cwd !== cwd) {
this.cwd = cwd;
this.handleDidChangeProperty({ type: TerminalPropertyType.cwd, value: this.cwd });
}
return this.cwd;
}
getLatency(): Promise<number> {
// TODO: The idea here was to add the result plus the time it took to get the latency
......@@ -114,6 +125,9 @@ export class LocalPty extends Disposable implements ITerminalChildProcess {
handleDidChangeHasChildProcesses(e: boolean) {
this._onDidChangeHasChildProcesses.fire(e);
}
handleDidChangeProperty(e: TerminalProperty) {
this._onDidChangeProperty.fire(e);
}
async handleReplay(e: IPtyHostProcessReplayEvent) {
try {
......
......@@ -66,6 +66,7 @@ export class LocalTerminalService extends Disposable implements ILocalTerminalSe
this._localPtyService.onProcessOverrideDimensions(e => this._ptys.get(e.id)?.handleOverrideDimensions(e.event));
this._localPtyService.onProcessResolvedShellLaunchConfig(e => this._ptys.get(e.id)?.handleResolvedShellLaunchConfig(e.event));
this._localPtyService.onProcessDidChangeHasChildProcesses(e => this._ptys.get(e.id)?.handleDidChangeHasChildProcesses(e.event));
this._localPtyService.onDidChangeProperty(e => this._ptys.get(e.id)?.handleDidChangeProperty(e.event));
this._localPtyService.onProcessReplay(e => this._ptys.get(e.id)?.handleReplay(e.event));
this._localPtyService.onProcessOrphanQuestion(e => this._ptys.get(e.id)?.handleOrphanQuestion());
this._localPtyService.onDidRequestDetach(e => this._onDidRequestDetach.fire(e));
......
......@@ -4,13 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import { DeferredPromise } from 'vs/base/common/async';
import { Emitter } from 'vs/base/common/event';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { listenStream } from 'vs/base/common/stream';
import { isDefined } from 'vs/base/common/types';
import { localize } from 'vs/nls';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IProcessDataEvent, ITerminalChildProcess, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IProcessDataEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IViewsService } from 'vs/workbench/common/views';
import { ITerminalGroupService, ITerminalInstance, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
......@@ -147,6 +147,10 @@ export class TestingOutputTerminalService implements ITestingOutputTerminalServi
}
class TestOutputProcess extends Disposable implements ITerminalChildProcess {
onProcessOverrideDimensions?: Event<ITerminalDimensionsOverride | undefined> | undefined;
onProcessResolvedShellLaunchConfig?: Event<IShellLaunchConfig> | undefined;
onDidChangeHasChildProcesses?: Event<boolean> | undefined;
onDidChangeProperty = Event.None;
private processDataEmitter = this._register(new Emitter<string | IProcessDataEvent>());
private titleEmitter = this._register(new Emitter<string>());
private readonly startedDeferred = new DeferredPromise<void>();
......
......@@ -126,7 +126,7 @@ import { SideBySideEditor } from 'vs/workbench/browser/parts/editor/sideBySideEd
import { IEnterWorkspaceResult, IRecent, IRecentlyOpened, IWorkspaceFolderCreationData, IWorkspaceIdentifier, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceTrustManagementService, IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/workspaceTrust';
import { TestWorkspaceTrustManagementService, TestWorkspaceTrustRequestService } from 'vs/workbench/services/workspaces/test/common/testWorkspaceTrustService';
import { IShellLaunchConfig, ITerminalChildProcess, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IProcessDetails, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
import { ICreateTerminalOptions, ITerminalInstance, ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { isArray } from 'vs/base/common/types';
......@@ -1705,7 +1705,11 @@ class TestTerminalChildProcess implements ITerminalChildProcess {
readonly shouldPersist: boolean
) {
}
onProcessOverrideDimensions?: Event<ITerminalDimensionsOverride | undefined> | undefined;
onProcessResolvedShellLaunchConfig?: Event<IShellLaunchConfig> | undefined;
onDidChangeHasChildProcesses?: Event<boolean> | undefined;
onDidChangeProperty = Event.None;
onProcessData = Event.None;
onProcessExit = Event.None;
onProcessReady = Event.None;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册