Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/copilotCLIFolderMru.ts
13405 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 { CancellationToken, Uri } from 'vscode';
7
import { IGitService } from '../../../../platform/git/common/gitService';
8
import { IWorkspaceService } from '../../../../platform/workspace/common/workspaceService';
9
import { raceTimeout } from '../../../../util/vs/base/common/async';
10
import { ResourceMap, ResourceSet } from '../../../../util/vs/base/common/map';
11
import { ChatSessionStatus } from '../../../../vscodeTypes';
12
import { FolderRepositoryMRUEntry, IChatFolderMruService } from '../../common/folderRepositoryManager';
13
import { ICopilotCLISessionService } from '../../copilotcli/node/copilotcliSessionService';
14
15
16
type Mutable<T> = {
17
-readonly [K in keyof T]: T[K];
18
};
19
20
export class CopilotCLIFolderMruService implements IChatFolderMruService {
21
declare _serviceBrand: undefined;
22
private readonly removedFolders = new ResourceSet();
23
private cachedEntries: FolderRepositoryMRUEntry[] | undefined = undefined;
24
constructor(
25
@ICopilotCLISessionService private readonly sessionService: ICopilotCLISessionService,
26
@IGitService private readonly gitService: IGitService,
27
@IWorkspaceService private readonly workspaceService: IWorkspaceService,
28
) { }
29
30
async getRecentlyUsedFolders(token: CancellationToken): Promise<FolderRepositoryMRUEntry[]> {
31
const cachedEntries = this.cachedEntries;
32
const entries = this.getRecentlyUsedFoldersImpl(token).then(entries => {
33
this.cachedEntries = entries;
34
return entries;
35
});
36
37
return (cachedEntries ? cachedEntries : await entries).filter(e => {
38
if (this.removedFolders.has(e.folder)) {
39
return false;
40
}
41
return true;
42
});
43
}
44
45
async getRecentlyUsedFoldersImpl(token: CancellationToken): Promise<FolderRepositoryMRUEntry[]> {
46
const mruEntries = new ResourceMap<Mutable<FolderRepositoryMRUEntry>>();
47
48
// We're getting MRU, don't delay session retrieve by more than 5s
49
const sessions = await raceTimeout(this.sessionService.getAllSessions(token), 5_000);
50
51
for (const session of (sessions ?? [])) {
52
if (!session.workingDirectory) {
53
continue;
54
}
55
if (session.workingDirectory.path.includes('.worktrees/copilot-')) {
56
continue;
57
}
58
const isActive = session.status === ChatSessionStatus.InProgress;
59
const lastAccessed = session.timing?.lastRequestEnded ?? session.timing?.endTime ?? session.timing?.lastRequestStarted ?? session.timing?.startTime ?? (isActive ? Date.now() : 0);
60
mruEntries.set(session.workingDirectory, {
61
folder: session.workingDirectory,
62
repository: undefined,
63
lastAccessed,
64
});
65
}
66
67
// Add recent git repositories
68
for (const repo of this.gitService.getRecentRepositories()) {
69
if (repo.rootUri.path.includes('.worktrees/copilot-')) {
70
continue;
71
}
72
const existingEntry = mruEntries.get(repo.rootUri);
73
if (existingEntry) {
74
existingEntry.lastAccessed = Math.max(existingEntry.lastAccessed, repo.lastAccessTime);
75
existingEntry.repository = repo.rootUri;
76
continue;
77
}
78
mruEntries.set(repo.rootUri, {
79
folder: repo.rootUri,
80
repository: repo.rootUri,
81
lastAccessed: repo.lastAccessTime,
82
});
83
}
84
85
// If in mult-root folder add the folders as well, but on top.
86
for (const folder of this.workspaceService.getWorkspaceFolders()) {
87
const existingEntry = mruEntries.get(folder);
88
if (existingEntry) {
89
continue;
90
}
91
mruEntries.set(folder, {
92
folder: folder,
93
repository: undefined,
94
lastAccessed: Date.now(),
95
});
96
}
97
98
return Array.from(mruEntries.values())
99
.sort((a, b) => b.lastAccessed - a.lastAccessed);
100
}
101
102
async deleteRecentlyUsedFolder(folder: Uri): Promise<void> {
103
this.removedFolders.add(folder);
104
}
105
}
106
107