Skip to content

Commit 0438813

Browse files
author
Kartik Raj
authored
Guide users to install workaround when deactivate command is run (microsoft#22223)
1 parent a55484d commit 0438813

29 files changed

+979
-115
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"quickPickSortByLabel",
2323
"testObserver",
2424
"quickPickItemTooltip",
25-
"saveEditor"
25+
"saveEditor",
26+
"terminalDataWriteEvent"
2627
],
2728
"author": {
2829
"name": "Microsoft Corporation"

pythonFiles/deactivate

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Same as deactivate in "<venv>/bin/activate"
2+
deactivate () {
3+
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
4+
PATH="${_OLD_VIRTUAL_PATH:-}"
5+
export PATH
6+
unset _OLD_VIRTUAL_PATH
7+
fi
8+
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
9+
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
10+
export PYTHONHOME
11+
unset _OLD_VIRTUAL_PYTHONHOME
12+
fi
13+
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
14+
hash -r 2> /dev/null
15+
fi
16+
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
17+
PS1="${_OLD_VIRTUAL_PS1:-}"
18+
export PS1
19+
unset _OLD_VIRTUAL_PS1
20+
fi
21+
unset VIRTUAL_ENV
22+
unset VIRTUAL_ENV_PROMPT
23+
if [ ! "${1:-}" = "nondestructive" ] ; then
24+
unset -f deactivate
25+
fi
26+
}
27+
28+
# Initialize the variables required by deactivate function
29+
_OLD_VIRTUAL_PS1="${PS1:-}"
30+
_OLD_VIRTUAL_PATH="$PATH"
31+
if [ -n "${PYTHONHOME:-}" ] ; then
32+
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
33+
fi

pythonFiles/deactivate.csh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Same as deactivate in "<venv>/bin/activate.csh"
2+
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate'
3+
4+
# Initialize the variables required by deactivate function
5+
set _OLD_VIRTUAL_PROMPT="$prompt"
6+
set _OLD_VIRTUAL_PATH="$PATH"

pythonFiles/deactivate.fish

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Same as deactivate in "<venv>/bin/activate.fish"
2+
function deactivate -d "Exit virtual environment and return to normal shell environment"
3+
# reset old environment variables
4+
if test -n "$_OLD_VIRTUAL_PATH"
5+
set -gx PATH $_OLD_VIRTUAL_PATH
6+
set -e _OLD_VIRTUAL_PATH
7+
end
8+
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
9+
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
10+
set -e _OLD_VIRTUAL_PYTHONHOME
11+
end
12+
13+
if test -n "$vscode_python_old_fish_prompt_OVERRIDE"
14+
set -e vscode_python_old_fish_prompt_OVERRIDE
15+
if functions -q vscode_python_old_fish_prompt
16+
functions -e fish_prompt
17+
functions -c vscode_python_old_fish_prompt fish_prompt
18+
functions -e vscode_python_old_fish_prompt
19+
end
20+
end
21+
22+
set -e VIRTUAL_ENV
23+
set -e VIRTUAL_ENV_PROMPT
24+
if test "$argv[1]" != "nondestructive"
25+
functions -e deactivate
26+
end
27+
end
28+
29+
# Initialize the variables required by deactivate function
30+
set -gx _OLD_VIRTUAL_PATH $PATH
31+
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
32+
functions -c fish_prompt vscode_python_old_fish_prompt
33+
end
34+
if set -q PYTHONHOME
35+
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
36+
end

pythonFiles/deactivate.ps1

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Same as deactivate in "Activate.ps1"
2+
function global:deactivate ([switch]$NonDestructive) {
3+
if (Test-Path function:_OLD_VIRTUAL_PROMPT) {
4+
copy-item function:_OLD_VIRTUAL_PROMPT function:prompt
5+
remove-item function:_OLD_VIRTUAL_PROMPT
6+
}
7+
if (Test-Path env:_OLD_VIRTUAL_PYTHONHOME) {
8+
copy-item env:_OLD_VIRTUAL_PYTHONHOME env:PYTHONHOME
9+
remove-item env:_OLD_VIRTUAL_PYTHONHOME
10+
}
11+
if (Test-Path env:_OLD_VIRTUAL_PATH) {
12+
copy-item env:_OLD_VIRTUAL_PATH env:PATH
13+
remove-item env:_OLD_VIRTUAL_PATH
14+
}
15+
if (Test-Path env:VIRTUAL_ENV) {
16+
remove-item env:VIRTUAL_ENV
17+
}
18+
if (!$NonDestructive) {
19+
remove-item function:deactivate
20+
}
21+
}
22+
23+
# Initialize the variables required by deactivate function
24+
if (! $env:VIRTUAL_ENV_DISABLE_PROMPT) {
25+
function global:_OLD_VIRTUAL_PROMPT {""}
26+
copy-item function:prompt function:_OLD_VIRTUAL_PROMPT
27+
}
28+
if (Test-Path env:PYTHONHOME) {
29+
copy-item env:PYTHONHOME env:_OLD_VIRTUAL_PYTHONHOME
30+
}
31+
copy-item env:PATH env:_OLD_VIRTUAL_PATH

src/client/common/application/applicationShell.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
DocumentSelector,
1111
env,
1212
Event,
13+
EventEmitter,
1314
InputBox,
1415
InputBoxOptions,
1516
languages,
@@ -37,7 +38,8 @@ import {
3738
WorkspaceFolder,
3839
WorkspaceFolderPickOptions,
3940
} from 'vscode';
40-
import { IApplicationShell } from './types';
41+
import { traceError } from '../../logging';
42+
import { IApplicationShell, TerminalDataWriteEvent } from './types';
4143

4244
@injectable()
4345
export class ApplicationShell implements IApplicationShell {
@@ -172,4 +174,12 @@ export class ApplicationShell implements IApplicationShell {
172174
public createLanguageStatusItem(id: string, selector: DocumentSelector): LanguageStatusItem {
173175
return languages.createLanguageStatusItem(id, selector);
174176
}
177+
public get onDidWriteTerminalData(): Event<TerminalDataWriteEvent> {
178+
try {
179+
return window.onDidWriteTerminalData;
180+
} catch (ex) {
181+
traceError('Failed to get proposed API onDidWriteTerminalData', ex);
182+
return new EventEmitter<TerminalDataWriteEvent>().event;
183+
}
184+
}
175185
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
import { ProgressOptions } from 'vscode';
5+
import { Deferred, createDeferred } from '../utils/async';
6+
import { IApplicationShell } from './types';
7+
8+
export class ProgressService {
9+
private deferred: Deferred<void> | undefined;
10+
11+
constructor(private readonly shell: IApplicationShell) {}
12+
13+
public showProgress(options: ProgressOptions): void {
14+
if (!this.deferred) {
15+
this.createProgress(options);
16+
}
17+
}
18+
19+
public hideProgress(): void {
20+
if (this.deferred) {
21+
this.deferred.resolve();
22+
this.deferred = undefined;
23+
}
24+
}
25+
26+
private createProgress(options: ProgressOptions) {
27+
this.shell.withProgress(options, () => {
28+
this.deferred = createDeferred();
29+
return this.deferred.promise;
30+
});
31+
}
32+
}

src/client/common/application/types.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ import { Resource } from '../types';
6767
import { ICommandNameArgumentTypeMapping } from './commands';
6868
import { ExtensionContextKey } from './contextKeys';
6969

70+
export interface TerminalDataWriteEvent {
71+
/**
72+
* The {@link Terminal} for which the data was written.
73+
*/
74+
readonly terminal: Terminal;
75+
/**
76+
* The data being written.
77+
*/
78+
readonly data: string;
79+
}
80+
7081
export const IApplicationShell = Symbol('IApplicationShell');
7182
export interface IApplicationShell {
7283
/**
@@ -75,6 +86,13 @@ export interface IApplicationShell {
7586
*/
7687
readonly onDidChangeWindowState: Event<WindowState>;
7788

89+
/**
90+
* An event which fires when the terminal's child pseudo-device is written to (the shell).
91+
* In other words, this provides access to the raw data stream from the process running
92+
* within the terminal, including VT sequences.
93+
*/
94+
readonly onDidWriteTerminalData: Event<TerminalDataWriteEvent>;
95+
7896
showInformationMessage(message: string, ...items: string[]): Thenable<string | undefined>;
7997

8098
/**

src/client/common/experiments/helpers.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import { env, workspace } from 'vscode';
77
import { IExperimentService } from '../types';
88
import { TerminalEnvVarActivation } from './groups';
99
import { isTestExecution } from '../constants';
10+
import { traceInfo } from '../../logging';
1011

1112
export function inTerminalEnvVarExperiment(experimentService: IExperimentService): boolean {
12-
if (!isTestExecution() && workspace.workspaceFile && env.remoteName) {
13+
if (!isTestExecution() && env.remoteName && workspace.workspaceFolders && workspace.workspaceFolders.length > 1) {
1314
// TODO: Remove this if statement once https://github.com/microsoft/vscode/issues/180486 is fixed.
15+
traceInfo('Not enabling terminal env var experiment in multiroot remote workspaces');
1416
return false;
1517
}
1618
if (!experimentService.inExperimentSync(TerminalEnvVarActivation.experiment)) {

src/client/common/platform/fs-paths.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import * as nodepath from 'path';
55
import { getSearchPathEnvVarNames } from '../utils/exec';
6+
import * as fs from 'fs-extra';
67
import { getOSType, OSType } from '../utils/platform';
78
import { IExecutables, IFileSystemPaths, IFileSystemPathUtils } from './types';
89

@@ -170,3 +171,22 @@ export function isParentPath(filePath: string, parentPath: string): boolean {
170171
export function arePathsSame(path1: string, path2: string): boolean {
171172
return normCasePath(path1) === normCasePath(path2);
172173
}
174+
175+
export async function copyFile(src: string, dest: string): Promise<void> {
176+
const destDir = nodepath.dirname(dest);
177+
if (!(await fs.pathExists(destDir))) {
178+
await fs.mkdirp(destDir);
179+
}
180+
181+
await fs.copy(src, dest, {
182+
overwrite: true,
183+
});
184+
}
185+
186+
export function pathExists(absPath: string): Promise<boolean> {
187+
return fs.pathExists(absPath);
188+
}
189+
190+
export function createFile(filename: string): Promise<void> {
191+
return fs.createFile(filename);
192+
}

0 commit comments

Comments
 (0)