Skip to content

Commit 63a2a8d

Browse files
authored
Preserve terminal visibility across background session restart
1 parent 41162be commit 63a2a8d

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

src/process.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ export class PowerShellProcess {
238238
this.consoleTerminal?.show(preserveFocus);
239239
}
240240

241+
public isTerminalActive(): boolean {
242+
return this.consoleTerminal === vscode.window.activeTerminal;
243+
}
244+
241245
public dispose(): void {
242246
this.logger.writeDebug(
243247
`Disposing PowerShell process with PID: ${this.pid}`,

src/session.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,11 @@ export class SessionManager implements Middleware {
347347

348348
private async restartSession(exeNameOverride?: string): Promise<void> {
349349
this.logger.write("Restarting session...");
350+
const shouldRevealTerminalAfterRestart =
351+
this.languageServerProcess?.isTerminalActive() === true &&
352+
vscode.workspace
353+
.getConfiguration("powershell.integratedConsole")
354+
.get<boolean>("startInBackground") === true;
350355
await this.stop();
351356

352357
if (exeNameOverride) {
@@ -361,6 +366,9 @@ export class SessionManager implements Middleware {
361366
}
362367

363368
await this.start();
369+
if (shouldRevealTerminalAfterRestart) {
370+
this.languageServerProcess?.showTerminal(true);
371+
}
364372
}
365373

366374
/** In Development mode, write the PID to a file where the parent session can find it, to attach the dotnet debugger. */

test/core/session.test.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as assert from "assert";
66
import Sinon from "sinon";
77
import * as vscode from "vscode";
88
import type { DocumentSelector } from "vscode-languageclient";
9+
import { PowerShellProcess } from "../../src/process";
910
import {
1011
type IPowerShellVersionDetails,
1112
SessionManager,
@@ -200,6 +201,89 @@ describe("SessionManager.getVersionDetails", () => {
200201
});
201202
});
202203

204+
describe("SessionManager.restartSession", () => {
205+
afterEach(() => {
206+
Sinon.restore();
207+
});
208+
209+
it("re-shows the terminal after restart when it was active in background mode", async () => {
210+
const manager = makeManager();
211+
const oldProcess = stubInterface<PowerShellProcess>({
212+
isTerminalActive: () => true,
213+
});
214+
const showTerminal = Sinon.spy();
215+
const newProcess = stubInterface<PowerShellProcess>({
216+
showTerminal,
217+
});
218+
(
219+
manager as unknown as { languageServerProcess: PowerShellProcess }
220+
).languageServerProcess = oldProcess;
221+
222+
Sinon.stub(vscode.workspace, "getConfiguration").returns(
223+
stubInterface<vscode.WorkspaceConfiguration>({
224+
get: <T>(_section: string): T => true as T,
225+
}),
226+
);
227+
Sinon.stub(manager as unknown as { stop(): Promise<void> }, "stop")
228+
.resolves();
229+
Sinon.stub(manager as unknown as { start(): Promise<void> }, "start")
230+
.callsFake(async () => {
231+
(
232+
manager as unknown as {
233+
languageServerProcess: PowerShellProcess;
234+
}
235+
).languageServerProcess = newProcess;
236+
});
237+
238+
await (
239+
manager as unknown as {
240+
restartSession(): Promise<void>;
241+
}
242+
).restartSession();
243+
244+
assert.strictEqual(showTerminal.callCount, 1);
245+
assert.deepStrictEqual(showTerminal.firstCall.args, [true]);
246+
});
247+
248+
it("keeps the terminal hidden after restart when it was not active in background mode", async () => {
249+
const manager = makeManager();
250+
const oldProcess = stubInterface<PowerShellProcess>({
251+
isTerminalActive: () => false,
252+
});
253+
const showTerminal = Sinon.spy();
254+
const newProcess = stubInterface<PowerShellProcess>({
255+
showTerminal,
256+
});
257+
(
258+
manager as unknown as { languageServerProcess: PowerShellProcess }
259+
).languageServerProcess = oldProcess;
260+
261+
Sinon.stub(vscode.workspace, "getConfiguration").returns(
262+
stubInterface<vscode.WorkspaceConfiguration>({
263+
get: <T>(_section: string): T => true as T,
264+
}),
265+
);
266+
Sinon.stub(manager as unknown as { stop(): Promise<void> }, "stop")
267+
.resolves();
268+
Sinon.stub(manager as unknown as { start(): Promise<void> }, "start")
269+
.callsFake(async () => {
270+
(
271+
manager as unknown as {
272+
languageServerProcess: PowerShellProcess;
273+
}
274+
).languageServerProcess = newProcess;
275+
});
276+
277+
await (
278+
manager as unknown as {
279+
restartSession(): Promise<void>;
280+
}
281+
).restartSession();
282+
283+
assert.strictEqual(showTerminal.callCount, 0);
284+
});
285+
});
286+
203287
function makeManager(): SessionManager {
204288
Sinon.stub(vscode.commands, "registerCommand").returns(disposableStub());
205289
Sinon.stub(vscode.workspace, "onDidChangeConfiguration").returns(

0 commit comments

Comments
 (0)