Skip to content

Commit 9f9f6ca

Browse files
Add -Login startup option (#2400)
* Add -Login startup option * Improve dummy command * Add explanatory comment * switch to .osx & .linux and code clean up * remove import * rob's feedback Co-authored-by: Tyler James Leonhardt <tylerl0706@gmail.com>
1 parent 17c520a commit 9f9f6ca

File tree

3 files changed

+59
-31
lines changed

3 files changed

+59
-31
lines changed

package.json

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,16 @@
550550
"description": "Specifies whether you should be prompted to update your version of PowerShell.",
551551
"default": true
552552
},
553+
"powershell.startAsLoginShell.osx": {
554+
"type": "boolean",
555+
"default": true,
556+
"description": "Starts the PowerShell extension's underlying PowerShell process as a login shell, if applicable."
557+
},
558+
"powershell.startAsLoginShell.linux": {
559+
"type": "boolean",
560+
"default": false,
561+
"description": "Starts the PowerShell extension's underlying PowerShell process as a login shell, if applicable."
562+
},
553563
"powershell.startAutomatically": {
554564
"type": "boolean",
555565
"default": true,
@@ -740,11 +750,6 @@
740750
"type": "array",
741751
"default": null,
742752
"description": "An array of strings that enable experimental features in the PowerShell extension."
743-
},
744-
"powershell.developer.powerShellExeIsWindowsDevBuild": {
745-
"type": "boolean",
746-
"default": false,
747-
"description": "Indicates that the powerShellExePath points to a developer build of Windows PowerShell and configures it for development."
748753
}
749754
}
750755
},

src/process.ts

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,19 @@ export class PowerShellProcess {
6363
this.startArgs += "-UseLegacyReadLine";
6464
}
6565

66-
const powerShellArgs = [
67-
"-NoProfile",
68-
"-NonInteractive",
69-
];
66+
const powerShellArgs = [];
67+
68+
const useLoginShell: boolean =
69+
(utils.isMacOS && this.sessionSettings.startAsLoginShell.osx)
70+
|| (utils.isLinux && this.sessionSettings.startAsLoginShell.linux);
71+
72+
if (useLoginShell && this.isLoginShell(this.exePath)) {
73+
// This MUST be the first argument.
74+
powerShellArgs.push("-Login");
75+
}
76+
77+
powerShellArgs.push("-NoProfile");
78+
powerShellArgs.push("-NonInteractive");
7079

7180
// Only add ExecutionPolicy param on Windows
7281
if (utils.isWindows) {
@@ -88,27 +97,11 @@ export class PowerShellProcess {
8897
Buffer.from(startEditorServices, "utf16le").toString("base64"));
8998
}
9099

91-
let powerShellExePath = this.exePath;
92-
93-
if (this.sessionSettings.developer.powerShellExeIsWindowsDevBuild) {
94-
// Windows PowerShell development builds need the DEVPATH environment
95-
// variable set to the folder where development binaries are held
96-
97-
// NOTE: This batch file approach is needed temporarily until VS Code's
98-
// createTerminal API gets an argument for setting environment variables
99-
// on the launched process.
100-
const batScriptPath = path.resolve(__dirname, "../../sessions/powershell.bat");
101-
fs.writeFileSync(
102-
batScriptPath,
103-
`@set DEVPATH=${path.dirname(powerShellExePath)}\r\n@${powerShellExePath} %*`);
104-
105-
powerShellExePath = batScriptPath;
106-
}
107-
108100
this.log.write(
109101
"Language server starting --",
110-
" exe: " + powerShellExePath,
111-
" args: " + startEditorServices);
102+
" PowerShell executable: " + this.exePath,
103+
" PowerShell args: " + powerShellArgs.join(" "),
104+
" PowerShell Editor Services args: " + startEditorServices);
112105

