Change:
From
For January we decided to keep the task in the core. So there is no need to make this 'public' API now. May be it would be good to first experiment a little with the new API.
just to make sure, were you thinking of using a prompt (press any key to close) that can be reused? Or a terminal that executes something, the pty process dies and just sits there ("dead") until another task command is sent?
I would like to achieve the following: create a new terminal and allow terminal reuse (could be an additional option) without actually running a terminal right away (if necessary we could run it as well) run a command in the terminal. This will create the actual shell process. Usually the shell would be started with /c receive an exit event when the shell exists reuse the terminal to run another command in the terminal which creates a new shell process. Use case if for a build task: if the user runs the build tasks 3 times in a row I would like to have one terminal (e.g. on entry in the drop down in the terminal pane) which contains the output of all three task runs.
I have one additional question. Does the terminal require to run a shell or would the terminal be able to run any other arbitrary process (for example a ).
I got it working to run an arbitrary program. Only drawback is that I needed to specify the full path to the program (e.g. ). Any idea why this is the case?
do you mean the shell path you're using is and it's not working like that? I guess the resolution stuff is contained within , I would think it would probably be safest to always wrap the command within or . Wrapping the command means the process will die when it finishes so I don't see a downside?
the only problem is argument passing with spaces contained. If you call node directly then you pass the args as a string[]. If you call the for example you need to construct a single string with proper arg quoting to ensure everything works when for example the command to call contains spaces. And you save a process :-)
could this be useful for Python terminal execution?

Discussion:
* null means the process was killed as a result of the ITerminalInstance being disposed. */ onExit(listener: (exitCode: number) => void): void; <ins> /** * Immediately kills the terminal's current pty process and launches a new one to replace it. * * @param shell The new launch configuration. */ reuseTerminal(shell?: IShellLaunchConfig): void; </ins> }

private _processId: number; private _skipTerminalCommands: string[]; private _title: string; <del> private _toDispose: lifecycle.IDisposable[]; </del> <ins> private _instanceDisposables: lifecycle.IDisposable[]; private _processDisposables: lifecycle.IDisposable[]; </ins> private _wrapperElement: HTMLDivElement; private _xterm: any; private _xtermElement: HTMLDivElement;

