Skip to content

Commit 2687b53

Browse files
authored
Get zsh shell integration working again (microsoft#143963)
ZDOTDIR/.zshrc is now created manually on the pty host Fixes microsoft#143629
1 parent 1aaf7cd commit 2687b53

File tree

7 files changed

+24
-13
lines changed

7 files changed

+24
-13
lines changed

build/filters.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ module.exports.copyrightFilter = [
141141
'!**/*.icns',
142142
'!**/*.xml',
143143
'!**/*.sh',
144+
'!**/*.zsh',
144145
'!**/*.txt',
145146
'!**/*.xpm',
146147
'!**/*.opts',

build/gulpfile.reh.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ const serverResources = [
7575
'out-build/vs/base/node/ps.sh',
7676

7777
// Terminal shell integration
78-
'out-build/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh',
79-
'out-build/vs/workbench/contrib/terminal/browser/media/.zshrc',
8078
'out-build/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1',
79+
'out-build/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh',
80+
'out-build/vs/workbench/contrib/terminal/browser/media/shellIntegration.zsh',
8181

8282
'!**/test/**'
8383
];

build/gulpfile.vscode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ const vscodeResources = [
7171
'out-build/vs/workbench/contrib/debug/**/*.json',
7272
'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt',
7373
'out-build/vs/workbench/contrib/terminal/browser/media/*.ps1',
74-
'out-build/vs/workbench/contrib/terminal/browser/media/.zshrc',
7574
'out-build/vs/workbench/contrib/terminal/browser/media/*.sh',
75+
'out-build/vs/workbench/contrib/terminal/browser/media/*.zsh',
7676
'out-build/vs/workbench/contrib/webview/browser/pre/*.js',
7777
'out-build/vs/**/markdown.css',
7878
'out-build/vs/workbench/contrib/tasks/**/*.json',

src/vs/platform/terminal/node/terminalProcess.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { exec } from 'child_process';
7+
import { promises as fs } from 'fs';
78
import type * as pty from 'node-pty';
9+
import { tmpdir } from 'os';
810
import { timeout } from 'vs/base/common/async';
911
import { Emitter, Event } from 'vs/base/common/event';
1012
import { Disposable } from 'vs/base/common/lifecycle';
13+
import { FileAccess } from 'vs/base/common/network';
1114
import * as path from 'vs/base/common/path';
1215
import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
1316
import { URI } from 'vs/base/common/uri';
@@ -184,6 +187,17 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
184187
return firstError;
185188
}
186189

190+
// Handle zsh shell integration - Set $ZDOTDIR to a temp dir and create $ZDOTDIR/.zshrc
191+
if (this.shellLaunchConfig.env?.['_ZDOTDIR'] === '1') {
192+
const zdotdir = path.join(tmpdir(), 'vscode-zsh');
193+
await fs.mkdir(zdotdir, { recursive: true });
194+
const source = path.join(path.dirname(FileAccess.asFileUri('', require).fsPath), 'out/vs/workbench/contrib/terminal/browser/media/shellIntegration.zsh');
195+
await fs.copyFile(source, path.join(zdotdir, '.zshrc'));
196+
this._ptyOptions.env = this._ptyOptions.env || {};
197+
this._ptyOptions.env['ZDOTDIR'] = zdotdir;
198+
delete this._ptyOptions.env['_ZDOTDIR'];
199+
}
200+
187201
try {
188202
await this.setupPtyProcess(this.shellLaunchConfig, this._ptyOptions);
189203
return undefined;

src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,9 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
273273
shellLaunchConfig.env = shellLaunchConfig.env || {} as IProcessEnvironment;
274274
shellLaunchConfig.env['VSCODE_SHELL_LOGIN'] = '1';
275275
}
276-
if (env?.['ZDOTDIR']) {
276+
if (env?.['_ZDOTDIR']) {
277277
shellLaunchConfig.env = shellLaunchConfig.env || {} as IProcessEnvironment;
278-
shellLaunchConfig.env['ZDOTDIR'] = env['ZDOTDIR'].replace('${execInstallFolder}', remoteEnv.appRoot.fsPath);
278+
shellLaunchConfig.env['_ZDOTDIR'] = '1';
279279
}
280280

281281
newProcess = await backend.createProcess(
@@ -455,12 +455,9 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
455455
const shellIntegration = terminalEnvironment.injectShellIntegrationArgs(this._logService, this._configurationService, env, this._configHelper.config.shellIntegration?.enabled || false, shellLaunchConfig, OS);
456456
if (shellIntegration.enableShellIntegration) {
457457
shellLaunchConfig.args = shellIntegration.args;
458-
if (env?.['ZDOTDIR']) {
458+
if (env?.['_ZDOTDIR']) {
459459
shellLaunchConfig.env = shellLaunchConfig.env || {} as IProcessEnvironment;
460-
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
461-
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? withNullAsUndefined(this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri)) : undefined;
462-
const resolved = await this._configurationResolverService.resolveAsync(lastActiveWorkspaceRoot, env['ZDOTDIR']);
463-
env['ZDOTDIR'] = resolved;
460+
shellLaunchConfig.env['_ZDOTDIR'] = '1';
464461
}
465462
// Always resolve the injected arguments on local processes
466463
await this._terminalProfileResolverService.resolveShellLaunchConfig(shellLaunchConfig, {

src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,8 @@ export function injectShellIntegrationArgs(
494494
} else if (originalArgs === shellIntegrationArgs.get(ShellIntegrationExecutable.Zsh) || originalArgs === shellIntegrationArgs.get(ShellIntegrationExecutable.ZshLogin)) {
495495
newArgs = originalArgs;
496496
}
497-
// Set the ZDOTDIR to be the dir of the shell integration script so that it runs
498-
// as a .zshrc file and the autoload hook will work and set precmd and preexec correctly
499-
env['ZDOTDIR'] = '${execInstallFolder}/out/vs/workbench/contrib/terminal/browser/media';
497+
// Set _ZDOTDIR which will defer setting ZDOTDIR to the pty host
498+
env['_ZDOTDIR'] = '1';
500499
const showWelcome = configurationService.getValue(TerminalSettingId.ShellIntegrationShowWelcome);
501500
if (!showWelcome) {
502501
env['VSCODE_SHELL_HIDE_WELCOME'] = '1';

0 commit comments

Comments
 (0)