Skip to content

Commit 6041abd

Browse files
authored
Merge pull request microsoft#152802 from microsoft/tyriar/151933
Allow manual install of shell integration
2 parents da823b2 + a1e9fa6 commit 6041abd

File tree

5 files changed

+66
-31
lines changed

5 files changed

+66
-31
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ export function getShellIntegrationInjection(
118118
const shell = process.platform === 'win32' ? path.basename(shellLaunchConfig.executable).toLowerCase() : path.basename(shellLaunchConfig.executable);
119119
const appRoot = path.dirname(FileAccess.asFileUri('', require).fsPath);
120120
let newArgs: string[] | undefined;
121+
const envMixin: IProcessEnvironment = {
122+
'VSCODE_INJECTION': '1'
123+
};
121124

122125
// Windows
123126
if (isWindows) {
@@ -134,14 +137,13 @@ export function getShellIntegrationInjection(
134137
newArgs = [...newArgs]; // Shallow clone the array to avoid setting the default array
135138
newArgs[newArgs.length - 1] = format(newArgs[newArgs.length - 1], appRoot, '');
136139
}
137-
return { newArgs };
140+
return { newArgs, envMixin };
138141
}
139142
logService.warn(`Shell integration cannot be enabled for executable "${shellLaunchConfig.executable}" and args`, shellLaunchConfig.args);
140143
return undefined;
141144
}
142145