113106
// Make sure no old session file exists
114107
utils.deleteSessionFile(this.sessionFilePath);
@@ -117,7 +110,7 @@ export class PowerShellProcess {
117110
this.consoleTerminal =
118111
vscode.window.createTerminal(
119112
this.title,
120-
powerShellExePath,
113+
this.exePath,
121114
powerShellArgs);
122115

123116
if (this.sessionSettings.integratedConsole.showOnStartup) {
@@ -178,4 +171,18 @@ export class PowerShellProcess {
178171
this.consoleTerminal = undefined;
179172
}
180173
}
174+
175+
private isLoginShell(pwshPath: string): boolean {
176+
try {
177+
// We can't know what version of PowerShell we have without running it
178+
// So we try to start PowerShell with -Login
179+
// If it exits successfully, we return true
180+
// If it exits unsuccessfully, node throws, we catch, and return false
181+
cp.execFileSync(pwshPath, ["-Login", "-NoProfile", "-NoLogo", "-Command", "exit 0"]);
182+
} catch {
183+
return false;
184+
}
185+
186+
return true;
187+
}
181188
}

src/settings.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ export interface IDeveloperSettings {
7272
bundledModulesPath?: string;
7373
editorServicesLogLevel?: string;
7474
editorServicesWaitForDebugger?: boolean;
75-
powerShellExeIsWindowsDevBuild?: boolean;
7675
}
7776

7877
export interface ISettings {
@@ -82,6 +81,7 @@ export interface ISettings {
8281
powerShellExePath?: string;
8382
promptToUpdatePowerShell?: boolean;
8483
bundledModulesPath?: string;
84+
startAsLoginShell?: IStartAsLoginShellSettings;
8585
startAutomatically?: boolean;
8686
useX86Host?: boolean;
8787
enableProfileLoading?: boolean;
@@ -96,6 +96,11 @@ export interface ISettings {
9696
sideBar?: ISideBarSettings;
9797
}
9898

99+
export interface IStartAsLoginShellSettings {
100+
osx?: boolean;
101+
linux?: boolean;
102+
}
103+
99104
export interface IIntegratedConsoleSettings {
100105
showOnStartup?: boolean;
101106
focusConsoleOnExecute?: boolean;
@@ -131,7 +136,6 @@ export function load(): ISettings {
131136
bundledModulesPath: "../../../PowerShellEditorServices/module",
132137
editorServicesLogLevel: "Normal",
133138
editorServicesWaitForDebugger: false,
134-
powerShellExeIsWindowsDevBuild: false,
135139
};
136140

137141
const defaultCodeFoldingSettings: ICodeFoldingSettings = {
@@ -157,6 +161,11 @@ export function load(): ISettings {
157161
useCorrectCasing: false,
158162
};
159163

164+
const defaultStartAsLoginShellSettings: IStartAsLoginShellSettings = {
165+
osx: true,
166+
linux: false,
167+
};
168+
160169
const defaultIntegratedConsoleSettings: IIntegratedConsoleSettings = {
161170
showOnStartup: true,
162171
focusConsoleOnExecute: true,
@@ -203,6 +212,13 @@ export function load(): ISettings {
203212
configuration.get<IBugReportingSettings>("bugReporting", defaultBugReportingSettings),
204213
sideBar:
205214
configuration.get<ISideBarSettings>("sideBar", defaultSideBarSettings),
215+
startAsLoginShell:
216+
// tslint:disable-next-line
217+
// We follow the same convention as VS Code - https://github.com/microsoft/vscode/blob/ff00badd955d6cfcb8eab5f25f3edc86b762f49f/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts#L105-L107
218+
// "Unlike on Linux, ~/.profile is not sourced when logging into a macOS session. This
219+
// is the reason terminals on macOS typically run login shells by default which set up
220+
// the environment. See http://unix.stackexchange.com/a/119675/115410"
221+
configuration.get<IStartAsLoginShellSettings>("startAsLoginShell", defaultStartAsLoginShellSettings),
206222
};
207223
}
208224

0 commit comments

Comments
 (0)