mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 09:08:48 +01:00
update shellType when it changes for local windows terminals (#117998)
Co-authored-by: Daniel Imms <daimms@microsoft.com>
This commit is contained in:
@@ -9,6 +9,13 @@ import { IProcessEnvironment } from 'vs/base/common/platform';
|
|||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { IGetTerminalLayoutInfoArgs, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
|
import { IGetTerminalLayoutInfoArgs, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
|
||||||
|
|
||||||
|
export enum WindowsShellType {
|
||||||
|
CommandPrompt = 'cmd',
|
||||||
|
PowerShell = 'pwsh',
|
||||||
|
Wsl = 'wsl',
|
||||||
|
GitBash = 'gitbash'
|
||||||
|
}
|
||||||
|
export type TerminalShellType = WindowsShellType | undefined;
|
||||||
export interface IRawTerminalInstanceLayoutInfo<T> {
|
export interface IRawTerminalInstanceLayoutInfo<T> {
|
||||||
relativeSize: number;
|
relativeSize: number;
|
||||||
terminal: T;
|
terminal: T;
|
||||||
@@ -109,6 +116,7 @@ export interface IPtyService {
|
|||||||
readonly onProcessExit: Event<{ id: number, event: number | undefined }>;
|
readonly onProcessExit: Event<{ id: number, event: number | undefined }>;
|
||||||
readonly onProcessReady: Event<{ id: number, event: { pid: number, cwd: string } }>;
|
readonly onProcessReady: Event<{ id: number, event: { pid: number, cwd: string } }>;
|
||||||
readonly onProcessTitleChanged: Event<{ id: number, event: string }>;
|
readonly onProcessTitleChanged: Event<{ id: number, event: string }>;
|
||||||
|
readonly onProcessShellTypeChanged: Event<{ id: number, event: TerminalShellType }>;
|
||||||
readonly onProcessOverrideDimensions: Event<{ id: number, event: ITerminalDimensionsOverride | undefined }>;
|
readonly onProcessOverrideDimensions: Event<{ id: number, event: ITerminalDimensionsOverride | undefined }>;
|
||||||
readonly onProcessResolvedShellLaunchConfig: Event<{ id: number, event: IShellLaunchConfig }>;
|
readonly onProcessResolvedShellLaunchConfig: Event<{ id: number, event: IShellLaunchConfig }>;
|
||||||
readonly onProcessReplay: Event<{ id: number, event: IPtyHostProcessReplayEvent }>;
|
readonly onProcessReplay: Event<{ id: number, event: IPtyHostProcessReplayEvent }>;
|
||||||
@@ -296,6 +304,7 @@ export interface ITerminalChildProcess {
|
|||||||
onProcessTitleChanged: Event<string>;
|
onProcessTitleChanged: Event<string>;
|
||||||
onProcessOverrideDimensions?: Event<ITerminalDimensionsOverride | undefined>;
|
onProcessOverrideDimensions?: Event<ITerminalDimensionsOverride | undefined>;
|
||||||
onProcessResolvedShellLaunchConfig?: Event<IShellLaunchConfig>;
|
onProcessResolvedShellLaunchConfig?: Event<IShellLaunchConfig>;
|
||||||
|
onProcessShellTypeChanged: Event<TerminalShellType>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the process.
|
* Starts the process.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalsLayoutInfo, TerminalIpcChannels, IHeartbeatService, HeartbeatConstants } from 'vs/platform/terminal/common/terminal';
|
import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalsLayoutInfo, TerminalIpcChannels, IHeartbeatService, HeartbeatConstants, TerminalShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
import { Client } from 'vs/base/parts/ipc/node/ipc.cp';
|
import { Client } from 'vs/base/parts/ipc/node/ipc.cp';
|
||||||
import { FileAccess } from 'vs/base/common/network';
|
import { FileAccess } from 'vs/base/common/network';
|
||||||
import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
|
import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||||
@@ -56,6 +56,8 @@ export class LocalPtyService extends Disposable implements IPtyService {
|
|||||||
readonly onProcessReplay = this._onProcessReplay.event;
|
readonly onProcessReplay = this._onProcessReplay.event;
|
||||||
private readonly _onProcessTitleChanged = this._register(new Emitter<{ id: number, event: string }>());
|
private readonly _onProcessTitleChanged = this._register(new Emitter<{ id: number, event: string }>());
|
||||||
readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
|
readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
|
||||||
|
private readonly _onProcessShellTypeChanged = this._register(new Emitter<{ id: number, event: TerminalShellType }>());
|
||||||
|
readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
|
||||||
private readonly _onProcessOverrideDimensions = this._register(new Emitter<{ id: number, event: ITerminalDimensionsOverride | undefined }>());
|
private readonly _onProcessOverrideDimensions = this._register(new Emitter<{ id: number, event: ITerminalDimensionsOverride | undefined }>());
|
||||||
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
|
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
|
||||||
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<{ id: number, event: IShellLaunchConfig }>());
|
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<{ id: number, event: IShellLaunchConfig }>());
|
||||||
@@ -116,6 +118,7 @@ export class LocalPtyService extends Disposable implements IPtyService {
|
|||||||
this._register(proxy.onProcessExit(e => this._onProcessExit.fire(e)));
|
this._register(proxy.onProcessExit(e => this._onProcessExit.fire(e)));
|
||||||
this._register(proxy.onProcessReady(e => this._onProcessReady.fire(e)));
|
this._register(proxy.onProcessReady(e => this._onProcessReady.fire(e)));
|
||||||
this._register(proxy.onProcessTitleChanged(e => this._onProcessTitleChanged.fire(e)));
|
this._register(proxy.onProcessTitleChanged(e => this._onProcessTitleChanged.fire(e)));
|
||||||
|
this._register(proxy.onProcessShellTypeChanged(e => this._onProcessShellTypeChanged.fire(e)));
|
||||||
this._register(proxy.onProcessOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e)));
|
this._register(proxy.onProcessOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e)));
|
||||||
this._register(proxy.onProcessResolvedShellLaunchConfig(e => this._onProcessResolvedShellLaunchConfig.fire(e)));
|
this._register(proxy.onProcessResolvedShellLaunchConfig(e => this._onProcessResolvedShellLaunchConfig.fire(e)));
|
||||||
this._register(proxy.onProcessReplay(e => this._onProcessReplay.fire(e)));
|
this._register(proxy.onProcessReplay(e => this._onProcessReplay.fire(e)));
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||||
import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, LocalReconnectConstants, ITerminalsLayoutInfo, IRawTerminalInstanceLayoutInfo, ITerminalTabLayoutInfoById, ITerminalInstanceLayoutInfoById } from 'vs/platform/terminal/common/terminal';
|
import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, LocalReconnectConstants, ITerminalsLayoutInfo, IRawTerminalInstanceLayoutInfo, ITerminalTabLayoutInfoById, ITerminalInstanceLayoutInfoById, TerminalShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
import { AutoOpenBarrier, Queue, RunOnceScheduler } from 'vs/base/common/async';
|
import { AutoOpenBarrier, Queue, RunOnceScheduler } from 'vs/base/common/async';
|
||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
import { TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder';
|
import { TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder';
|
||||||
@@ -34,6 +34,8 @@ export class PtyService extends Disposable implements IPtyService {
|
|||||||
readonly onProcessReady = this._onProcessReady.event;
|
readonly onProcessReady = this._onProcessReady.event;
|
||||||
private readonly _onProcessTitleChanged = this._register(new Emitter<{ id: number, event: string }>());
|
private readonly _onProcessTitleChanged = this._register(new Emitter<{ id: number, event: string }>());
|
||||||
readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
|
readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
|
||||||
|
private readonly _onProcessShellTypeChanged = this._register(new Emitter<{ id: number, event: TerminalShellType }>());
|
||||||
|
readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
|
||||||
private readonly _onProcessOverrideDimensions = this._register(new Emitter<{ id: number, event: ITerminalDimensionsOverride | undefined }>());
|
private readonly _onProcessOverrideDimensions = this._register(new Emitter<{ id: number, event: ITerminalDimensionsOverride | undefined }>());
|
||||||
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
|
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
|
||||||
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<{ id: number, event: IShellLaunchConfig }>());
|
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<{ id: number, event: IShellLaunchConfig }>());
|
||||||
@@ -90,6 +92,7 @@ export class PtyService extends Disposable implements IPtyService {
|
|||||||
persistentProcess.onProcessReplay(event => this._onProcessReplay.fire({ id, event }));
|
persistentProcess.onProcessReplay(event => this._onProcessReplay.fire({ id, event }));
|
||||||
persistentProcess.onProcessReady(event => this._onProcessReady.fire({ id, event }));
|
persistentProcess.onProcessReady(event => this._onProcessReady.fire({ id, event }));
|
||||||
persistentProcess.onProcessTitleChanged(event => this._onProcessTitleChanged.fire({ id, event }));
|
persistentProcess.onProcessTitleChanged(event => this._onProcessTitleChanged.fire({ id, event }));
|
||||||
|
persistentProcess.onProcessShellTypeChanged(event => this._onProcessShellTypeChanged.fire({ id, event }));
|
||||||
this._ptys.set(id, persistentProcess);
|
this._ptys.set(id, persistentProcess);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -219,6 +222,8 @@ export class PersistentTerminalProcess extends Disposable {
|
|||||||
readonly onProcessReady = this._onProcessReady.event;
|
readonly onProcessReady = this._onProcessReady.event;
|
||||||
private readonly _onProcessTitleChanged = this._register(new Emitter<string>());
|
private readonly _onProcessTitleChanged = this._register(new Emitter<string>());
|
||||||
readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
|
readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
|
||||||
|
private readonly _onProcessShellTypeChanged = this._register(new Emitter<TerminalShellType>());
|
||||||
|
readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
|
||||||
private readonly _onProcessOverrideDimensions = this._register(new Emitter<ITerminalDimensionsOverride | undefined>());
|
private readonly _onProcessOverrideDimensions = this._register(new Emitter<ITerminalDimensionsOverride | undefined>());
|
||||||
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
|
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
|
||||||
private readonly _onProcessData = this._register(new Emitter<IProcessDataEvent>());
|
private readonly _onProcessData = this._register(new Emitter<IProcessDataEvent>());
|
||||||
@@ -269,7 +274,7 @@ export class PersistentTerminalProcess extends Disposable {
|
|||||||
this._onProcessReady.fire(e);
|
this._onProcessReady.fire(e);
|
||||||
}));
|
}));
|
||||||
this._register(this._terminalProcess.onProcessTitleChanged(e => this._onProcessTitleChanged.fire(e)));
|
this._register(this._terminalProcess.onProcessTitleChanged(e => this._onProcessTitleChanged.fire(e)));
|
||||||
|
this._register(this._terminalProcess.onProcessShellTypeChanged(e => this._onProcessShellTypeChanged.fire(e)));
|
||||||
// Buffer data events to reduce the amount of messages going to the renderer
|
// Buffer data events to reduce the amount of messages going to the renderer
|
||||||
// this._register(this._bufferer.startBuffering(this._persistentProcessId, this._terminalProcess.onProcessData));
|
// this._register(this._bufferer.startBuffering(this._persistentProcessId, this._terminalProcess.onProcessData));
|
||||||
this._register(this._terminalProcess.onProcessData(e => this._recorder.recordData(e)));
|
this._register(this._terminalProcess.onProcessData(e => this._recorder.recordData(e)));
|
||||||
@@ -301,6 +306,7 @@ export class PersistentTerminalProcess extends Disposable {
|
|||||||
} else {
|
} else {
|
||||||
this._onProcessReady.fire({ pid: this._pid, cwd: this._cwd });
|
this._onProcessReady.fire({ pid: this._pid, cwd: this._cwd });
|
||||||
this._onProcessTitleChanged.fire(this._terminalProcess.currentTitle);
|
this._onProcessTitleChanged.fire(this._terminalProcess.currentTitle);
|
||||||
|
this._onProcessShellTypeChanged.fire(this._terminalProcess.shellType);
|
||||||
this.triggerReplay();
|
this.triggerReplay();
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -10,12 +10,13 @@ import * as fs from 'fs';
|
|||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { IShellLaunchConfig, ITerminalLaunchError, FlowControlConstants, ITerminalChildProcess, ITerminalDimensionsOverride } from 'vs/platform/terminal/common/terminal';
|
import { IShellLaunchConfig, ITerminalLaunchError, FlowControlConstants, ITerminalChildProcess, ITerminalDimensionsOverride, TerminalShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
import { exec } from 'child_process';
|
import { exec } from 'child_process';
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { findExecutable, getWindowsBuildNumber } from 'vs/platform/terminal/node/terminalEnvironment';
|
import { findExecutable, getWindowsBuildNumber } from 'vs/platform/terminal/node/terminalEnvironment';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
|
import { WindowsShellHelper } from 'vs/platform/terminal/node/windowsShellHelper';
|
||||||
|
|
||||||
// Writing large amounts of data can be corrupted for some reason, after looking into this is
|
// Writing large amounts of data can be corrupted for some reason, after looking into this is
|
||||||
// appears to be a race condition around writing to the FD which may be based on how powerful the
|
// appears to be a race condition around writing to the FD which may be based on how powerful the
|
||||||
@@ -54,6 +55,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||||||
private _currentTitle: string = '';
|
private _currentTitle: string = '';
|
||||||
private _processStartupComplete: Promise<void> | undefined;
|
private _processStartupComplete: Promise<void> | undefined;
|
||||||
private _isDisposed: boolean = false;
|
private _isDisposed: boolean = false;
|
||||||
|
private _windowsShellHelper: WindowsShellHelper | undefined;
|
||||||
private _titleInterval: NodeJS.Timer | null = null;
|
private _titleInterval: NodeJS.Timer | null = null;
|
||||||
private _writeQueue: string[] = [];
|
private _writeQueue: string[] = [];
|
||||||
private _writeTimeout: NodeJS.Timeout | undefined;
|
private _writeTimeout: NodeJS.Timeout | undefined;
|
||||||
@@ -63,9 +65,10 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||||||
|
|
||||||
private _isPtyPaused: boolean = false;
|
private _isPtyPaused: boolean = false;
|
||||||
private _unacknowledgedCharCount: number = 0;
|
private _unacknowledgedCharCount: number = 0;
|
||||||
|
|
||||||
public get exitMessage(): string | undefined { return this._exitMessage; }
|
public get exitMessage(): string | undefined { return this._exitMessage; }
|
||||||
public get currentTitle(): string { return this._currentTitle; }
|
|
||||||
|
public get currentTitle(): string { return this._windowsShellHelper?.shellTitle || this._currentTitle; }
|
||||||
|
public get shellType(): TerminalShellType { return this._windowsShellHelper ? this._windowsShellHelper.shellType : undefined; }
|
||||||
|
|
||||||
private readonly _onProcessData = this._register(new Emitter<string>());
|
private readonly _onProcessData = this._register(new Emitter<string>());
|
||||||
public get onProcessData(): Event<string> { return this._onProcessData.event; }
|
public get onProcessData(): Event<string> { return this._onProcessData.event; }
|
||||||
@@ -75,6 +78,8 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||||||
public get onProcessReady(): Event<{ pid: number, cwd: string }> { return this._onProcessReady.event; }
|
public get onProcessReady(): Event<{ pid: number, cwd: string }> { return this._onProcessReady.event; }
|
||||||
private readonly _onProcessTitleChanged = this._register(new Emitter<string>());
|
private readonly _onProcessTitleChanged = this._register(new Emitter<string>());
|
||||||
public get onProcessTitleChanged(): Event<string> { return this._onProcessTitleChanged.event; }
|
public get onProcessTitleChanged(): Event<string> { return this._onProcessTitleChanged.event; }
|
||||||
|
private readonly _onProcessShellTypeChanged = this._register(new Emitter<TerminalShellType>());
|
||||||
|
public readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _shellLaunchConfig: IShellLaunchConfig,
|
private readonly _shellLaunchConfig: IShellLaunchConfig,
|
||||||
@@ -111,15 +116,23 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||||||
conptyInheritCursor: useConpty && !!_shellLaunchConfig.initialText
|
conptyInheritCursor: useConpty && !!_shellLaunchConfig.initialText
|
||||||
};
|
};
|
||||||
// Delay resizes to avoid conpty not respecting very early resize calls
|
// Delay resizes to avoid conpty not respecting very early resize calls
|
||||||
if (platform.isWindows && useConpty && cols === 0 && rows === 0 && this._shellLaunchConfig.executable?.endsWith('Git\\bin\\bash.exe')) {
|
if (platform.isWindows) {
|
||||||
this._delayedResizer = new DelayedResizer();
|
if (useConpty && cols === 0 && rows === 0 && this._shellLaunchConfig.executable?.endsWith('Git\\bin\\bash.exe')) {
|
||||||
this._register(this._delayedResizer.onTrigger(dimensions => {
|
this._delayedResizer = new DelayedResizer();
|
||||||
this._delayedResizer?.dispose();
|
this._register(this._delayedResizer.onTrigger(dimensions => {
|
||||||
this._delayedResizer = undefined;
|
this._delayedResizer?.dispose();
|
||||||
if (dimensions.cols && dimensions.rows) {
|
this._delayedResizer = undefined;
|
||||||
this.resize(dimensions.cols, dimensions.rows);
|
if (dimensions.cols && dimensions.rows) {
|
||||||
}
|
this.resize(dimensions.cols, dimensions.rows);
|
||||||
}));
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
// WindowsShellHelper is used to fetch the process title and shell type
|
||||||
|
this.onProcessReady(e => {
|
||||||
|
this._windowsShellHelper = this._register(new WindowsShellHelper(e.pid));
|
||||||
|
this._register(this._windowsShellHelper.onShellTypeChanged(e => this._onProcessShellTypeChanged.fire(e)));
|
||||||
|
this._register(this._windowsShellHelper.onShellNameChanged(e => this._onProcessTitleChanged.fire(e)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onProcessOverrideDimensions?: Event<ITerminalDimensionsOverride | undefined> | undefined;
|
onProcessOverrideDimensions?: Event<ITerminalDimensionsOverride | undefined> | undefined;
|
||||||
@@ -196,12 +209,14 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||||||
ptyProcess.pause();
|
ptyProcess.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Refire the data event
|
// Refire the data event
|
||||||
this._onProcessData.fire(data);
|
this._onProcessData.fire(data);
|
||||||
if (this._closeTimeout) {
|
if (this._closeTimeout) {
|
||||||
clearTimeout(this._closeTimeout);
|
clearTimeout(this._closeTimeout);
|
||||||
this._queueProcessExit();
|
this._queueProcessExit();
|
||||||
}
|
}
|
||||||
|
this._windowsShellHelper?.checkShell();
|
||||||
});
|
});
|
||||||
ptyProcess.onExit(e => {
|
ptyProcess.onExit(e => {
|
||||||
this._exitCode = e.exitCode;
|
this._exitCode = e.exitCode;
|
||||||
@@ -217,10 +232,6 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||||||
clearInterval(this._titleInterval);
|
clearInterval(this._titleInterval);
|
||||||
}
|
}
|
||||||
this._titleInterval = null;
|
this._titleInterval = null;
|
||||||
this._onProcessData.dispose();
|
|
||||||
this._onProcessExit.dispose();
|
|
||||||
this._onProcessReady.dispose();
|
|
||||||
this._onProcessTitleChanged.dispose();
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+58
-36
@@ -5,12 +5,19 @@
|
|||||||
|
|
||||||
import * as platform from 'vs/base/common/platform';
|
import * as platform from 'vs/base/common/platform';
|
||||||
import { Emitter, Event } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
import { IWindowsShellHelper } from 'vs/workbench/contrib/terminal/common/terminal';
|
|
||||||
import type { Terminal as XTermTerminal } from 'xterm';
|
|
||||||
import type * as WindowsProcessTreeType from 'windows-process-tree';
|
import type * as WindowsProcessTreeType from 'windows-process-tree';
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
|
import { TerminalShellType, WindowsShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
|
import { debounce } from 'vs/base/common/decorators';
|
||||||
import { timeout } from 'vs/base/common/async';
|
import { timeout } from 'vs/base/common/async';
|
||||||
|
|
||||||
|
export interface IWindowsShellHelper extends IDisposable {
|
||||||
|
readonly onShellNameChanged: Event<string>;
|
||||||
|
readonly onShellTypeChanged: Event<TerminalShellType>;
|
||||||
|
getShellType(title: string): TerminalShellType;
|
||||||
|
getShellName(): Promise<string>;
|
||||||
|
}
|
||||||
|
|
||||||
const SHELL_EXECUTABLES = [
|
const SHELL_EXECUTABLES = [
|
||||||
'cmd.exe',
|
'cmd.exe',
|
||||||
'powershell.exe',
|
'powershell.exe',
|
||||||
@@ -28,17 +35,19 @@ const SHELL_EXECUTABLES = [
|
|||||||
let windowsProcessTree: typeof WindowsProcessTreeType;
|
let windowsProcessTree: typeof WindowsProcessTreeType;
|
||||||
|
|
||||||
export class WindowsShellHelper extends Disposable implements IWindowsShellHelper {
|
export class WindowsShellHelper extends Disposable implements IWindowsShellHelper {
|
||||||
private _onCheckShell: Emitter<Promise<string> | undefined> = this._register(new Emitter<Promise<string> | undefined>());
|
|
||||||
private _isDisposed: boolean;
|
private _isDisposed: boolean;
|
||||||
private _currentRequest: Promise<string> | undefined;
|
private _currentRequest: Promise<string> | undefined;
|
||||||
private _newLineFeed: boolean = false;
|
private _shellType: TerminalShellType | undefined;
|
||||||
|
public get shellType(): TerminalShellType | undefined { return this._shellType; }
|
||||||
private readonly _onShellNameChange = new Emitter<string>();
|
private _shellTitle: string = '';
|
||||||
public get onShellNameChange(): Event<string> { return this._onShellNameChange.event; }
|
public get shellTitle(): string { return this._shellTitle; }
|
||||||
|
private readonly _onShellNameChanged = new Emitter<string>();
|
||||||
|
public get onShellNameChanged(): Event<string> { return this._onShellNameChanged.event; }
|
||||||
|
private readonly _onShellTypeChanged = new Emitter<TerminalShellType>();
|
||||||
|
public get onShellTypeChanged(): Event<TerminalShellType> { return this._onShellTypeChanged.event; }
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private _rootProcessId: number,
|
private _rootProcessId: number
|
||||||
private _xterm: XTermTerminal
|
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@@ -55,35 +64,25 @@ export class WindowsShellHelper extends Disposable implements IWindowsShellHelpe
|
|||||||
if (this._isDisposed) {
|
if (this._isDisposed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.checkShell();
|
||||||
// The debounce is necessary to prevent multiple processes from spawning when
|
|
||||||
// the enter key or output is spammed
|
|
||||||
Event.debounce(this._onCheckShell.event, (l, e) => e, 150, true)(async () => {
|
|
||||||
await timeout(50);
|
|
||||||
this.checkShell();
|
|
||||||
});
|
|
||||||
|
|
||||||
// We want to fire a new check for the shell on a linefeed, but only
|
|
||||||
// when parsing has finished which is indicated by the cursormove event.
|
|
||||||
// If this is done on every linefeed, parsing ends up taking
|
|
||||||
// significantly longer due to resetting timers. Note that this is
|
|
||||||
// private API.
|
|
||||||
this._xterm.onLineFeed(() => this._newLineFeed = true);
|
|
||||||
this._xterm.onCursorMove(() => {
|
|
||||||
if (this._newLineFeed) {
|
|
||||||
this._onCheckShell.fire(undefined);
|
|
||||||
this._newLineFeed = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fire a new check for the shell when any key is pressed.
|
|
||||||
this._xterm.onKey(() => this._onCheckShell.fire(undefined));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkShell(): void {
|
@debounce(500)
|
||||||
|
async checkShell(): Promise<void> {
|
||||||
if (platform.isWindows) {
|
if (platform.isWindows) {
|
||||||
// TODO: Only fire when it's different
|
// Wait to give the shell some time to actually launch a process, this
|
||||||
this.getShellName().then(title => this._onShellNameChange.fire(title));
|
// could lead to a race condition but it would be recovered from when
|
||||||
|
// data stops and should cover the majority of cases
|
||||||
|
await timeout(300);
|
||||||
|
this.getShellName().then(title => {
|
||||||
|
const type = this.getShellType(title);
|
||||||
|
if (type !== this._shellType) {
|
||||||
|
this._onShellTypeChanged.fire(type);
|
||||||
|
this._onShellNameChanged.fire(title);
|
||||||
|
this._shellType = type;
|
||||||
|
this._shellTitle = title;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,4 +140,27 @@ export class WindowsShellHelper extends Disposable implements IWindowsShellHelpe
|
|||||||
});
|
});
|
||||||
return this._currentRequest;
|
return this._currentRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getShellType(executable: string): TerminalShellType {
|
||||||
|
switch (executable.toLowerCase()) {
|
||||||
|
case 'cmd.exe':
|
||||||
|
return WindowsShellType.CommandPrompt;
|
||||||
|
case 'powershell.exe':
|
||||||
|
case 'pwsh.exe':
|
||||||
|
return WindowsShellType.PowerShell;
|
||||||
|
case 'bash.exe':
|
||||||
|
case 'git-cmd.exe':
|
||||||
|
return WindowsShellType.GitBash;
|
||||||
|
case 'wsl.exe':
|
||||||
|
case 'ubuntu.exe':
|
||||||
|
case 'ubuntu1804.exe':
|
||||||
|
case 'kali.exe':
|
||||||
|
case 'debian.exe':
|
||||||
|
case 'opensuse-42.exe':
|
||||||
|
case 'sles-12.exe':
|
||||||
|
return WindowsShellType.Wsl;
|
||||||
|
default:
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ import { serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/ter
|
|||||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||||
import { generateUuid } from 'vs/base/common/uuid';
|
import { generateUuid } from 'vs/base/common/uuid';
|
||||||
import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||||
import { ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError } from 'vs/platform/terminal/common/terminal';
|
import { ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
|
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
|
||||||
|
|
||||||
export interface IExtHostTerminalService extends ExtHostTerminalServiceShape, IDisposable {
|
export interface IExtHostTerminalService extends ExtHostTerminalServiceShape, IDisposable {
|
||||||
@@ -198,6 +198,9 @@ export class ExtHostPseudoterminal implements ITerminalChildProcess {
|
|||||||
public readonly onProcessTitleChanged: Event<string> = this._onProcessTitleChanged.event;
|
public readonly onProcessTitleChanged: Event<string> = this._onProcessTitleChanged.event;
|
||||||
private readonly _onProcessOverrideDimensions = new Emitter<ITerminalDimensionsOverride | undefined>();
|
private readonly _onProcessOverrideDimensions = new Emitter<ITerminalDimensionsOverride | undefined>();
|
||||||
public get onProcessOverrideDimensions(): Event<ITerminalDimensionsOverride | undefined> { return this._onProcessOverrideDimensions.event; }
|
public get onProcessOverrideDimensions(): Event<ITerminalDimensionsOverride | undefined> { return this._onProcessOverrideDimensions.event; }
|
||||||
|
private readonly _onProcessShellTypeChanged = new Emitter<TerminalShellType>();
|
||||||
|
public readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
|
||||||
|
|
||||||
|
|
||||||
constructor(private readonly _pty: vscode.Pseudoterminal) { }
|
constructor(private readonly _pty: vscode.Pseudoterminal) { }
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { IRemoteTerminalService, ITerminalInstanceService } from 'vs/workbench/c
|
|||||||
import { IRemoteTerminalProcessExecCommandEvent, IShellLaunchConfigDto, RemoteTerminalChannelClient, REMOTE_TERMINAL_CHANNEL_NAME } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel';
|
import { IRemoteTerminalProcessExecCommandEvent, IShellLaunchConfigDto, RemoteTerminalChannelClient, REMOTE_TERMINAL_CHANNEL_NAME } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel';
|
||||||
import { IRemoteTerminalAttachTarget, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { IRemoteTerminalAttachTarget, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||||
import { IProcessDataEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById } from 'vs/platform/terminal/common/terminal';
|
import { IProcessDataEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
|
|
||||||
export class RemoteTerminalService extends Disposable implements IRemoteTerminalService {
|
export class RemoteTerminalService extends Disposable implements IRemoteTerminalService {
|
||||||
public _serviceBrand: undefined;
|
public _serviceBrand: undefined;
|
||||||
@@ -101,6 +101,8 @@ export class RemoteTerminalProcess extends Disposable implements ITerminalChildP
|
|||||||
public readonly onProcessOverrideDimensions: Event<ITerminalDimensionsOverride | undefined> = this._onProcessOverrideDimensions.event;
|
public readonly onProcessOverrideDimensions: Event<ITerminalDimensionsOverride | undefined> = this._onProcessOverrideDimensions.event;
|
||||||
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<IShellLaunchConfig>());
|
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<IShellLaunchConfig>());
|
||||||
public get onProcessResolvedShellLaunchConfig(): Event<IShellLaunchConfig> { return this._onProcessResolvedShellLaunchConfig.event; }
|
public get onProcessResolvedShellLaunchConfig(): Event<IShellLaunchConfig> { return this._onProcessResolvedShellLaunchConfig.event; }
|
||||||
|
private readonly _onProcessShellTypeChanged = this._register(new Emitter<TerminalShellType | undefined>());
|
||||||
|
public readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
|
||||||
|
|
||||||
private _startBarrier: Barrier;
|
private _startBarrier: Barrier;
|
||||||
private _persistentProcessId: number;
|
private _persistentProcessId: number;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import { setupTerminalMenu } from 'vs/workbench/contrib/terminal/common/terminal
|
|||||||
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
|
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||||
import { TerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService';
|
import { TerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService';
|
||||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||||
import { IRemoteTerminalService, ITerminalService, WindowsShellType } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { IRemoteTerminalService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||||
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||||
import { IQuickAccessRegistry, Extensions as QuickAccessExtensions } from 'vs/platform/quickinput/common/quickAccess';
|
import { IQuickAccessRegistry, Extensions as QuickAccessExtensions } from 'vs/platform/quickinput/common/quickAccess';
|
||||||
@@ -36,6 +36,7 @@ import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/co
|
|||||||
import { terminalViewIcon } from 'vs/workbench/contrib/terminal/browser/terminalIcons';
|
import { terminalViewIcon } from 'vs/workbench/contrib/terminal/browser/terminalIcons';
|
||||||
import { RemoteTerminalService } from 'vs/workbench/contrib/terminal/browser/remoteTerminalService';
|
import { RemoteTerminalService } from 'vs/workbench/contrib/terminal/browser/remoteTerminalService';
|
||||||
import { isIPad } from 'vs/base/browser/browser';
|
import { isIPad } from 'vs/base/browser/browser';
|
||||||
|
import { WindowsShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
|
|
||||||
// Register services
|
// Register services
|
||||||
registerSingleton(ITerminalService, TerminalService, true);
|
registerSingleton(ITerminalService, TerminalService, true);
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import { IProcessEnvironment, Platform } from 'vs/base/common/platform';
|
|||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { FindReplaceState } from 'vs/editor/contrib/find/findState';
|
import { FindReplaceState } from 'vs/editor/contrib/find/findState';
|
||||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, ITerminalTabLayoutInfoById } from 'vs/platform/terminal/common/terminal';
|
import { IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, ITerminalTabLayoutInfoById, TerminalShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
import { IAvailableShellsRequest, ICommandTracker, IDefaultShellAndArgsRequest, INavigationMode, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalNativeWindowsDelegate, ITerminalProcessExtHostProxy, IWindowsShellHelper, LinuxDistro, TitleEventSource } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { IAvailableShellsRequest, ICommandTracker, IDefaultShellAndArgsRequest, INavigationMode, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalNativeWindowsDelegate, ITerminalProcessExtHostProxy, LinuxDistro, TitleEventSource } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import type { Terminal as XTermTerminal } from 'xterm';
|
import type { Terminal as XTermTerminal } from 'xterm';
|
||||||
import type { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
|
import type { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
|
||||||
import type { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11';
|
import type { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11';
|
||||||
@@ -35,7 +35,6 @@ export interface ITerminalInstanceService {
|
|||||||
getXtermSearchConstructor(): Promise<typeof XTermSearchAddon>;
|
getXtermSearchConstructor(): Promise<typeof XTermSearchAddon>;
|
||||||
getXtermUnicode11Constructor(): Promise<typeof XTermUnicode11Addon>;
|
getXtermUnicode11Constructor(): Promise<typeof XTermUnicode11Addon>;
|
||||||
getXtermWebglConstructor(): Promise<typeof XTermWebglAddon>;
|
getXtermWebglConstructor(): Promise<typeof XTermWebglAddon>;
|
||||||
createWindowsShellHelper(shellProcessId: number, xterm: XTermTerminal): IWindowsShellHelper;
|
|
||||||
getDefaultShellAndArgs(useAutomationShell: boolean, platformOverride?: Platform): Promise<{ shell: string, args: string[] | string | undefined }>;
|
getDefaultShellAndArgs(useAutomationShell: boolean, platformOverride?: Platform): Promise<{ shell: string, args: string[] | string | undefined }>;
|
||||||
getMainProcessParentEnv(): Promise<IProcessEnvironment>;
|
getMainProcessParentEnv(): Promise<IProcessEnvironment>;
|
||||||
}
|
}
|
||||||
@@ -226,14 +225,6 @@ export interface ISearchOptions {
|
|||||||
incremental?: boolean;
|
incremental?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum WindowsShellType {
|
|
||||||
CommandPrompt = 'cmd',
|
|
||||||
PowerShell = 'pwsh',
|
|
||||||
Wsl = 'wsl',
|
|
||||||
GitBash = 'gitbash'
|
|
||||||
}
|
|
||||||
export type TerminalShellType = WindowsShellType | undefined;
|
|
||||||
|
|
||||||
export interface ITerminalBeforeHandleLinkEvent {
|
export interface ITerminalBeforeHandleLinkEvent {
|
||||||
terminal?: ITerminalInstance;
|
terminal?: ITerminalInstance;
|
||||||
/** The text of the link */
|
/** The text of the link */
|
||||||
@@ -536,11 +527,6 @@ export interface ITerminalInstance {
|
|||||||
*/
|
*/
|
||||||
setTitle(title: string, eventSource: TitleEventSource): void;
|
setTitle(title: string, eventSource: TitleEventSource): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the shell type of the terminal instance.
|
|
||||||
*/
|
|
||||||
setShellType(shellType: TerminalShellType): void;
|
|
||||||
|
|
||||||
waitForTitle(): Promise<string>;
|
waitForTitle(): Promise<string>;
|
||||||
|
|
||||||
setDimensions(dimensions: ITerminalDimensions): void;
|
setDimensions(dimensions: ITerminalDimensions): void;
|
||||||
|
|||||||
@@ -25,12 +25,12 @@ import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderB
|
|||||||
import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||||
import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||||
import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager';
|
import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager';
|
||||||
import { ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_VIEW_ID, IWindowsShellHelper, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, INavigationMode, TitleEventSource, DEFAULT_COMMANDS_TO_SKIP_SHELL, TERMINAL_CREATION_COMMANDS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE, SUGGESTED_RENDERER_TYPE } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_VIEW_ID, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, INavigationMode, TitleEventSource, DEFAULT_COMMANDS_TO_SKIP_SHELL, TERMINAL_CREATION_COMMANDS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE, SUGGESTED_RENDERER_TYPE } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
|
import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
|
||||||
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
||||||
import { TerminalLinkManager } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager';
|
import { TerminalLinkManager } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager';
|
||||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||||
import { ITerminalInstanceService, ITerminalInstance, TerminalShellType, WindowsShellType, ITerminalExternalLinkProvider } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { ITerminalInstanceService, ITerminalInstance, ITerminalExternalLinkProvider } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/browser/terminalProcessManager';
|
import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/browser/terminalProcessManager';
|
||||||
import type { Terminal as XTermTerminal, IBuffer, ITerminalAddon } from 'xterm';
|
import type { Terminal as XTermTerminal, IBuffer, ITerminalAddon } from 'xterm';
|
||||||
import type { SearchAddon, ISearchOptions } from 'xterm-addon-search';
|
import type { SearchAddon, ISearchOptions } from 'xterm-addon-search';
|
||||||
@@ -47,7 +47,7 @@ import { TypeAheadAddon } from 'vs/workbench/contrib/terminal/browser/terminalTy
|
|||||||
import { BrowserFeatures } from 'vs/base/browser/canIUse';
|
import { BrowserFeatures } from 'vs/base/browser/canIUse';
|
||||||
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
|
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
|
||||||
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||||
import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError } from 'vs/platform/terminal/common/terminal';
|
import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
|
|
||||||
// How long in milliseconds should an average frame take to render for a notification to appear
|
// How long in milliseconds should an average frame take to render for a notification to appear
|
||||||
// which suggests the fallback DOM-based renderer
|
// which suggests the fallback DOM-based renderer
|
||||||
@@ -99,7 +99,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||||||
private _cols: number = 0;
|
private _cols: number = 0;
|
||||||
private _rows: number = 0;
|
private _rows: number = 0;
|
||||||
private _dimensionsOverride: ITerminalDimensionsOverride | undefined;
|
private _dimensionsOverride: ITerminalDimensionsOverride | 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) | undefined;
|
private _titleReadyComplete: ((title: string) => any) | undefined;
|
||||||
@@ -648,7 +647,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||||||
this._terminalFocusContextKey.reset();
|
this._terminalFocusContextKey.reset();
|
||||||
this._refreshSelectionContextKey();
|
this._refreshSelectionContextKey();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._widgetManager.attachToElement(xterm.element);
|
this._widgetManager.attachToElement(xterm.element);
|
||||||
this._processManager.onProcessReady(() => this._linkManager?.setWidgetManager(this._widgetManager));
|
this._processManager.onProcessReady(() => this._linkManager?.setWidgetManager(this._widgetManager));
|
||||||
|
|
||||||
@@ -773,8 +771,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||||||
public dispose(immediate?: boolean): void {
|
public dispose(immediate?: boolean): void {
|
||||||
this._logService.trace(`terminalInstance#dispose (instanceId: ${this.instanceId})`);
|
this._logService.trace(`terminalInstance#dispose (instanceId: ${this.instanceId})`);
|
||||||
|
|
||||||
dispose(this._windowsShellHelper);
|
|
||||||
this._windowsShellHelper = undefined;
|
|
||||||
dispose(this._linkManager);
|
dispose(this._linkManager);
|
||||||
this._linkManager = undefined;
|
this._linkManager = undefined;
|
||||||
dispose(this._commandTrackerAddon);
|
dispose(this._commandTrackerAddon);
|
||||||
@@ -969,25 +965,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||||||
this._messageTitleDisposable = this._processManager.onProcessTitle(title => this.setTitle(title ? title : '', TitleEventSource.Process));
|
this._messageTitleDisposable = this._processManager.onProcessTitle(title => this.setTitle(title ? title : '', TitleEventSource.Process));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this._processManager.onProcessShellTypeChanged(type => {
|
||||||
if (platform.isWindows) {
|
this.setShellType(type);
|
||||||
this._processManager.ptyProcessReady.then(() => {
|
});
|
||||||
if (this._processManager.remoteAuthority) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._xtermReadyPromise.then(xterm => {
|
|
||||||
if (!this._isDisposed && this._processManager && this._processManager.shellProcessId) {
|
|
||||||
this._windowsShellHelper = this._terminalInstanceService.createWindowsShellHelper(this._processManager.shellProcessId, xterm);
|
|
||||||
this._windowsShellHelper.onShellNameChange(title => {
|
|
||||||
this.setShellType(this.getShellType(title));
|
|
||||||
if (this.isTitleSetByProcess && !this._configHelper.config.experimentalUseTitleEvent) {
|
|
||||||
this.setTitle(title, TitleEventSource.Process);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createProcess(): void {
|
private _createProcess(): void {
|
||||||
@@ -998,29 +978,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private getShellType(executable: string): TerminalShellType {
|
|
||||||
switch (executable.toLowerCase()) {
|
|
||||||
case 'cmd.exe':
|
|
||||||
return WindowsShellType.CommandPrompt;
|
|
||||||
case 'powershell.exe':
|
|
||||||
case 'pwsh.exe':
|
|
||||||
return WindowsShellType.PowerShell;
|
|
||||||
case 'bash.exe':
|
|
||||||
case 'git-cmd.exe':
|
|
||||||
return WindowsShellType.GitBash;
|
|
||||||
case 'wsl.exe':
|
|
||||||
case 'ubuntu.exe':
|
|
||||||
case 'ubuntu1804.exe':
|
|
||||||
case 'kali.exe':
|
|
||||||
case 'debian.exe':
|
|
||||||
case 'opensuse-42.exe':
|
|
||||||
case 'sles-12.exe':
|
|
||||||
return WindowsShellType.Wsl;
|
|
||||||
default:
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _onProcessData(ev: IProcessDataEvent): void {
|
private _onProcessData(ev: IProcessDataEvent): void {
|
||||||
if (ev.sync) {
|
if (ev.sync) {
|
||||||
this._xtermCore?.writeSync(ev.data);
|
this._xtermCore?.writeSync(ev.data);
|
||||||
@@ -1541,8 +1498,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||||||
// automatically updates the terminal name
|
// automatically updates the terminal name
|
||||||
dispose(this._messageTitleDisposable);
|
dispose(this._messageTitleDisposable);
|
||||||
this._messageTitleDisposable = undefined;
|
this._messageTitleDisposable = undefined;
|
||||||
dispose(this._windowsShellHelper);
|
|
||||||
this._windowsShellHelper = undefined;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const didTitleChange = title !== this._title;
|
const didTitleChange = title !== this._title;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { IWindowsShellHelper, IDefaultShellAndArgsRequest } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { IDefaultShellAndArgsRequest } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import type { Terminal as XTermTerminal } from 'xterm';
|
import type { Terminal as XTermTerminal } from 'xterm';
|
||||||
import type { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
|
import type { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
|
||||||
import type { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11';
|
import type { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11';
|
||||||
@@ -59,10 +59,6 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst
|
|||||||
return WebglAddon;
|
return WebglAddon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createWindowsShellHelper(): IWindowsShellHelper {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
public createTerminalProcess(): Promise<ITerminalChildProcess> {
|
public createTerminalProcess(): Promise<ITerminalChildProcess> {
|
||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import { Emitter, Event } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError } from 'vs/platform/terminal/common/terminal';
|
import { IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
|
|
||||||
@@ -42,6 +42,8 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal
|
|||||||
public readonly onRequestCwd: Event<void> = this._onRequestCwd.event;
|
public readonly onRequestCwd: Event<void> = this._onRequestCwd.event;
|
||||||
private readonly _onRequestLatency = this._register(new Emitter<void>());
|
private readonly _onRequestLatency = this._register(new Emitter<void>());
|
||||||
public readonly onRequestLatency: Event<void> = this._onRequestLatency.event;
|
public readonly onRequestLatency: Event<void> = this._onRequestLatency.event;
|
||||||
|
private readonly _onProcessShellTypeChanged = this._register(new Emitter<TerminalShellType>());
|
||||||
|
public readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
|
||||||
|
|
||||||
private _pendingInitialCwdRequests: ((value: string | PromiseLike<string>) => void)[] = [];
|
private _pendingInitialCwdRequests: ((value: string | PromiseLike<string>) => void)[] = [];
|
||||||
private _pendingCwdRequests: ((value: string | PromiseLike<string>) => void)[] = [];
|
private _pendingCwdRequests: ((value: string | PromiseLike<string>) => void)[] = [];
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import { EnvironmentVariableInfoChangesActive, EnvironmentVariableInfoStale } fr
|
|||||||
import { IPathService } from 'vs/workbench/services/path/common/pathService';
|
import { IPathService } from 'vs/workbench/services/path/common/pathService';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { IEnvironmentVariableInfo, IEnvironmentVariableService, IMergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableInfo, IEnvironmentVariableService, IMergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||||
import { IProcessDataEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalEnvironment, ITerminalLaunchError, FlowControlConstants, ILocalTerminalService } from 'vs/platform/terminal/common/terminal';
|
import { IProcessDataEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalEnvironment, ITerminalLaunchError, FlowControlConstants, TerminalShellType, ILocalTerminalService } from 'vs/platform/terminal/common/terminal';
|
||||||
|
|
||||||
/** The amount of time to consider terminal errors to be related to the launch */
|
/** The amount of time to consider terminal errors to be related to the launch */
|
||||||
const LAUNCHING_DURATION = 500;
|
const LAUNCHING_DURATION = 500;
|
||||||
@@ -84,6 +84,8 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||||||
public get onProcessData(): Event<IProcessDataEvent> { return this._onProcessData.event; }
|
public get onProcessData(): Event<IProcessDataEvent> { return this._onProcessData.event; }
|
||||||
private readonly _onProcessTitle = this._register(new Emitter<string>());
|
private readonly _onProcessTitle = this._register(new Emitter<string>());
|
||||||
public get onProcessTitle(): Event<string> { return this._onProcessTitle.event; }
|
public get onProcessTitle(): Event<string> { return this._onProcessTitle.event; }
|
||||||
|
private readonly _onProcessShellTypeChanged = this._register(new Emitter<TerminalShellType>());
|
||||||
|
public get onProcessShellTypeChanged(): Event<TerminalShellType> { return this._onProcessShellTypeChanged.event; }
|
||||||
private readonly _onProcessExit = this._register(new Emitter<number | undefined>());
|
private readonly _onProcessExit = this._register(new Emitter<number | undefined>());
|
||||||
public get onProcessExit(): Event<number | undefined> { return this._onProcessExit.event; }
|
public get onProcessExit(): Event<number | undefined> { return this._onProcessExit.event; }
|
||||||
private readonly _onProcessOverrideDimensions = this._register(new Emitter<ITerminalDimensionsOverride | undefined>());
|
private readonly _onProcessOverrideDimensions = this._register(new Emitter<ITerminalDimensionsOverride | undefined>());
|
||||||
@@ -240,6 +242,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||||||
});
|
});
|
||||||
|
|
||||||
this._process.onProcessTitleChanged(title => this._onProcessTitle.fire(title));
|
this._process.onProcessTitleChanged(title => this._onProcessTitle.fire(title));
|
||||||
|
this._process.onProcessShellTypeChanged(type => this._onProcessShellTypeChanged.fire(type));
|
||||||
this._process.onProcessExit(exitCode => this._onExit(exitCode));
|
this._process.onProcessExit(exitCode => this._onExit(exitCode));
|
||||||
if (this._process.onProcessOverrideDimensions) {
|
if (this._process.onProcessOverrideDimensions) {
|
||||||
this._process.onProcessOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e));
|
this._process.onProcessOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e));
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
|||||||
import { IInstantiationService, optional } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService, optional } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IPickOptions, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
import { IPickOptions, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
import { ILocalTerminalService, IShellLaunchConfig, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById } from 'vs/platform/terminal/common/terminal';
|
import { ILocalTerminalService, IShellLaunchConfig, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalShellType, WindowsShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
import { IViewDescriptorService, IViewsService, ViewContainerLocation } from 'vs/workbench/common/views';
|
import { IViewDescriptorService, IViewsService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||||
import { IRemoteTerminalService, ITerminalExternalLinkProvider, ITerminalInstance, ITerminalService, ITerminalTab, TerminalConnectionState, TerminalShellType, WindowsShellType } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { IRemoteTerminalService, ITerminalExternalLinkProvider, ITerminalInstance, ITerminalService, ITerminalTab, TerminalConnectionState } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
||||||
import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance';
|
import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance';
|
||||||
import { TerminalTab } from 'vs/workbench/contrib/terminal/browser/terminalTab';
|
import { TerminalTab } from 'vs/workbench/contrib/terminal/browser/terminalTab';
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
|||||||
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { OperatingSystem } from 'vs/base/common/platform';
|
import { OperatingSystem } from 'vs/base/common/platform';
|
||||||
import { IExtensionPointDescriptor } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
import { IExtensionPointDescriptor } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||||
import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError } from 'vs/platform/terminal/common/terminal';
|
import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||||
|
|
||||||
export const TERMINAL_VIEW_ID = 'terminal';
|
export const TERMINAL_VIEW_ID = 'terminal';
|
||||||
@@ -231,12 +231,6 @@ export interface IDefaultShellAndArgsRequest {
|
|||||||
callback: (shell: string, args: string[] | string | undefined) => void;
|
callback: (shell: string, args: string[] | string | undefined) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IWindowsShellHelper extends IDisposable {
|
|
||||||
readonly onShellNameChange: Event<string>;
|
|
||||||
|
|
||||||
getShellName(): Promise<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ITerminalProcessManager extends IDisposable {
|
export interface ITerminalProcessManager extends IDisposable {
|
||||||
readonly processState: ProcessState;
|
readonly processState: ProcessState;
|
||||||
readonly ptyProcessReady: Promise<void>;
|
readonly ptyProcessReady: Promise<void>;
|
||||||
@@ -258,6 +252,7 @@ export interface ITerminalProcessManager extends IDisposable {
|
|||||||
readonly onBeforeProcessData: Event<IBeforeProcessDataEvent>;
|
readonly onBeforeProcessData: Event<IBeforeProcessDataEvent>;
|
||||||
readonly onProcessData: Event<IProcessDataEvent>;
|
readonly onProcessData: Event<IProcessDataEvent>;
|
||||||
readonly onProcessTitle: Event<string>;
|
readonly onProcessTitle: Event<string>;
|
||||||
|
readonly onProcessShellTypeChanged: Event<TerminalShellType>;
|
||||||
readonly onProcessExit: Event<number | undefined>;
|
readonly onProcessExit: Event<number | undefined>;
|
||||||
readonly onProcessOverrideDimensions: Event<ITerminalDimensionsOverride | undefined>;
|
readonly onProcessOverrideDimensions: Event<ITerminalDimensionsOverride | undefined>;
|
||||||
readonly onProcessResolvedShellLaunchConfig: Event<IShellLaunchConfig>;
|
readonly onProcessResolvedShellLaunchConfig: Event<IShellLaunchConfig>;
|
||||||
@@ -347,12 +342,6 @@ export enum TitleEventSource {
|
|||||||
Sequence
|
Sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IWindowsShellHelper extends IDisposable {
|
|
||||||
readonly onShellNameChange: Event<string>;
|
|
||||||
|
|
||||||
getShellName(): Promise<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const enum TERMINAL_COMMAND_ID {
|
export const enum TERMINAL_COMMAND_ID {
|
||||||
FIND_NEXT = 'workbench.action.terminal.findNext',
|
FIND_NEXT = 'workbench.action.terminal.findNext',
|
||||||
FIND_PREVIOUS = 'workbench.action.terminal.findPrevious',
|
FIND_PREVIOUS = 'workbench.action.terminal.findPrevious',
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
|
import { IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { IProcessEnvironment, platform, Platform } from 'vs/base/common/platform';
|
import { IProcessEnvironment, platform, Platform } from 'vs/base/common/platform';
|
||||||
import { getSystemShell } from 'vs/base/node/shell';
|
import { getSystemShell } from 'vs/base/node/shell';
|
||||||
@@ -10,10 +11,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
|||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||||
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
|
||||||
import { IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, IWindowsShellHelper } from 'vs/workbench/contrib/terminal/common/terminal';
|
|
||||||
import { createVariableResolver, getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
|
||||||
import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/electron-browser/windowsShellHelper';
|
|
||||||
import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment';
|
import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment';
|
||||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||||
@@ -21,6 +18,7 @@ import type { Terminal as XTermTerminal } from 'xterm';
|
|||||||
import type { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
|
import type { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
|
||||||
import type { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11';
|
import type { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11';
|
||||||
import type { WebglAddon as XTermWebglAddon } from 'xterm-addon-webgl';
|
import type { WebglAddon as XTermWebglAddon } from 'xterm-addon-webgl';
|
||||||
|
import { createVariableResolver, getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
||||||
|
|
||||||
let Terminal: typeof XTermTerminal;
|
let Terminal: typeof XTermTerminal;
|
||||||
let SearchAddon: typeof XTermSearchAddon;
|
let SearchAddon: typeof XTermSearchAddon;
|
||||||
@@ -69,10 +67,6 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst
|
|||||||
return WebglAddon;
|
return WebglAddon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createWindowsShellHelper(shellProcessId: number, xterm: XTermTerminal): IWindowsShellHelper {
|
|
||||||
return new WindowsShellHelper(shellProcessId, xterm);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _isWorkspaceShellAllowed(): boolean {
|
private _isWorkspaceShellAllowed(): boolean {
|
||||||
return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false);
|
return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal';
|
import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal';
|
||||||
import { IProcessDataEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError } from 'vs/platform/terminal/common/terminal';
|
import { IProcessDataEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
|
||||||
import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/terminalProcess';
|
import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/terminalProcess';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,6 +30,8 @@ export class LocalPty extends Disposable implements ITerminalChildProcess {
|
|||||||
public readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
|
public readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
|
||||||
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<IShellLaunchConfig>());
|
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<IShellLaunchConfig>());
|
||||||
public readonly onProcessResolvedShellLaunchConfig = this._onProcessResolvedShellLaunchConfig.event;
|
public readonly onProcessResolvedShellLaunchConfig = this._onProcessResolvedShellLaunchConfig.event;
|
||||||
|
private readonly _onProcessShellTypeChanged = this._register(new Emitter<TerminalShellType>());
|
||||||
|
public readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly id: number,
|
readonly id: number,
|
||||||
@@ -95,6 +97,9 @@ export class LocalPty extends Disposable implements ITerminalChildProcess {
|
|||||||
handleTitleChanged(e: string) {
|
handleTitleChanged(e: string) {
|
||||||
this._onProcessTitleChanged.fire(e);
|
this._onProcessTitleChanged.fire(e);
|
||||||
}
|
}
|
||||||
|
handleShellTypeChanged(e: TerminalShellType) {
|
||||||
|
this._onProcessShellTypeChanged.fire(e);
|
||||||
|
}
|
||||||
handleOverrideDimensions(e: ITerminalDimensionsOverride | undefined) {
|
handleOverrideDimensions(e: ITerminalDimensionsOverride | undefined) {
|
||||||
this._onProcessOverrideDimensions.fire(e);
|
this._onProcessOverrideDimensions.fire(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1477,7 +1477,6 @@ export class TestTerminalInstanceService implements ITerminalInstanceService {
|
|||||||
createWindowsShellHelper(shellProcessId: number, xterm: any): any { throw new Error('Method not implemented.'); }
|
createWindowsShellHelper(shellProcessId: number, xterm: any): any { throw new Error('Method not implemented.'); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class TestLocalTerminalService implements ILocalTerminalService {
|
export class TestLocalTerminalService implements ILocalTerminalService {
|
||||||
declare readonly _serviceBrand: undefined;
|
declare readonly _serviceBrand: undefined;
|
||||||
|
|
||||||
@@ -1507,7 +1506,7 @@ class TestTerminalChildProcess implements ITerminalChildProcess {
|
|||||||
onProcessExit = Event.None;
|
onProcessExit = Event.None;
|
||||||
onProcessReady = Event.None;
|
onProcessReady = Event.None;
|
||||||
onProcessTitleChanged = Event.None;
|
onProcessTitleChanged = Event.None;
|
||||||
|
onProcessShellTypeChanged = Event.None;
|
||||||
async start(): Promise<undefined> { return undefined; }
|
async start(): Promise<undefined> { return undefined; }
|
||||||
shutdown(immediate: boolean): void { }
|
shutdown(immediate: boolean): void { }
|
||||||
input(data: string): void { }
|
input(data: string): void { }
|
||||||
|
|||||||
Reference in New Issue
Block a user