Skip to content

Commit 918ba66

Browse files
committed
updateprojecturi to updateproject and include debounce updates
1 parent ba89af2 commit 918ba66

4 files changed

Lines changed: 77 additions & 46 deletions

File tree

src/features/projectManager.ts

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -170,33 +170,39 @@ export class PythonProjectManagerImpl implements PythonProjectManager {
170170
this._onDidChangeProjects.fire(Array.from(this._projects.values()));
171171
}
172172

173-
updateProjectUri(oldUri: Uri, newUri: Uri): void {
174-
const oldKey = oldUri.toString();
175-
const project = this._projects.get(oldKey);
176-
173+
/**
174+
* Update a project by removing the old one and adding a new one with updated properties.
175+
* @param existingUri The URI of the project to update.
176+
* @param newName The new name for the project (optional, defaults to old name).
177+
* @param newUri The new URI for the project (optional, defaults to old URI).
178+
* @param newOptions New options for the project (optional, merged with old options).
179+
*/
180+
async updateProject(
181+
existingUri: Uri,
182+
newName?: string,
183+
newUri?: Uri,
184+
newOptions?: { description?: string; tooltip?: string | MarkdownString; iconPath?: IconPath },
185+
): Promise<void> {
186+
const project = this.get(existingUri);
177187
if (!project) {
178188
return;
179189
}
180190

181-
// Remove the project with the old URI
182-
this._projects.delete(oldKey);
183-
184-
// Create a new project instance with the updated URI
185-
const updatedProject = this.create(
186-
path.basename(newUri.fsPath),
187-
newUri,
188-
{
189-
description: project.description,
190-
tooltip: project.tooltip,
191-
iconPath: (project as PythonProjectsImpl).iconPath, // Cast to implementation to access iconPath
192-
}
193-
);
194-
195-
// Add the updated project
196-
this._projects.set(newUri.toString(), updatedProject);
197-
198-
// Fire the change event to update the view
199-
this._onDidChangeProjects.fire(Array.from(this._projects.values()));
191+
// Remove the old project
192+
this.remove(project);
193+
194+
// Prepare new values
195+
const name = newName ?? project.name;
196+
const uri = newUri ?? project.uri;
197+
const options = {
198+
description: newOptions?.description ?? project.description,
199+
tooltip: newOptions?.tooltip ?? project.tooltip,
200+
iconPath: newOptions?.iconPath ?? (project as PythonProjectsImpl).iconPath,
201+
};
202+
203+
// Create and add the new project
204+
const updatedProject = this.create(name, uri, options);
205+
await this.add(updatedProject);
200206
}
201207

202208
getProjects(uris?: Uri[]): ReadonlyArray<PythonProject> {
@@ -212,7 +218,7 @@ export class PythonProjectManagerImpl implements PythonProjectManager {
212218
}
213219
return projects;
214220
}
215-
}
221+
}0
216222