143146
// Linux & macOS
144-
const envMixin: IProcessEnvironment = {};
145147
switch (shell) {
146148
case 'bash': {
147149
if (!originalArgs || originalArgs.length === 0) {
@@ -168,7 +170,7 @@ export function getShellIntegrationInjection(
168170
}
169171
newArgs = [...newArgs]; // Shallow clone the array to avoid setting the default array
170172
newArgs[newArgs.length - 1] = format(newArgs[newArgs.length - 1], appRoot, '');
171-
return { newArgs };
173+
return { newArgs, envMixin };
172174
}
173175
case 'zsh': {
174176
if (!originalArgs || originalArgs.length === 0) {

src/vs/platform/terminal/test/node/terminalEnvironment.test.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ suite('platform - terminalEnvironment', () => {
3333
'-noexit',
3434
'-command',
3535
`. "${expectedPs1}"`
36-
]
36+
],
37+
envMixin: {
38+
VSCODE_INJECTION: '1'
39+
}
3740
});
3841
test('when undefined, []', () => {
3942
deepStrictEqual(getShellIntegrationInjection({ executable: pwshExe, args: [] }, enabledProcessOptions, logService), enabledExpectedResult);
@@ -61,7 +64,10 @@ suite('platform - terminalEnvironment', () => {
6164
'-noexit',
6265
'-command',
6366
`. "${expectedPs1}"`
64-
]
67+
],
68+
envMixin: {
69+
VSCODE_INJECTION: '1'
70+
}
6571
});
6672
test('when array contains no logo and login', () => {
6773
deepStrictEqual(getShellIntegrationInjection({ executable: pwshExe, args: ['-l', '-NoLogo'] }, enabledProcessOptions, logService), enabledExpectedResult);
@@ -97,8 +103,9 @@ suite('platform - terminalEnvironment', () => {
97103
/.+\/out\/vs\/workbench\/contrib\/terminal\/browser\/media\/shellIntegration-login.zsh/
98104
];
99105
function assertIsEnabled(result: IShellIntegrationConfigInjection) {
100-
strictEqual(Object.keys(result.envMixin!).length, 1);
106+
strictEqual(Object.keys(result.envMixin!).length, 2);
101107
ok(result.envMixin!['ZDOTDIR']?.match(expectedDir));
108+
ok(result.envMixin!['VSCODE_INJECTION']?.match('1'));
102109
strictEqual(result.filesToCopy?.length, 4);
103110
ok(result.filesToCopy[0].dest.match(expectedDests[0]));
104111
ok(result.filesToCopy[1].dest.match(expectedDests[1]));
@@ -143,7 +150,9 @@ suite('platform - terminalEnvironment', () => {
143150
'--init-file',
144151
`${repoRoot}/out/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh`
145152
],
146-
envMixin: {}
153+
envMixin: {
154+
VSCODE_INJECTION: '1'
155+
}
147156
});
148157
deepStrictEqual(getShellIntegrationInjection({ executable: 'bash', args: [] }, enabledProcessOptions, logService), enabledExpectedResult);
149158
deepStrictEqual(getShellIntegrationInjection({ executable: 'bash', args: '' }, enabledProcessOptions, logService), enabledExpectedResult);
@@ -156,6 +165,7 @@ suite('platform - terminalEnvironment', () => {
156165
`${repoRoot}/out/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh`
157166
],
158167
envMixin: {
168+
VSCODE_INJECTION: '1',
159169
VSCODE_SHELL_LOGIN: '1'
160170
}
161171
});

src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,39 @@
33
# Licensed under the MIT License. See License.txt in the project root for license information.
44
# ---------------------------------------------------------------------------------------------
55

6+
# Prevent the script recursing when setting up
7+
if [[ -n "$VSCODE_SHELL_INTEGRATION" ]]; then
8+
builtin return
9+
fi
10+
611
VSCODE_SHELL_INTEGRATION=1
712

8-
if [ -z "$VSCODE_SHELL_LOGIN" ]; then
9-
. ~/.bashrc
10-
else
11-
# Imitate -l because --init-file doesn't support it:
12-
# run the first of these files that exists
13-
if [ -f /etc/profile ]; then
14-
. /etc/profile
15-
fi
16-
# exceute the first that exists
17-
if [ -f ~/.bash_profile ]; then
18-
. ~/.bash_profile
19-
elif [ -f ~/.bash_login ]; then
20-
. ~/.bash_login
21-
elif [ -f ~/.profile ]; then
22-
. ~/.profile
13+
# Run relevant rc/profile only if shell integration has been injected, not when run manually
14+
if [ "$VSCODE_INJECTION" == "1" ]; then
15+
if [ -z "$VSCODE_SHELL_LOGIN" ]; then
16+
. ~/.bashrc
17+
else
18+
# Imitate -l because --init-file doesn't support it:
19+
# run the first of these files that exists
20+
if [ -f /etc/profile ]; then
21+
. /etc/profile
22+
fi
23+
# exceute the first that exists
24+
if [ -f ~/.bash_profile ]; then
25+
. ~/.bash_profile
26+
elif [ -f ~/.bash_login ]; then
27+
. ~/.bash_login
28+
elif [ -f ~/.profile ]; then
29+
. ~/.profile
30+
fi
31+
builtin unset VSCODE_SHELL_LOGIN=""
2332
fi
24-
VSCODE_SHELL_LOGIN=""
33+
builtin unset VSCODE_INJECTION
2534
fi
2635

36+
# Disable shell integration if PROMPT_COMMAND is 2+ function calls since that is not handled.
2737
if [[ "$PROMPT_COMMAND" =~ .*(' '.*\;)|(\;.*' ').* ]]; then
28-
VSCODE_SHELL_INTEGRATION=""
38+
builtin unset VSCODE_SHELL_INTEGRATION
2939
builtin return
3040
fi
3141

src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,23 @@
44
# ---------------------------------------------------------------------------------------------
55
builtin autoload -Uz add-zsh-hook
66

7+
# Prevent the script recursing when setting up
8+
if [ -n "$VSCODE_SHELL_INTEGRATION" ]; then
9+
builtin return
10+
fi
11+
712
# This variable allows the shell to both detect that VS Code's shell integration is enabled as well
813
# as disable it by unsetting the variable.
9-
VSCODE_SHELL_INTEGRATION=1
10-
11-
if [[ $options[norcs] = off && -f $USER_ZDOTDIR/.zshrc ]]; then
12-
VSCODE_ZDOTDIR=$ZDOTDIR
13-
ZDOTDIR=$USER_ZDOTDIR
14-
. $USER_ZDOTDIR/.zshrc
15-
ZDOTDIR=$VSCODE_ZDOTDIR
14+
export VSCODE_SHELL_INTEGRATION=1
15+
16+
# Only fix up ZDOTDIR if shell integration was injected (not manually installed) and has not been called yet
17+
if [[ "$VSCODE_INJECTION" == "1" ]]; then
18+
if [[ $options[norcs] = off && -f $USER_ZDOTDIR/.zshrc ]]; then
19+
VSCODE_ZDOTDIR=$ZDOTDIR
20+
ZDOTDIR=$USER_ZDOTDIR
21+
. $USER_ZDOTDIR/.zshrc
22+
ZDOTDIR=$VSCODE_ZDOTDIR
23+
fi
1624
fi
1725

1826
# Shell integration was disabled by the shell, exit without warning assuming either the shell has

src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
# Licensed under the MIT License. See License.txt in the project root for license information.
44
# ---------------------------------------------------------------------------------------------
55

6+
# Prevent installing more than once per session
7+
if (Test-Path variable:global:__VSCodeOriginalPrompt) {
8+
return;
9+
}
10+
611
$Global:__VSCodeOriginalPrompt = $function:Prompt
712

813
$Global:__LastHistoryId = -1

0 commit comments

Comments
 (0)