mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-31 09:10:30 -04:00
This reverts commit 5d44b6a6a7.
This commit is contained in:
@@ -502,7 +502,7 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindPrevious, Fi
|
||||
|
||||
const sendSequenceTerminalCommand = new SendSequenceTerminalCommand({
|
||||
id: SendSequenceTerminalCommand.ID,
|
||||
precondition: undefined,
|
||||
precondition: null,
|
||||
description: {
|
||||
description: `Send Custom Sequence To Terminal`,
|
||||
args: [{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { Terminal as XTermTerminal } from 'vscode-xterm';
|
||||
import { ITerminalInstance, IWindowsShellHelper, ITerminalProcessManager, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IProcessEnvironment, Platform } from 'vs/base/common/platform';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
|
||||
export const ITerminalInstanceService = createDecorator<ITerminalInstanceService>('terminalInstanceService');
|
||||
|
||||
@@ -17,7 +17,6 @@ export interface ITerminalInstanceService {
|
||||
createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper;
|
||||
createTerminalProcessManager(id: number, configHelper: ITerminalConfigHelper): ITerminalProcessManager;
|
||||
createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess;
|
||||
getDefaultShell(p: Platform): string;
|
||||
}
|
||||
|
||||
export interface IBrowserTerminalConfigHelper extends ITerminalConfigHelper {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Action, IAction } from 'vs/base/common/actions';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/model';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ITerminalService, TERMINAL_PANEL_ID, ITerminalInstance, Direction, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { SelectActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { TogglePanelAction } from 'vs/workbench/browser/panel';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
@@ -726,7 +726,7 @@ export class SwitchTerminalAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class SwitchTerminalActionViewItem extends SelectActionViewItem {
|
||||
export class SwitchTerminalActionItem extends SelectActionItem {
|
||||
|
||||
constructor(
|
||||
action: IAction,
|
||||
|
||||
@@ -30,7 +30,7 @@ export class TerminalCommandTracker implements ITerminalCommandTracker, IDisposa
|
||||
constructor(
|
||||
private _xterm: Terminal
|
||||
) {
|
||||
this._xterm.onKey(e => this._onKey(e.key));
|
||||
this._xterm.on('key', key => this._onKey(key));
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
@@ -48,7 +48,7 @@ export class TerminalCommandTracker implements ITerminalCommandTracker, IDisposa
|
||||
}
|
||||
|
||||
private _onEnter(): void {
|
||||
if (this._xterm.buffer.cursorX >= MINIMUM_PROMPT_LENGTH) {
|
||||
if (this._xterm._core.buffer.x >= MINIMUM_PROMPT_LENGTH) {
|
||||
this._xterm.addMarker(0);
|
||||
}
|
||||
}
|
||||
@@ -175,7 +175,7 @@ export class TerminalCommandTracker implements ITerminalCommandTracker, IDisposa
|
||||
private _getLine(marker: IMarker | Boundary): number {
|
||||
// Use the _second last_ row as the last row is likely the prompt
|
||||
if (marker === Boundary.Bottom) {
|
||||
return this._xterm.buffer.baseY + this._xterm.rows - 1;
|
||||
return this._xterm._core.buffer.ybase + this._xterm.rows - 1;
|
||||
}
|
||||
|
||||
if (marker === Boundary.Top) {
|
||||
@@ -235,10 +235,10 @@ export class TerminalCommandTracker implements ITerminalCommandTracker, IDisposa
|
||||
if (this._currentMarker === Boundary.Bottom) {
|
||||
return 0;
|
||||
} else if (this._currentMarker === Boundary.Top) {
|
||||
return 0 - (this._xterm.buffer.baseY + this._xterm.buffer.cursorY);
|
||||
return 0 - (this._xterm._core.buffer.ybase + this._xterm._core.buffer.y);
|
||||
} else {
|
||||
let offset = this._getLine(this._currentMarker);
|
||||
offset -= this._xterm.buffer.baseY + this._xterm.buffer.cursorY;
|
||||
offset -= this._xterm._core.buffer.ybase + this._xterm._core.buffer.y;
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,9 +227,9 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
|
||||
return !!isWorkspaceShellAllowed;
|
||||
}
|
||||
|
||||
public mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, platformOverride: platform.Platform = platform.platform): void {
|
||||
public mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, platformOverride: platform.Platform = platform.platform): void {
|
||||
const isWorkspaceShellAllowed = this.checkWorkspaceShellPermissions(platformOverride === platform.Platform.Windows ? platform.OperatingSystem.Windows : (platformOverride === platform.Platform.Mac ? platform.OperatingSystem.Macintosh : platform.OperatingSystem.Linux));
|
||||
mergeDefaultShellPathAndArgs(shell, (key) => this._workspaceConfigurationService.inspect(key), isWorkspaceShellAllowed, defaultShell, platformOverride);
|
||||
mergeDefaultShellPathAndArgs(shell, (key) => this._workspaceConfigurationService.inspect(key), isWorkspaceShellAllowed, platformOverride);
|
||||
}
|
||||
|
||||
private _toInteger(source: any, minimum: number, maximum: number, fallback: number): number {
|
||||
|
||||
@@ -25,14 +25,14 @@ import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderB
|
||||
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { PANEL_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager';
|
||||
import { IShellLaunchConfig, ITerminalDimensions, ITerminalInstance, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_PANEL_ID, IWindowsShellHelper, SHELL_PATH_INVALID_EXIT_CODE } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IShellLaunchConfig, ITerminalDimensions, ITerminalInstance, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_PANEL_ID, IWindowsShellHelper } 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 { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands';
|
||||
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
||||
import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler';
|
||||
import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/browser/terminalCommandTracker';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { ISearchOptions, Terminal as XTermTerminal, IBuffer } from 'vscode-xterm';
|
||||
import { ISearchOptions, Terminal as XTermTerminal } from 'vscode-xterm';
|
||||
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
|
||||
@@ -371,7 +371,7 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
// it gets removed and then added back to the DOM (resetting scrollTop to 0).
|
||||
// Upstream issue: https://github.com/sourcelair/xterm.js/issues/291
|
||||
if (this._xterm) {
|
||||
this._xterm._core._onScroll.fire(this._xterm.buffer.viewportY);
|
||||
this._xterm.emit('scroll', this._xterm._core.buffer.ydisp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,17 +416,18 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
// TODO: Guess whether to use canvas or dom better
|
||||
rendererType: config.rendererType === 'auto' ? 'canvas' : config.rendererType,
|
||||
// TODO: Remove this once the setting is removed upstream
|
||||
experimentalCharAtlas: 'dynamic'
|
||||
experimentalCharAtlas: 'dynamic',
|
||||
experimentalBufferLineImpl: 'TypedArray'
|
||||
});
|
||||
if (this._shellLaunchConfig.initialText) {
|
||||
this._xterm.writeln(this._shellLaunchConfig.initialText);
|
||||
}
|
||||
this._xterm.onLineFeed(() => this._onLineFeed());
|
||||
this._xterm.onKey(e => this._onKey(e.key, e.domEvent));
|
||||
this._xterm.on('linefeed', () => this._onLineFeed());
|
||||
this._xterm.on('key', (key, ev) => this._onKey(key, ev));
|
||||
|
||||
if (this._processManager) {
|
||||
this._processManager.onProcessData(data => this._onProcessData(data));
|
||||
this._xterm.onData(data => this._processManager!.write(data));
|
||||
this._xterm.on('data', data => this._processManager!.write(data));
|
||||
// TODO: How does the cwd work on detached processes?
|
||||
this.processReady.then(async () => {
|
||||
this._linkHandler.processCwd = await this._processManager!.getInitialCwd();
|
||||
@@ -438,24 +439,18 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
return;
|
||||
}
|
||||
if (this._processManager.os === platform.OperatingSystem.Windows) {
|
||||
this._xterm.setOption('windowsMode', true);
|
||||
// Force line data to be sent when the cursor is moved, the main purpose for
|
||||
// this is because ConPTY will often not do a line feed but instead move the
|
||||
// cursor, in which case we still want to send the current line's data to tasks.
|
||||
this._xterm.addCsiHandler('H', () => {
|
||||
this._onCursorMove();
|
||||
return false;
|
||||
});
|
||||
this._xterm.winptyCompatInit();
|
||||
}
|
||||
this._linkHandler = this._instantiationService.createInstance(TerminalLinkHandler, this._xterm, platform.platform, this._processManager);
|
||||
});
|
||||
} else if (this.shellLaunchConfig.isRendererOnly) {
|
||||
this._linkHandler = this._instantiationService.createInstance(TerminalLinkHandler, this._xterm, undefined, undefined);
|
||||
}
|
||||
this._xterm.on('focus', () => this._onFocus.fire(this));
|
||||
|
||||
// Register listener to trigger the onInput ext API if the terminal is a renderer only
|
||||
if (this._shellLaunchConfig.isRendererOnly) {
|
||||
this._xterm.onData(data => this._sendRendererInput(data));
|
||||
this._xterm.on('data', (data) => this._sendRendererInput(data));
|
||||
}
|
||||
|
||||
this._commandTracker = new TerminalCommandTracker(this._xterm);
|
||||
@@ -513,7 +508,6 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
(<any>this._wrapperElement).xterm = this._xterm;
|
||||
|
||||
this._xterm.open(this._xtermElement);
|
||||
this._xterm.textarea.addEventListener('focus', () => this._onFocus.fire(this));
|
||||
this._xterm.attachCustomKeyEventHandler((event: KeyboardEvent): boolean => {
|
||||
// Disable all input if the terminal is exiting
|
||||
if (this._isExiting) {
|
||||
@@ -751,8 +745,8 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
}
|
||||
}
|
||||
if (this._xterm) {
|
||||
const buffer = this._xterm.buffer;
|
||||
this._sendLineData(buffer, buffer.baseY + buffer.cursorY);
|
||||
const buffer = (<any>this._xterm._core.buffer);
|
||||
this._sendLineData(buffer, buffer.ybase + buffer.y);
|
||||
this._xterm.dispose();
|
||||
}
|
||||
|
||||
@@ -865,7 +859,7 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
// necessary if the number of rows in the terminal has decreased while it was in the
|
||||
// background since scrollTop changes take no effect but the terminal's position does
|
||||
// change since the number of visible rows decreases.
|
||||
this._xterm._core._onScroll.fire(this._xterm.buffer.viewportY);
|
||||
this._xterm.emit('scroll', this._xterm._core.buffer.ydisp);
|
||||
if (this._container && this._container.parentElement) {
|
||||
// Force a layout when the instance becomes invisible. This is particularly important
|
||||
// for ensuring that terminals that are created in the background by an extension will
|
||||
@@ -976,32 +970,10 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
}
|
||||
|
||||
this._isExiting = true;
|
||||
let exitCodeMessage: string | undefined;
|
||||
let exitCodeMessage: string;
|
||||
|
||||
// Create exit code message
|
||||
if (exitCode) {
|
||||
if (exitCode === SHELL_PATH_INVALID_EXIT_CODE) {
|
||||
exitCodeMessage = nls.localize('terminal.integrated.exitedWithInvalidPath', 'The terminal shell path does not exist: {0}', this._shellLaunchConfig.executable);
|
||||
} else if (this._processManager && this._processManager.processState === ProcessState.KILLED_DURING_LAUNCH) {
|
||||
let args = '';
|
||||
if (typeof this._shellLaunchConfig.args === 'string') {
|
||||
args = ` ${this._shellLaunchConfig.args}`;
|
||||
} else if (this._shellLaunchConfig.args && this._shellLaunchConfig.args.length) {
|
||||
args = ' ' + this._shellLaunchConfig.args.map(a => {
|
||||
if (typeof a === 'string' && a.indexOf(' ') !== -1) {
|
||||
return `'${a}'`;
|
||||
}
|
||||
return a;
|
||||
}).join(' ');
|
||||
}
|
||||
if (this._shellLaunchConfig.executable) {
|
||||
exitCodeMessage = nls.localize('terminal.integrated.launchFailed', 'The terminal process command \'{0}{1}\' failed to launch (exit code: {2})', this._shellLaunchConfig.executable, args, exitCode);
|
||||
} else {
|
||||
exitCodeMessage = nls.localize('terminal.integrated.launchFailedExtHost', 'The terminal process failed to launch (exit code: {0})', exitCode);
|
||||
}
|
||||
} else {
|
||||
exitCodeMessage = nls.localize('terminal.integrated.exitedWithCode', 'The terminal process terminated with exit code: {0}', exitCode);
|
||||
}
|
||||
exitCodeMessage = nls.localize('terminal.integrated.exitedWithCode', 'The terminal process terminated with exit code: {0}', exitCode);
|
||||
}
|
||||
|
||||
this._logService.debug(`Terminal process exit (id: ${this.id})${this._processManager ? ' state ' + this._processManager.processState : ''}`);
|
||||
@@ -1009,8 +981,8 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
// Only trigger wait on exit when the exit was *not* triggered by the
|
||||
// user (via the `workbench.action.terminal.kill` command).
|
||||
if (this._shellLaunchConfig.waitOnExit && (!this._processManager || this._processManager.processState !== ProcessState.KILLED_BY_USER)) {
|
||||
if (exitCodeMessage) {
|
||||
this._xterm.writeln(exitCodeMessage);
|
||||
if (exitCode) {
|
||||
this._xterm.writeln(exitCodeMessage!);
|
||||
}
|
||||
if (typeof this._shellLaunchConfig.waitOnExit === 'string') {
|
||||
let message = this._shellLaunchConfig.waitOnExit;
|
||||
@@ -1025,14 +997,29 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
}
|
||||
} else {
|
||||
this.dispose();
|
||||
if (exitCodeMessage) {
|
||||
if (exitCode) {
|
||||
if (this._processManager && this._processManager.processState === ProcessState.KILLED_DURING_LAUNCH) {
|
||||
this._notificationService.error(exitCodeMessage);
|
||||
let args = '';
|
||||
if (typeof this._shellLaunchConfig.args === 'string') {
|
||||
args = this._shellLaunchConfig.args;
|
||||
} else if (this._shellLaunchConfig.args && this._shellLaunchConfig.args.length) {
|
||||
args = ' ' + this._shellLaunchConfig.args.map(a => {
|
||||
if (typeof a === 'string' && a.indexOf(' ') !== -1) {
|
||||
return `'${a}'`;
|
||||
}
|
||||
return a;
|
||||
}).join(' ');
|
||||
}
|
||||
if (this._shellLaunchConfig.executable) {
|
||||
this._notificationService.error(nls.localize('terminal.integrated.launchFailed', 'The terminal process command \'{0}{1}\' failed to launch (exit code: {2})', this._shellLaunchConfig.executable, args, exitCode));
|
||||
} else {
|
||||
this._notificationService.error(nls.localize('terminal.integrated.launchFailedExtHost', 'The terminal process failed to launch (exit code: {0})', exitCode));
|
||||
}
|
||||
} else {
|
||||
if (this._configHelper.config.showExitAlert) {
|
||||
this._notificationService.error(exitCodeMessage);
|
||||
this._notificationService.error(exitCodeMessage!);
|
||||
} else {
|
||||
console.warn(exitCodeMessage);
|
||||
console.warn(exitCodeMessage!);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1114,22 +1101,17 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
}
|
||||
|
||||
private _onLineFeed(): void {
|
||||
const buffer = this._xterm.buffer;
|
||||
const newLine = buffer.getLine(buffer.baseY + buffer.cursorY);
|
||||
if (newLine && !newLine.isWrapped) {
|
||||
this._sendLineData(buffer, buffer.baseY + buffer.cursorY - 1);
|
||||
const buffer = (<any>this._xterm._core.buffer);
|
||||
const newLine = buffer.lines.get(buffer.ybase + buffer.y);
|
||||
if (!newLine.isWrapped) {
|
||||
this._sendLineData(buffer, buffer.ybase + buffer.y - 1);
|
||||
}
|
||||
}
|
||||
|
||||
private _onCursorMove(): void {
|
||||
const buffer = this._xterm.buffer;
|
||||
this._sendLineData(buffer, buffer.baseY + buffer.cursorY);
|
||||
}
|
||||
|
||||
private _sendLineData(buffer: IBuffer, lineIndex: number): void {
|
||||
let lineData = buffer.getLine(lineIndex)!.translateToString(true);
|
||||
while (lineIndex >= 0 && buffer.getLine(lineIndex--)!.isWrapped) {
|
||||
lineData = buffer.getLine(lineIndex)!.translateToString(false) + lineData;
|
||||
private _sendLineData(buffer: any, lineIndex: number): void {
|
||||
let lineData = buffer.translateBufferLineToString(lineIndex, true);
|
||||
while (lineIndex >= 0 && buffer.lines.get(lineIndex--).isWrapped) {
|
||||
lineData = buffer.translateBufferLineToString(lineIndex, false) + lineData;
|
||||
}
|
||||
this._onLineData.fire(lineData);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import * as dom from 'vs/base/browser/dom';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { Action, IAction } from 'vs/base/common/actions';
|
||||
import { IActionViewItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -16,7 +16,7 @@ import { ITerminalService, TERMINAL_PANEL_ID } from 'vs/workbench/contrib/termin
|
||||
import { IThemeService, ITheme, registerThemingParticipant, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { TerminalFindWidget } from 'vs/workbench/contrib/terminal/browser/terminalFindWidget';
|
||||
import { editorHoverBackground, editorHoverBorder, editorForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { KillTerminalAction, SwitchTerminalAction, SwitchTerminalActionViewItem, CopyTerminalSelectionAction, TerminalPasteAction, ClearTerminalAction, SelectAllTerminalAction, CreateNewTerminalAction, SplitTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions';
|
||||
import { KillTerminalAction, SwitchTerminalAction, SwitchTerminalActionItem, CopyTerminalSelectionAction, TerminalPasteAction, ClearTerminalAction, SelectAllTerminalAction, CreateNewTerminalAction, SplitTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions';
|
||||
import { Panel } from 'vs/workbench/browser/panel';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
@@ -161,12 +161,12 @@ export class TerminalPanel extends Panel {
|
||||
return this._contextMenuActions;
|
||||
}
|
||||
|
||||
public getActionViewItem(action: Action): IActionViewItem | undefined {
|
||||
public getActionItem(action: Action): IActionItem | undefined {
|
||||
if (action.id === SwitchTerminalAction.ID) {
|
||||
return this._instantiationService.createInstance(SwitchTerminalActionViewItem, action);
|
||||
return this._instantiationService.createInstance(SwitchTerminalActionItem, action);
|
||||
}
|
||||
|
||||
return super.getActionViewItem(action);
|
||||
return super.getActionItem(action);
|
||||
}
|
||||
|
||||
public focus(): void {
|
||||
|
||||
@@ -169,7 +169,7 @@ export class TerminalProcessManager implements ITerminalProcessManager {
|
||||
|
||||
private _launchProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number): ITerminalChildProcess {
|
||||
if (!shellLaunchConfig.executable) {
|
||||
this._configHelper.mergeDefaultShellPathAndArgs(shellLaunchConfig, this._terminalInstanceService.getDefaultShell(platform.platform));
|
||||
this._configHelper.mergeDefaultShellPathAndArgs(shellLaunchConfig);
|
||||
}
|
||||
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
|
||||
@@ -181,7 +181,8 @@ export class TerminalProcessManager implements ITerminalProcessManager {
|
||||
const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions();
|
||||
const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables);
|
||||
|
||||
const useConpty = this._configHelper.config.windowsEnableConpty;
|
||||
this._logService.debug(`Terminal process launching`, shellLaunchConfig, initialCwd, cols, rows, env);
|
||||
const useConpty = (shellLaunchConfig.forceWinpty !== true) && this._configHelper.config.windowsEnableConpty;
|
||||
return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, useConpty);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export abstract class TerminalService extends CommonTerminalService implements I
|
||||
super(contextKeyService, panelService, lifecycleService, storageService, notificationService, dialogService, extensionService, fileService, remoteAgentService);
|
||||
}
|
||||
|
||||
public abstract getDefaultShell(p: platform.Platform): string;
|
||||
protected abstract _getDefaultShell(p: platform.Platform): string;
|
||||
|
||||
public createInstance(terminalFocusContextKey: IContextKey<boolean>, configHelper: ITerminalConfigHelper, container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance {
|
||||
const instance = this._instantiationService.createInstance(TerminalInstance, terminalFocusContextKey, configHelper, container, shellLaunchConfig);
|
||||
@@ -101,7 +101,7 @@ export abstract class TerminalService extends CommonTerminalService implements I
|
||||
}
|
||||
|
||||
// Never suggest if the setting is non-default already (ie. they set the setting manually)
|
||||
if (this.configHelper.config.shell.windows !== this.getDefaultShell(platform.Platform.Windows)) {
|
||||
if (this.configHelper.config.shell.windows !== this._getDefaultShell(platform.Platform.Windows)) {
|
||||
this._storageService.store(NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, true, StorageScope.GLOBAL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@ export const TERMINAL_CONFIG_SECTION = 'terminal.integrated';
|
||||
export const DEFAULT_LETTER_SPACING = 0;
|
||||
export const MINIMUM_LETTER_SPACING = -5;
|
||||
export const DEFAULT_LINE_HEIGHT = 1;
|
||||
export const SHELL_PATH_INVALID_EXIT_CODE = -1;
|
||||
|
||||
export type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
|
||||
|
||||
@@ -113,7 +112,7 @@ export interface ITerminalConfigHelper {
|
||||
/**
|
||||
* Merges the default shell path and args into the provided launch configuration
|
||||
*/
|
||||
mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, platformOverride?: platform.Platform): void;
|
||||
mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, platformOverride?: platform.Platform): void;
|
||||
/** Sets whether a workspace shell configuration is allowed or not */
|
||||
setWorkspaceShellAllowed(isAllowed: boolean): void;
|
||||
checkWorkspaceShellPermissions(osOverride?: platform.OperatingSystem): boolean;
|
||||
@@ -193,6 +192,12 @@ export interface IShellLaunchConfig {
|
||||
* provided as nothing will be inherited from the process or any configuration.
|
||||
*/
|
||||
strictEnv?: boolean;
|
||||
|
||||
/**
|
||||
* Moving forward, conpty will be the default. However, there are cases where conpty is not ready
|
||||
* to be the default. This property will force winpty to be used, even when conpty would normally be used.
|
||||
*/
|
||||
forceWinpty?: boolean;
|
||||
}
|
||||
|
||||
export interface ITerminalService {
|
||||
@@ -254,7 +259,6 @@ export interface ITerminalService {
|
||||
findPrevious(): void;
|
||||
|
||||
setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void;
|
||||
getDefaultShell(p: platform.Platform): string;
|
||||
selectDefaultWindowsShell(): Promise<string | undefined>;
|
||||
setWorkspaceShellAllowed(isAllowed: boolean): void;
|
||||
|
||||
@@ -690,6 +694,7 @@ export const enum ProcessState {
|
||||
KILLED_BY_PROCESS
|
||||
}
|
||||
|
||||
|
||||
export interface ITerminalProcessExtHostProxy extends IDisposable {
|
||||
readonly terminalId: number;
|
||||
|
||||
|
||||
@@ -164,14 +164,15 @@ export function mergeDefaultShellPathAndArgs(
|
||||
shell: IShellLaunchConfig,
|
||||
fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined },
|
||||
isWorkspaceShellAllowed: boolean,
|
||||
defaultShell: string,
|
||||
platformOverride: platform.Platform = platform.platform
|
||||
): void {
|
||||
const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux';
|
||||
const shellConfigValue = fetchSetting(`terminal.integrated.shell.${platformKey}`);
|
||||
// const shellConfigValue = this._workspaceConfigurationService.inspect<string>(`terminal.integrated.shell.${platformKey}`);
|
||||
const shellArgsConfigValue = fetchSetting(`terminal.integrated.shellArgs.${platformKey}`);
|
||||
// const shellArgsConfigValue = this._workspaceConfigurationService.inspect<string[]>(`terminal.integrated.shellArgs.${platformKey}`);
|
||||
|
||||
shell.executable = (isWorkspaceShellAllowed ? <string>shellConfigValue.value : <string>shellConfigValue.user) || (<string | null>shellConfigValue.default || defaultShell);
|
||||
shell.executable = (isWorkspaceShellAllowed ? <string>shellConfigValue.value : <string>shellConfigValue.user) || <string>shellConfigValue.default;
|
||||
shell.args = (isWorkspaceShellAllowed ? <string[]>shellArgsConfigValue.value : <string[]>shellArgsConfigValue.user) || <string[]>shellArgsConfigValue.default;
|
||||
|
||||
// Change Sysnative to System32 if the OS is Windows but NOT WoW64. It's
|
||||
|
||||
@@ -17,7 +17,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
||||
import { isWindows, Platform } from 'vs/base/common/platform';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
@@ -106,7 +106,6 @@ export abstract class TerminalService implements ITerminalService {
|
||||
|
||||
public abstract createTerminal(shell?: IShellLaunchConfig, wasNewTerminalAction?: boolean): ITerminalInstance;
|
||||
public abstract createInstance(terminalFocusContextKey: IContextKey<boolean>, configHelper: ITerminalConfigHelper, container: HTMLElement, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance;
|
||||
public abstract getDefaultShell(platform: Platform): string;
|
||||
public abstract selectDefaultWindowsShell(): Promise<string | undefined>;
|
||||
public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void;
|
||||
|
||||
@@ -427,9 +426,6 @@ export abstract class TerminalService implements ITerminalService {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
const current = potentialPaths.shift();
|
||||
if (current! === '') {
|
||||
return this._validateShellPaths(label, potentialPaths);
|
||||
}
|
||||
return this._fileService.exists(URI.file(current!)).then(exists => {
|
||||
if (!exists) {
|
||||
return this._validateShellPaths(label, potentialPaths);
|
||||
|
||||
@@ -22,19 +22,19 @@ configurationRegistry.registerConfiguration({
|
||||
type: 'object',
|
||||
properties: {
|
||||
'terminal.integrated.shell.linux': {
|
||||
markdownDescription: nls.localize('terminal.integrated.shell.linux', "The path of the shell that the terminal uses on Linux (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", getDefaultShell(platform.Platform.Linux)),
|
||||
type: ['string', 'null'],
|
||||
default: null
|
||||
markdownDescription: nls.localize('terminal.integrated.shell.linux', "The path of the shell that the terminal uses on Linux. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."),
|
||||
type: 'string',
|
||||
default: getDefaultShell(platform.Platform.Linux)
|
||||
},
|
||||
'terminal.integrated.shell.osx': {
|
||||
markdownDescription: nls.localize('terminal.integrated.shell.osx', "The path of the shell that the terminal uses on macOS (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", getDefaultShell(platform.Platform.Mac)),
|
||||
type: ['string', 'null'],
|
||||
default: null
|
||||
markdownDescription: nls.localize('terminal.integrated.shell.osx', "The path of the shell that the terminal uses on macOS. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."),
|
||||
type: 'string',
|
||||
default: getDefaultShell(platform.Platform.Mac)
|
||||
},
|
||||
'terminal.integrated.shell.windows': {
|
||||
markdownDescription: nls.localize('terminal.integrated.shell.windows', "The path of the shell that the terminal uses on Windows (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", getDefaultShell(platform.Platform.Windows)),
|
||||
type: ['string', 'null'],
|
||||
default: null
|
||||
markdownDescription: nls.localize('terminal.integrated.shell.windows', "The path of the shell that the terminal uses on Windows. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."),
|
||||
type: 'string',
|
||||
default: getDefaultShell(platform.Platform.Windows)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -10,10 +10,9 @@ import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITermina
|
||||
import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/browser/terminalProcessManager';
|
||||
import { IProcessEnvironment, Platform } from 'vs/base/common/platform';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess';
|
||||
import * as typeAheadAddon from 'vs/workbench/contrib/terminal/browser/terminalTypeAheadAddon';
|
||||
import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal';
|
||||
|
||||
let Terminal: typeof XTermTerminal;
|
||||
|
||||
@@ -36,6 +35,7 @@ export class TerminalInstanceService implements ITerminalInstanceService {
|
||||
// Enable xterm.js addons
|
||||
Terminal.applyAddon(require.__$__nodeRequire('vscode-xterm/lib/addons/search/search'));
|
||||
Terminal.applyAddon(require.__$__nodeRequire('vscode-xterm/lib/addons/webLinks/webLinks'));
|
||||
Terminal.applyAddon(require.__$__nodeRequire('vscode-xterm/lib/addons/winptyCompat/winptyCompat'));
|
||||
Terminal.applyAddon(typeAheadAddon);
|
||||
// Localize strings
|
||||
Terminal.strings.blankLine = nls.localize('terminal.integrated.a11yBlankLine', 'Blank line');
|
||||
@@ -54,10 +54,6 @@ export class TerminalInstanceService implements ITerminalInstanceService {
|
||||
}
|
||||
|
||||
public createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess {
|
||||
return this._instantiationService.createInstance(TerminalProcess, shellLaunchConfig, cwd, cols, rows, env, windowsEnableConpty);
|
||||
return new TerminalProcess(shellLaunchConfig, cwd, cols, rows, env, windowsEnableConpty);
|
||||
}
|
||||
|
||||
public getDefaultShell(p: Platform): string {
|
||||
return getDefaultShell(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ export class TerminalService extends BrowserTerminalService implements ITerminal
|
||||
});
|
||||
}
|
||||
|
||||
public getDefaultShell(p: platform.Platform): string {
|
||||
protected _getDefaultShell(p: platform.Platform): string {
|
||||
return getDefaultShell(p);
|
||||
}
|
||||
|
||||
@@ -117,28 +117,7 @@ export class TerminalService extends BrowserTerminalService implements ITerminal
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the executable file path of shell from registry.
|
||||
* @param shellName The shell name to get the executable file path
|
||||
* @returns `[]` or `[ 'path' ]`
|
||||
*/
|
||||
private async _getShellPathFromRegistry(shellName: string): Promise<string[]> {
|
||||
const Registry = await import('vscode-windows-registry');
|
||||
|
||||
try {
|
||||
const shellPath = Registry.GetStringRegKey('HKEY_LOCAL_MACHINE', `SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\${shellName}.exe`, '');
|
||||
|
||||
if (shellPath === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [shellPath];
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private async _detectWindowsShells(): Promise<IQuickPickItem[]> {
|
||||
private _detectWindowsShells(): Promise<IQuickPickItem[]> {
|
||||
// Determine the correct System32 path. We want to point to Sysnative
|
||||
// when the 32-bit version of VS Code is running on a 64-bit machine.
|
||||
// The reason for this is because PowerShell's important PSReadline
|
||||
@@ -155,7 +134,6 @@ export class TerminalService extends BrowserTerminalService implements ITerminal
|
||||
const expectedLocations = {
|
||||
'Command Prompt': [`${system32Path}\\cmd.exe`],
|
||||
PowerShell: [`${system32Path}\\WindowsPowerShell\\v1.0\\powershell.exe`],
|
||||
'PowerShell Core': await this._getShellPathFromRegistry('pwsh'),
|
||||
'WSL Bash': [`${system32Path}\\${useWSLexe ? 'wsl.exe' : 'bash.exe'}`],
|
||||
'Git Bash': [
|
||||
`${process.env['ProgramW6432']}\\Git\\bin\\bash.exe`,
|
||||
|
||||
@@ -13,12 +13,11 @@ import { getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/termin
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IShellLaunchConfig, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { exec } from 'child_process';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
private _exitCode: number;
|
||||
private _closeTimeout: any;
|
||||
private _ptyProcess: pty.IPty | undefined;
|
||||
private _ptyProcess: pty.IPty;
|
||||
private _currentTitle: string = '';
|
||||
private _processStartupComplete: Promise<void>;
|
||||
private _isDisposed: boolean = false;
|
||||
@@ -40,8 +39,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
cols: number,
|
||||
rows: number,
|
||||
env: platform.IProcessEnvironment,
|
||||
windowsEnableConpty: boolean,
|
||||
@ILogService private readonly _logService: ILogService
|
||||
windowsEnableConpty: boolean
|
||||
) {
|
||||
let shellName: string;
|
||||
if (os.platform() === 'win32') {
|
||||
@@ -71,42 +69,37 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
experimentalUseConpty: useConpty
|
||||
};
|
||||
|
||||
// TODO: Need to verify whether executable is on $PATH, otherwise things like cmd.exe will break
|
||||
// fs.stat(shellLaunchConfig.executable!, (err) => {
|
||||
// if (err && err.code === 'ENOENT') {
|
||||
// this._exitCode = SHELL_PATH_INVALID_EXIT_CODE;
|
||||
// this._queueProcessExit();
|
||||
// this._processStartupComplete = Promise.resolve(undefined);
|
||||
// return;
|
||||
// }
|
||||
this.setupPtyProcess(shellLaunchConfig, options);
|
||||
// });
|
||||
}
|
||||
|
||||
private setupPtyProcess(shellLaunchConfig: IShellLaunchConfig, options: pty.IPtyForkOptions): void {
|
||||
const args = shellLaunchConfig.args || [];
|
||||
this._logService.trace('IPty#spawn', shellLaunchConfig.executable, args, options);
|
||||
const ptyProcess = pty.spawn(shellLaunchConfig.executable!, args, options);
|
||||
this._ptyProcess = ptyProcess;
|
||||
this._processStartupComplete = new Promise<void>(c => {
|
||||
this.onProcessIdReady(() => c());
|
||||
});
|
||||
ptyProcess.on('data', (data) => {
|
||||
try {
|
||||
this._ptyProcess = pty.spawn(shellLaunchConfig.executable!, shellLaunchConfig.args || [], options);
|
||||
this._processStartupComplete = new Promise<void>(c => {
|
||||
this.onProcessIdReady((pid) => {
|
||||
c();
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
// The only time this is expected to happen is when the file specified to launch with does not exist.
|
||||
this._exitCode = 2;
|
||||
this._queueProcessExit();
|
||||
this._processStartupComplete = Promise.resolve(undefined);
|
||||
return;
|
||||
}
|
||||
this._ptyProcess.on('data', (data) => {
|
||||
this._onProcessData.fire(data);
|
||||
if (this._closeTimeout) {
|
||||
clearTimeout(this._closeTimeout);
|
||||
this._queueProcessExit();
|
||||
}
|
||||
});
|
||||
ptyProcess.on('exit', (code) => {
|
||||
this._ptyProcess.on('exit', (code) => {
|
||||
this._exitCode = code;
|
||||
this._queueProcessExit();
|
||||
});
|
||||
this._setupTitlePolling(ptyProcess);
|
||||
|
||||
// TODO: We should no longer need to delay this since pty.spawn is sync
|
||||
setTimeout(() => {
|
||||
this._sendProcessId(ptyProcess);
|
||||
this._sendProcessId();
|
||||
}, 500);
|
||||
this._setupTitlePolling();
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
@@ -121,15 +114,15 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
this._onProcessTitleChanged.dispose();
|
||||
}
|
||||
|
||||
private _setupTitlePolling(ptyProcess: pty.IPty) {
|
||||
private _setupTitlePolling() {
|
||||
// Send initial timeout async to give event listeners a chance to init
|
||||
setTimeout(() => {
|
||||
this._sendProcessTitle(ptyProcess);
|
||||
this._sendProcessTitle();
|
||||
}, 0);
|
||||
// Setup polling
|
||||
this._titleInterval = setInterval(() => {
|
||||
if (this._currentTitle !== ptyProcess.process) {
|
||||
this._sendProcessTitle(ptyProcess);
|
||||
if (this._currentTitle !== this._ptyProcess.process) {
|
||||
this._sendProcessTitle();
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
@@ -153,10 +146,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
// Attempt to kill the pty, it may have already been killed at this
|
||||
// point but we want to make sure
|
||||
try {
|
||||
if (this._ptyProcess) {
|
||||
this._logService.trace('IPty#kill');
|
||||
this._ptyProcess.kill();
|
||||
}
|
||||
this._ptyProcess.kill();
|
||||
} catch (ex) {
|
||||
// Swallow, the pty has already been killed
|
||||
}
|
||||
@@ -165,15 +155,15 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
});
|
||||
}
|
||||
|
||||
private _sendProcessId(ptyProcess: pty.IPty) {
|
||||
this._onProcessIdReady.fire(ptyProcess.pid);
|
||||
private _sendProcessId() {
|
||||
this._onProcessIdReady.fire(this._ptyProcess.pid);
|
||||
}
|
||||
|
||||
private _sendProcessTitle(ptyProcess: pty.IPty): void {
|
||||
private _sendProcessTitle(): void {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
this._currentTitle = ptyProcess.process;
|
||||
this._currentTitle = this._ptyProcess.process;
|
||||
this._onProcessTitleChanged.fire(this._currentTitle);
|
||||
}
|
||||
|
||||
@@ -186,10 +176,9 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
}
|
||||
|
||||
public input(data: string): void {
|
||||
if (this._isDisposed || !this._ptyProcess) {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
this._logService.trace('IPty#write', data);
|
||||
this._ptyProcess.write(data);
|
||||
}
|
||||
|
||||
@@ -199,12 +188,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
}
|
||||
// Ensure that cols and rows are always >= 1, this prevents a native
|
||||
// exception in winpty.
|
||||
if (this._ptyProcess) {
|
||||
cols = Math.max(cols, 1);
|
||||
rows = Math.max(rows, 1);
|
||||
this._logService.trace('IPty#resize', cols, rows);
|
||||
this._ptyProcess.resize(cols, rows);
|
||||
}
|
||||
this._ptyProcess.resize(Math.max(cols, 1), Math.max(rows, 1));
|
||||
}
|
||||
|
||||
public getInitialCwd(): Promise<string> {
|
||||
@@ -214,11 +198,6 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
public getCwd(): Promise<string> {
|
||||
if (platform.isMacintosh) {
|
||||
return new Promise<string>(resolve => {
|
||||
if (!this._ptyProcess) {
|
||||
resolve(this._initialCwd);
|
||||
return;
|
||||
}
|
||||
this._logService.trace('IPty#pid');
|
||||
exec('lsof -p ' + this._ptyProcess.pid + ' | grep cwd', (error, stdout, stderr) => {
|
||||
if (stdout !== '') {
|
||||
resolve(stdout.substring(stdout.indexOf('/'), stdout.length - 1));
|
||||
@@ -229,11 +208,6 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
|
||||
if (platform.isLinux) {
|
||||
return new Promise<string>(resolve => {
|
||||
if (!this._ptyProcess) {
|
||||
resolve(this._initialCwd);
|
||||
return;
|
||||
}
|
||||
this._logService.trace('IPty#pid');
|
||||
fs.readlink('/proc/' + this._ptyProcess.pid + '/cwd', (err, linkedstr) => {
|
||||
if (err) {
|
||||
resolve(this._initialCwd);
|
||||
|
||||
@@ -61,15 +61,15 @@ export class WindowsShellHelper implements IWindowsShellHelper {
|
||||
// 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(() => {
|
||||
this._xterm.on('linefeed', () => this._newLineFeed = true);
|
||||
this._xterm.on('cursormove', () => {
|
||||
if (this._newLineFeed) {
|
||||
this._onCheckShell.fire(undefined);
|
||||
}
|
||||
});
|
||||
|
||||
// Fire a new check for the shell when any key is pressed.
|
||||
this._xterm.onKey(() => this._onCheckShell.fire(undefined));
|
||||
this._xterm.on('keypress', () => this._onCheckShell.fire(undefined));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user