Skip to content

Check if the Terminal Shell Integration setting is changed #4971

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export class SessionManager implements Middleware {
private sessionDetails: IEditorServicesSessionDetails | undefined;
private sessionsFolder: vscode.Uri;
private sessionStatus: SessionStatus = SessionStatus.NotStarted;
private shellIntegrationEnabled = false;
private startCancellationTokenSource: vscode.CancellationTokenSource | undefined;
private suppressRestartPrompt = false;
private versionDetails: IPowerShellVersionDetails | undefined;
Expand All @@ -109,6 +110,7 @@ export class SessionManager implements Middleware {
// We have to override the scheme because it defaults to
// 'vscode-userdata' which breaks UNC paths.
this.sessionsFolder = vscode.Uri.joinPath(extensionContext.globalStorageUri.with({ scheme: "file" }), "sessions");

this.platformDetails = getPlatformDetails();
this.HostName = hostName;
this.DisplayName = displayName;
Expand Down Expand Up @@ -189,6 +191,9 @@ export class SessionManager implements Middleware {
// Migrate things.
await this.migrateWhitespaceAroundPipeSetting();

// Update non-PowerShell settings.
this.shellIntegrationEnabled = vscode.workspace.getConfiguration("terminal.integrated.shellIntegration").get<boolean>("enabled") ?? false;

// Find the PowerShell executable to use for the server.
this.PowerShellExeDetails = await this.findPowerShell();

Expand Down Expand Up @@ -447,19 +452,23 @@ export class SessionManager implements Middleware {

private async onConfigurationUpdated(): Promise<void> {
const settings = getSettings();
const shellIntegrationEnabled = vscode.workspace.getConfiguration("terminal.integrated.shellIntegration").get<boolean>("enabled");
this.logger.updateLogLevel(settings.developer.editorServicesLogLevel);

// Detect any setting changes that would affect the session.
if (!this.suppressRestartPrompt && this.sessionStatus === SessionStatus.Running &&
(settings.cwd !== this.sessionSettings.cwd
|| settings.powerShellDefaultVersion !== this.sessionSettings.powerShellDefaultVersion
|| settings.developer.editorServicesLogLevel !== this.sessionSettings.developer.editorServicesLogLevel
|| settings.developer.bundledModulesPath !== this.sessionSettings.developer.bundledModulesPath
|| settings.developer.editorServicesWaitForDebugger !== this.sessionSettings.developer.editorServicesWaitForDebugger
|| settings.developer.setExecutionPolicy !== this.sessionSettings.developer.setExecutionPolicy
|| settings.integratedConsole.useLegacyReadLine !== this.sessionSettings.integratedConsole.useLegacyReadLine
|| settings.integratedConsole.startInBackground !== this.sessionSettings.integratedConsole.startInBackground
|| settings.integratedConsole.startLocation !== this.sessionSettings.integratedConsole.startLocation)) {
if (!this.suppressRestartPrompt
&& this.sessionStatus === SessionStatus.Running
&& ((shellIntegrationEnabled !== this.shellIntegrationEnabled
&& !settings.integratedConsole.startInBackground)
|| settings.cwd !== this.sessionSettings.cwd
|| settings.powerShellDefaultVersion !== this.sessionSettings.powerShellDefaultVersion
|| settings.developer.editorServicesLogLevel !== this.sessionSettings.developer.editorServicesLogLevel
|| settings.developer.bundledModulesPath !== this.sessionSettings.developer.bundledModulesPath
|| settings.developer.editorServicesWaitForDebugger !== this.sessionSettings.developer.editorServicesWaitForDebugger
|| settings.developer.setExecutionPolicy !== this.sessionSettings.developer.setExecutionPolicy
|| settings.integratedConsole.useLegacyReadLine !== this.sessionSettings.integratedConsole.useLegacyReadLine
|| settings.integratedConsole.startInBackground !== this.sessionSettings.integratedConsole.startInBackground
|| settings.integratedConsole.startLocation !== this.sessionSettings.integratedConsole.startLocation)) {

this.logger.writeVerbose("Settings changed, prompting to restart...");
const response = await vscode.window.showInformationMessage(
Expand Down Expand Up @@ -610,10 +619,6 @@ export class SessionManager implements Middleware {
});
};

// When Terminal Shell Integration is enabled, we pass the path to the script that the server should execute.
// Passing an empty string implies integration is disabled.
const shellIntegrationEnabled = vscode.workspace.getConfiguration("terminal.integrated.shellIntegration").get<boolean>("enabled");
const shellIntegrationScript = path.join(vscode.env.appRoot, "out", "vs", "workbench", "contrib", "terminal", "browser", "media", "shellIntegration.ps1");

const clientOptions: LanguageClientOptions = {
documentSelector: this.documentSelector,
Expand All @@ -624,10 +629,13 @@ export class SessionManager implements Middleware {
// TODO: fileEvents: vscode.workspace.createFileSystemWatcher('**/.eslintrc')
},
// NOTE: Some settings are only applicable on startup, so we send them during initialization.
// When Terminal Shell Integration is enabled, we pass the path to the script that the server should execute.
// Passing an empty string implies integration is disabled.
initializationOptions: {
enableProfileLoading: this.sessionSettings.enableProfileLoading,
initialWorkingDirectory: await validateCwdSetting(this.logger),
shellIntegrationScript: shellIntegrationEnabled ? shellIntegrationScript : "",
shellIntegrationScript: this.shellIntegrationEnabled
? utils.ShellIntegrationScript : "",
},
errorHandler: {
// Override the default error handler to prevent it from
Expand Down
2 changes: 2 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import vscode = require("vscode");

export const PowerShellLanguageId = "powershell";

export const ShellIntegrationScript = path.join(vscode.env.appRoot, "out", "vs", "workbench", "contrib", "terminal", "browser", "media", "shellIntegration.ps1");

export function escapeSingleQuotes(p: string): string {
return p.replace(new RegExp("'", "g"), "''");
}
Expand Down
7 changes: 6 additions & 1 deletion test/core/paths.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import assert from "assert";
import * as vscode from "vscode";
import { IPowerShellExtensionClient } from "../../src/features/ExternalApi";
import utils = require("../utils");
import { checkIfDirectoryExists } from "../../src/utils";
import { checkIfDirectoryExists, checkIfFileExists, ShellIntegrationScript } from "../../src/utils";

describe("Path assumptions", function () {
let globalStorageUri: vscode.Uri;
Expand All @@ -21,4 +21,9 @@ describe("Path assumptions", function () {
it("Creates the log folder at the correct path", async function () {
assert(await checkIfDirectoryExists(vscode.Uri.joinPath(globalStorageUri, "logs")));
});

it("Finds the Terminal Shell Integration Script", async function () {
// If VS Code changes the location of the script, we need to know ASAP (as it's not a public API).
assert(await checkIfFileExists(ShellIntegrationScript));
});
});