217223
get(uri: Uri): PythonProject | undefined {
218224
let pythonProject = this._projects.get(uri.toString());

src/features/views/projectView.ts

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -230,24 +230,30 @@ export class ProjectView implements TreeDataProvider<ProjectTreeItem> {
230230
return element.parent;
231231
}
232232

233-
private handleFileRenames(e: { readonly files: ReadonlyArray<{ readonly oldUri: Uri; readonly newUri: Uri }> }): void {
233+
private async handleFileRenames(e: {
234+
readonly files: ReadonlyArray<{ readonly oldUri: Uri; readonly newUri: Uri }>;
235+
}): Promise<void> {
234236
const projects = this.projectManager.getProjects();
235-
237+
236238
for (const { oldUri, newUri } of e.files) {
237239
// Check if any project matches the old URI exactly or is contained within it
238-
const affectedProjects = projects.filter(project => {
240+
const affectedProjects = projects.filter((project) => {
239241
const projectPath = project.uri.fsPath;
240242
const oldPath = oldUri.fsPath;
241-
243+
242244
// Check if the project path is the same as or is a child of the renamed path
243-
return projectPath === oldPath || projectPath.startsWith(oldPath + '/') || projectPath.startsWith(oldPath + '\\');
245+
return (
246+
projectPath === oldPath ||
247+
projectPath.startsWith(oldPath + '/') ||
248+
projectPath.startsWith(oldPath + '\\')
249+
);
244250
});
245-
251+
246252
for (const project of affectedProjects) {
247253
const projectPath = project.uri.fsPath;
248254
const oldPath = oldUri.fsPath;
249255
const newPath = newUri.fsPath;
250-
256+
251257
// Calculate the new project path
252258
let newProjectPath: string;
253259
if (projectPath === oldPath) {
@@ -258,28 +264,39 @@ export class ProjectView implements TreeDataProvider<ProjectTreeItem> {
258264
const relativePath = projectPath.substring(oldPath.length);
259265
newProjectPath = newPath + relativePath;
260266
}
261-
267+
262268
const newProjectUri = Uri.file(newProjectPath);
263-
this.projectManager.updateProjectUri(project.uri, newProjectUri);
269+
await this.projectManager.updateProject(project.uri, undefined, newProjectUri);
270+
}
271+
272+
if (affectedProjects.length > 0) {
273+
// only trigger update if there are affected projects
274+
this.debouncedUpdateProject.trigger();
264275
}
265276
}
266277
}
267278

268279
private handleFileDeletions(e: { readonly files: ReadonlyArray<Uri> }): void {
269280
const projects = this.projectManager.getProjects();
270-
281+
271282
for (const deletedUri of e.files) {
272283
// Check if any project matches the deleted URI exactly or is contained within it
273-
const affectedProjects = projects.filter(project => {
284+
const affectedProjects = projects.filter((project) => {
274285
const projectPath = project.uri.fsPath;
275286
const deletedPath = deletedUri.fsPath;
276-
287+
277288
// Check if the project path is the same as or is a child of the deleted path
278-
return projectPath === deletedPath || projectPath.startsWith(deletedPath + '/') || projectPath.startsWith(deletedPath + '\\');
289+
return (
290+
projectPath === deletedPath ||
291+
projectPath.startsWith(deletedPath + '/') ||
292+
projectPath.startsWith(deletedPath + '\\')
293+
);
279294
});
280-
295+
281296
if (affectedProjects.length > 0) {
282297
this.projectManager.remove(affectedProjects);
298+
// If there are affected projects, trigger an update
299+
this.debouncedUpdateProject.trigger();
283300
}
284301
}
285302
}

src/internal.api.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,12 @@ export interface PythonProjectManager extends Disposable {
287287
): PythonProject;
288288
add(pyWorkspace: PythonProject | PythonProject[]): Promise<void>;
289289
remove(pyWorkspace: PythonProject | PythonProject[]): void;
290-
updateProjectUri(oldUri: Uri, newUri: Uri): void;
290+
updateProject(
291+
existingUri: Uri,
292+
newName?: string,
293+
newUri?: Uri,
294+
newOptions?: { description?: string; tooltip?: string | MarkdownString; iconPath?: IconPath },
295+
): Promise<void>;
291296
getProjects(uris?: Uri[]): ReadonlyArray<PythonProject>;
292297
get(uri: Uri): PythonProject | undefined;
293298
onDidChangeProjects: Event<PythonProject[] | undefined>;

src/test/features/projectManager.updateUri.unit.test.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,22 @@ suite('Project Manager Update URI tests', () => {
2121
// Create a project and manually add it to the internal map to bypass the complex add method
2222
const project = projectManager.create('TestProject', oldUri, {
2323
description: 'Test project',
24-
tooltip: 'Test tooltip'
24+
tooltip: 'Test tooltip',
2525
});
26-
26+
2727
// Access private _projects map to manually add the project for testing
28-
(projectManager as unknown as { _projects: Map<string, PythonProject> })._projects.set(oldUri.toString(), project);
28+
(projectManager as unknown as { _projects: Map<string, PythonProject> })._projects.set(
29+
oldUri.toString(),
30+
project,
31+
);
2932

3033
// Verify project exists with old URI
3134
const oldProject = projectManager.get(oldUri);
3235
assert.ok(oldProject, 'Project should exist with old URI');
3336
assert.equal(oldProject.uri.fsPath, oldUri.fsPath, 'Old URI should match');
3437

3538
// Update the project URI
36-
projectManager.updateProjectUri(oldUri, newUri);
39+
projectManager.updateProject(oldUri, 'project', newUri);
3740

3841
// Verify project no longer exists with old URI
3942
const oldProjectAfterUpdate = projectManager.get(oldUri);
@@ -55,7 +58,7 @@ suite('Project Manager Update URI tests', () => {
5558
// Try to update a project that doesn't exist
5659
// This should not throw an error
5760
assert.doesNotThrow(() => {
58-
projectManager.updateProjectUri(oldUri, newUri);
61+
projectManager.updateProject(oldUri, 'project', newUri);
5962
}, 'Should handle non-existent project gracefully');
6063

6164
// Verify no project was created
@@ -70,7 +73,7 @@ suite('Project Manager Update URI tests', () => {
7073
// Create projects and manually add them to the internal map
7174
const project1 = projectManager.create('Project1', project1Uri);
7275
const project2 = projectManager.create('Project2', project2Uri);
73-
76+
7477
// Access private _projects map to manually add projects for testing
7578
const pmWithPrivateAccess = projectManager as unknown as { _projects: Map<string, PythonProject> };
7679
pmWithPrivateAccess._projects.set(project1Uri.toString(), project1);
@@ -87,4 +90,4 @@ suite('Project Manager Update URI tests', () => {
8790
assert.equal(projectManager.get(project1Uri), undefined, 'Project1 should be removed');
8891
assert.equal(projectManager.get(project2Uri), undefined, 'Project2 should be removed');
8992
});
90-
});
93+
});

0 commit comments

Comments
 (0)