Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/git/src/terminal.ts
3316 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { ExtensionContext, l10n, LogOutputChannel, TerminalShellExecutionEndEvent, window, workspace } from 'vscode';
7
import { dispose, filterEvent, IDisposable } from './util';
8
import { Model } from './model';
9
10
export interface ITerminalEnvironmentProvider {
11
featureDescription?: string;
12
getTerminalEnv(): { [key: string]: string };
13
}
14
15
export class TerminalEnvironmentManager {
16
17
private readonly disposable: IDisposable;
18
19
constructor(private readonly context: ExtensionContext, private readonly envProviders: (ITerminalEnvironmentProvider | undefined)[]) {
20
this.disposable = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git'))
21
(this.refresh, this);
22
23
this.refresh();
24
}
25
26
private refresh(): void {
27
const config = workspace.getConfiguration('git', null);
28
this.context.environmentVariableCollection.clear();
29
30
if (!config.get<boolean>('enabled', true)) {
31
return;
32
}
33
34
const features: string[] = [];
35
for (const envProvider of this.envProviders) {
36
const terminalEnv = envProvider?.getTerminalEnv() ?? {};
37
38
for (const name of Object.keys(terminalEnv)) {
39
this.context.environmentVariableCollection.replace(name, terminalEnv[name]);
40
}
41
if (envProvider?.featureDescription && Object.keys(terminalEnv).length > 0) {
42
features.push(envProvider.featureDescription);
43
}
44
}
45
if (features.length) {
46
this.context.environmentVariableCollection.description = l10n.t('Enables the following features: {0}', features.join(', '));
47
}
48
}
49
50
dispose(): void {
51
this.disposable.dispose();
52
}
53
}
54
55
export class TerminalShellExecutionManager {
56
private readonly subcommands = new Set<string>([
57
'add', 'branch', 'checkout', 'cherry-pick', 'clean', 'commit', 'fetch', 'merge',
58
'mv', 'rebase', 'reset', 'restore', 'revert', 'rm', 'pull', 'push', 'stash', 'switch']);
59
60
private readonly disposables: IDisposable[] = [];
61
62
constructor(
63
private readonly model: Model,
64
private readonly logger: LogOutputChannel
65
) {
66
window.onDidEndTerminalShellExecution(this.onDidEndTerminalShellExecution, this, this.disposables);
67
}
68
69
private onDidEndTerminalShellExecution(e: TerminalShellExecutionEndEvent): void {
70
const { execution, exitCode, shellIntegration } = e;
71
const [executable, subcommand] = execution.commandLine.value.split(/\s+/);
72
const cwd = execution.cwd ?? shellIntegration.cwd;
73
74
if (executable.toLowerCase() !== 'git' || !this.subcommands.has(subcommand?.toLowerCase()) || !cwd || exitCode !== 0) {
75
return;
76
}
77
78
this.logger.trace(`[TerminalShellExecutionManager][onDidEndTerminalShellExecution] Matched git subcommand: ${subcommand}`);
79
80
const repository = this.model.getRepository(cwd);
81
if (!repository) {
82
this.logger.trace(`[TerminalShellExecutionManager][onDidEndTerminalShellExecution] Unable to find repository for current working directory: ${cwd.toString()}`);
83
return;
84
}
85
86
repository.status();
87
}
88
89
dispose(): void {
90
dispose(this.disposables);
91
}
92
}
93
94