mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-22 12:50:29 -04:00
Vscode merge (#4582)
* Merge from vscode 37cb23d3dd4f9433d56d4ba5ea3203580719a0bd * fix issues with merges * bump node version in azpipe * replace license headers * remove duplicate launch task * fix build errors * fix build errors * fix tslint issues * working through package and linux build issues * more work * wip * fix packaged builds * working through linux build errors * wip * wip * wip * fix mac and linux file limits * iterate linux pipeline * disable editor typing * revert series to parallel * remove optimize vscode from linux * fix linting issues * revert testing change * add work round for new node * readd packaging for extensions * fix issue with angular not resolving decorator dependencies
This commit is contained in:
136
src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts
Normal file
136
src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { ITerminalInstance, IWindowsShellHelper } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { Terminal as XTermTerminal } from 'vscode-xterm';
|
||||
import WindowsProcessTreeType = require('windows-process-tree');
|
||||
|
||||
const SHELL_EXECUTABLES = [
|
||||
'cmd.exe',
|
||||
'powershell.exe',
|
||||
'bash.exe',
|
||||
'wsl.exe',
|
||||
'ubuntu.exe',
|
||||
'ubuntu1804.exe',
|
||||
'kali.exe',
|
||||
'debian.exe',
|
||||
'opensuse-42.exe',
|
||||
'sles-12.exe'
|
||||
];
|
||||
|
||||
let windowsProcessTree: typeof WindowsProcessTreeType;
|
||||
|
||||
export class WindowsShellHelper implements IWindowsShellHelper {
|
||||
private _onCheckShell: Emitter<Promise<string> | undefined>;
|
||||
private _isDisposed: boolean;
|
||||
private _currentRequest: Promise<string> | null;
|
||||
private _newLineFeed: boolean;
|
||||
|
||||
public constructor(
|
||||
private _rootProcessId: number,
|
||||
private _terminalInstance: ITerminalInstance,
|
||||
private _xterm: XTermTerminal
|
||||
) {
|
||||
if (!platform.isWindows) {
|
||||
throw new Error(`WindowsShellHelper cannot be instantiated on ${platform.platform}`);
|
||||
}
|
||||
|
||||
this._isDisposed = false;
|
||||
|
||||
(import('windows-process-tree')).then(mod => {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
windowsProcessTree = mod;
|
||||
this._onCheckShell = new Emitter<Promise<string>>();
|
||||
// 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)(() => {
|
||||
setTimeout(() => {
|
||||
this.checkShell();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
// 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.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.on('keypress', () => this._onCheckShell.fire(undefined));
|
||||
});
|
||||
}
|
||||
|
||||
private checkShell(): void {
|
||||
if (platform.isWindows && this._terminalInstance.isTitleSetByProcess) {
|
||||
this.getShellName().then(title => {
|
||||
if (!this._isDisposed) {
|
||||
this._terminalInstance.setTitle(title, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private traverseTree(tree: any): string {
|
||||
if (!tree) {
|
||||
return '';
|
||||
}
|
||||
if (SHELL_EXECUTABLES.indexOf(tree.name) === -1) {
|
||||
return tree.name;
|
||||
}
|
||||
if (!tree.children || tree.children.length === 0) {
|
||||
return tree.name;
|
||||
}
|
||||
let favouriteChild = 0;
|
||||
for (; favouriteChild < tree.children.length; favouriteChild++) {
|
||||
const child = tree.children[favouriteChild];
|
||||
if (!child.children || child.children.length === 0) {
|
||||
break;
|
||||
}
|
||||
if (child.children[0].name !== 'conhost.exe') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (favouriteChild >= tree.children.length) {
|
||||
return tree.name;
|
||||
}
|
||||
return this.traverseTree(tree.children[favouriteChild]);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._isDisposed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the innermost shell executable running in the terminal
|
||||
*/
|
||||
public getShellName(): Promise<string> {
|
||||
if (this._isDisposed) {
|
||||
return Promise.resolve('');
|
||||
}
|
||||
// Prevent multiple requests at once, instead return current request
|
||||
if (this._currentRequest) {
|
||||
return this._currentRequest;
|
||||
}
|
||||
this._currentRequest = new Promise<string>(resolve => {
|
||||
windowsProcessTree.getProcessTree(this._rootProcessId, (tree) => {
|
||||
const name = this.traverseTree(tree);
|
||||
this._currentRequest = null;
|
||||
resolve(name);
|
||||
});
|
||||
});
|
||||
return this._currentRequest;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user