@IPanelService private _panelService: IPanelService, @IWorkspaceContextService private _contextService: IWorkspaceContextService ) { <del> this._toDispose = []; </del> <ins> this._instanceDisposables = []; this._processDisposables = []; </ins> this._skipTerminalCommands = []; this._isExiting = false; this._hadFocusOnExit = false;

} public addDisposable(disposable: lifecycle.IDisposable): void { <del> this._toDispose.push(disposable); </del> <ins> this._instanceDisposables.push(disposable); </ins> } public attachToElement(container: HTMLElement): void {

}); this._xterm.open(this._xtermElement); <del> this._process.on('message', (message) => { if (!this._xterm) { return; } if (message.type === 'data') { this._xterm.write(message.content); } }); </del> <ins> this._process.on('message', (message) => this._sendPtyDataToXterm(message)); </ins> this._xterm.on('data', (data) => { <del> this._process.send({ event: 'input', data: this._sanitizeInput(data) }); </del> <ins> if (this._process) { this._process.send({ event: 'input', data: this._sanitizeInput(data) }); } </ins> return false; }); this._xterm.attachCustomKeydownHandler((event: KeyboardEvent) => {

return false; } }); <del> (<HTMLElement>this._xterm.element).addEventListener('mouseup', event => { </del> <ins> this._instanceDisposables.push(DOM.addDisposableListener(this._xterm.element, 'mouseup', (event: KeyboardEvent) => { </ins> // Wait until mouseup has propogated through the DOM before evaluating the new selection // state. setTimeout(() => { this._refreshSelectionContextKey(); }, 0); <del> }); </del> <ins> })); </ins> // xterm.js currently drops selection on keyup as we need to handle this case. <del> (<HTMLElement>this._xterm.element).addEventListener('keyup', event => { </del> <ins> this._instanceDisposables.push(DOM.addDisposableListener(this._xterm.element, 'keyup', (event: KeyboardEvent) => { </ins> // Wait until keyup has propogated through the DOM before evaluating the new selection // state. setTimeout(() => { this._refreshSelectionContextKey(); }, 0); <del> }); </del> <ins> })); </ins> const xtermHelper: HTMLElement = this._xterm.element.querySelector('.xterm-helpers'); const focusTrap: HTMLElement = document.createElement('div'); focusTrap.setAttribute('tabindex', '0'); DOM.addClass(focusTrap, 'focus-trap'); <del> focusTrap.addEventListener('focus', function (event: FocusEvent) { </del> <ins> this._instanceDisposables.push(DOM.addDisposableListener(focusTrap, 'focus', (event: FocusEvent) => { </ins> let currentElement = focusTrap; while (!DOM.hasClass(currentElement, 'part')) { currentElement = currentElement.parentElement; } const hidePanelElement = <HTMLElement>currentElement.querySelector('.hide-panel-action'); hidePanelElement.focus(); <del> }); </del> <ins> })); </ins> xtermHelper.insertBefore(focusTrap, this._xterm.textarea); <del> this._toDispose.push(DOM.addDisposableListener(this._xterm.textarea, 'focus', (event: KeyboardEvent) => { </del> <ins> this._instanceDisposables.push(DOM.addDisposableListener(this._xterm.textarea, 'focus', (event: KeyboardEvent) => { </ins> this._terminalFocusContextKey.set(true); })); <del> this._toDispose.push(DOM.addDisposableListener(this._xterm.textarea, 'blur', (event: KeyboardEvent) => { </del> <ins> this._instanceDisposables.push(DOM.addDisposableListener(this._xterm.textarea, 'blur', (event: KeyboardEvent) => { </ins> this._terminalFocusContextKey.reset(); this._refreshSelectionContextKey(); })); <del> this._toDispose.push(DOM.addDisposableListener(this._xterm.element, 'focus', (event: KeyboardEvent) => { </del> <ins> this._instanceDisposables.push(DOM.addDisposableListener(this._xterm.element, 'focus', (event: KeyboardEvent) => { </ins> this._terminalFocusContextKey.set(true); })); <del> this._toDispose.push(DOM.addDisposableListener(this._xterm.element, 'blur', (event: KeyboardEvent) => { </del> <ins> this._instanceDisposables.push(DOM.addDisposableListener(this._xterm.element, 'blur', (event: KeyboardEvent) => { </ins> this._terminalFocusContextKey.reset(); this._refreshSelectionContextKey(); }));

this._process = null; } this._onDisposed.fire(this); <del> this._toDispose = lifecycle.dispose(this._toDispose); </del> <ins> this._processDisposables = lifecycle.dispose(this._processDisposables); this._instanceDisposables = lifecycle.dispose(this._instanceDisposables); </ins> } public focus(force?: boolean): void {

}, LAUNCHING_DURATION); } <ins> private _sendPtyDataToXterm(message: { type: string, content: string }): void { if (!this._xterm) { return; } if (message.type === 'data') { this._xterm.write(message.content); } } </ins> private _onPtyProcessExit(exitCode: number): void { // Prevent dispose functions being triggered multiple times if (this._isExiting) {

this._xterm.writeln(nls.localize('terminal.integrated.waitOnExit', 'Press any key to close the terminal')); // Disable all input if the terminal is exiting and listen for next keypress this._xterm.setOption('disableStdin', true); <del> (<HTMLElement>this._xterm.textarea).addEventListener('keypress', (data) => { </del> <ins> this._processDisposables.push(DOM.addDisposableListener(this._xterm.textarea, 'keypress', () => { </ins> this.dispose(); <del> }); </del> <ins> })); </ins> } else { this.dispose(); if (exitCode) {

} } <ins> public reuseTerminal(shell?: IShellLaunchConfig): void { // Kill and clean up old process if (this._process) { this._process.removeAllListeners('exit'); if (this._process.connected) { this._process.kill(); } this._process = null; } lifecycle.dispose(this._processDisposables); this._processDisposables = []; // Ensure new processes' output starts at start of new line this._xterm.write('nx1b[G'); // Initialize new process this._createProcess(this._contextService.getWorkspace(), shell.name, shell); this._process.on('message', (message) => this._sendPtyDataToXterm(message)); // Clean up waitOnExit state if (this._isExiting && this._shellLaunchConfig.waitOnExit) { this._xterm.setOption('disableStdin', false); this._isExiting = false; } // Set the new shell launch config this._shellLaunchConfig = shell; } </ins> // TODO: This should be private/protected // TODO: locale should not be optional public static createTerminalEnv(parentEnv: IStringDictionary<string>, shell: IShellLaunchConfig, cwd: string, locale?: string): IStringDictionary<string> {