Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/sessions/contrib/chat/browser/scopedWorkspacePicker.ts
13401 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 { Codicon } from '../../../../base/common/codicons.js';
7
import { localize } from '../../../../nls.js';
8
import { IActionWidgetService } from '../../../../platform/actionWidget/browser/actionWidget.js';
9
import { ActionListItemKind, IActionListItem } from '../../../../platform/actionWidget/browser/actionList.js';
10
import { IMenuService } from '../../../../platform/actions/common/actions.js';
11
import { IRemoteAgentHostService } from '../../../../platform/agentHost/common/remoteAgentHostService.js';
12
import { ICommandService } from '../../../../platform/commands/common/commands.js';
13
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
14
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
15
import { IFileDialogService } from '../../../../platform/dialogs/common/dialogs.js';
16
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
17
import { IQuickInputService } from '../../../../platform/quickinput/common/quickInput.js';
18
import { IStorageService } from '../../../../platform/storage/common/storage.js';
19
import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';
20
import { ISessionsProvidersService } from '../../../services/sessions/browser/sessionsProvidersService.js';
21
import { IAgentHostFilterService } from '../../remoteAgentHost/common/agentHostFilter.js';
22
import { IWorkspacePickerItem, IWorkspaceSelection, WorkspacePicker } from './sessionWorkspacePicker.js';
23
import { IWorkspacesService } from '../../../../platform/workspaces/common/workspaces.js';
24
25
/**
26
* A simplified workspace picker that scopes its contents to the host
27
* currently selected in the agent host filter. It shows:
28
*
29
* 1. Recent workspaces for the selected host
30
* 2. A single "Select Folder..." entry that invokes the host's browse action
31
*
32
* Falls back to the Copilot local provider when no host is selected (e.g. on
33
* desktop, where the host filter UI is not surfaced).
34
*/
35
export class ScopedWorkspacePicker extends WorkspacePicker {
36
37
constructor(
38
@IActionWidgetService actionWidgetService: IActionWidgetService,
39
@IStorageService storageService: IStorageService,
40
@IUriIdentityService uriIdentityService: IUriIdentityService,
41
@ISessionsProvidersService sessionsProvidersService: ISessionsProvidersService,
42
@IRemoteAgentHostService remoteAgentHostService: IRemoteAgentHostService,
43
@IConfigurationService configurationService: IConfigurationService,
44
@ICommandService commandService: ICommandService,
45
@IWorkspacesService workspacesService: IWorkspacesService,
46
@IMenuService menuService: IMenuService,
47
@IContextKeyService contextKeyService: IContextKeyService,
48
@IInstantiationService instantiationService: IInstantiationService,
49
@IFileDialogService fileDialogService: IFileDialogService,
50
@IQuickInputService quickInputService: IQuickInputService,
51
@IAgentHostFilterService private readonly _agentHostFilterService: IAgentHostFilterService,
52
) {
53
super(
54
actionWidgetService,
55
storageService,
56
uriIdentityService,
57
sessionsProvidersService,
58
remoteAgentHostService,
59
configurationService,
60
commandService,
61
workspacesService,
62
menuService,
63
contextKeyService,
64
instantiationService,
65
fileDialogService,
66
quickInputService,
67
);
68
69
// When the scoped host changes, if the current selection no longer
70
// belongs to the selected host, reset it: prefer the most recent
71
// workspace for the new host, otherwise clear the selection.
72
this._register(this._agentHostFilterService.onDidChange(() => this._onScopedHostChanged()));
73
}
74
75
protected override _showTabs(): boolean {
76
// Scoped picker is already filtered to a single host \u2014 the categorical
77
// tab bar would be redundant.
78
return false;
79
}
80
81
private _onScopedHostChanged(): void {
82
const scopedProviderId = this._agentHostFilterService.selectedProviderId;
83
const current = this.selectedProject;
84
if (current && scopedProviderId !== undefined && current.providerId === scopedProviderId) {
85
this._onDidChangeSelection.fire();
86
return;
87
}
88
89
const firstRecent = scopedProviderId !== undefined
90
? this._getRecentWorkspaces().find(w => w.providerId === scopedProviderId)
91
: undefined;
92
if (firstRecent) {
93
this.setSelectedWorkspace({ providerId: firstRecent.providerId, workspace: firstRecent.workspace });
94
return;
95
}
96
97
this.clearSelection();
98
this._onDidSelectWorkspace.fire(undefined);
99
}
100
101
protected override _buildItems(): IActionListItem<IWorkspacePickerItem>[] {
102
const items: IActionListItem<IWorkspacePickerItem>[] = [];
103
104
const scopedProviderId = this._agentHostFilterService.selectedProviderId;
105
if (scopedProviderId === undefined) {
106
return [];
107
}
108
const provider = this.sessionsProvidersService.getProvider(scopedProviderId);
109
if (!provider) {
110
return items;
111
}
112
113
// 1. Recent workspaces for the scoped provider
114
const recents = this._getRecentWorkspaces().filter(w => w.providerId === scopedProviderId);
115
for (const { workspace, providerId } of recents) {
116
const selection: IWorkspaceSelection = { providerId, workspace };
117
items.push({
118
kind: ActionListItemKind.Action,
119
label: workspace.label,
120
description: workspace.description,
121
group: { title: '', icon: workspace.icon },
122
item: { selection, checked: this._isSelectedWorkspace(selection) || undefined },
123
onRemove: () => this._removeRecentWorkspace(selection),
124
});
125
}
126
127
// 2. "Select Folder..." — dispatches the scoped provider's first browse action
128
const allBrowseActions = this._getAllBrowseActions();
129
const browseIndex = allBrowseActions.findIndex(a => a.providerId === scopedProviderId);
130
if (browseIndex >= 0 && !this._isProviderUnavailable(scopedProviderId)) {
131
if (items.length > 0) {
132
items.push({ kind: ActionListItemKind.Separator, label: '' });
133
}
134
items.push({
135
kind: ActionListItemKind.Action,
136
label: localize('scopedWorkspacePicker.selectFolder', "Select Folder..."),
137
group: { title: '', icon: Codicon.folderOpened },
138
item: { browseActionIndex: browseIndex },
139
});
140
}
141
142
return items;
143
}
144
}
145
146