Skip to content

Commit 18525fb

Browse files
authored
feat(solution): preserve solution folder location during rename (#31)
1 parent 4268611 commit 18525fb

File tree

3 files changed

+64
-3
lines changed

3 files changed

+64
-3
lines changed

src/CodingWithCalvin.ProjectRenamifier/CodingWithCalvin.ProjectRenamifier.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
<Compile Include="ProjectRenamifierPackage.cs" />
7373
<Compile Include="Services\ProjectFileService.cs" />
7474
<Compile Include="Services\ProjectReferenceService.cs" />
75+
<Compile Include="Services\SolutionFolderService.cs" />
7576
<Compile Include="Services\SourceFileService.cs" />
7677
<Compile Include="source.extension.cs">
7778
<AutoGen>True</AutoGen>

src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ private void RenameProject(Project project, DTE2 dte)
8484
var referencingProjects = ProjectReferenceService.FindProjectsReferencingTarget(dte.Solution, projectFilePath);
8585
var oldProjectFilePath = projectFilePath;
8686

87+
// Capture the parent solution folder before removal
88+
var parentSolutionFolder = SolutionFolderService.GetParentSolutionFolder(project);
89+
8790
// Remove project from solution before file operations
8891
dte.Solution.Remove(project);
8992

@@ -102,15 +105,14 @@ private void RenameProject(Project project, DTE2 dte)
102105
// Update references in projects that referenced this project
103106
ProjectReferenceService.UpdateProjectReferences(referencingProjects, oldProjectFilePath, projectFilePath);
104107

105-
// Re-add project to solution with new path
106-
dte.Solution.AddFromFile(projectFilePath);
108+
// Re-add project to solution, preserving solution folder location
109+
SolutionFolderService.AddProjectToSolution(dte.Solution, projectFilePath, parentSolutionFolder);
107110

108111
// Update using statements across the entire solution
109112
SourceFileService.UpdateUsingStatementsInSolution(dte.Solution, currentName, newName);
110113

111114
// TODO: Implement remaining rename operations
112115
// See open issues for requirements:
113-
// - #11: Solution folder support
114116
// - #12: Progress indication
115117
// - #13: Error handling and rollback
116118
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using EnvDTE;
2+
using EnvDTE80;
3+
4+
namespace CodingWithCalvin.ProjectRenamifier.Services
5+
{
6+
/// <summary>
7+
/// Service for managing solution folder operations.
8+
/// </summary>
9+
internal static class SolutionFolderService
10+
{
11+
/// <summary>
12+
/// Gets the solution folder that contains the specified project, if any.
13+
/// </summary>
14+
/// <param name="project">The project to find the parent folder for.</param>
15+
/// <returns>The parent solution folder project, or null if the project is at the solution root.</returns>
16+
public static Project GetParentSolutionFolder(Project project)
17+
{
18+
ThreadHelper.ThrowIfNotOnUIThread();
19+
20+
if (project?.ParentProjectItem?.ContainingProject != null)
21+
{
22+
var parent = project.ParentProjectItem.ContainingProject;
23+
24+
// Verify it's actually a solution folder
25+
if (parent.Kind == EnvDTE.Constants.vsProjectKindSolutionItems)
26+
{
27+
return parent;
28+
}
29+
}
30+
31+
return null;
32+
}
33+
34+
/// <summary>
35+
/// Adds a project to the solution, placing it in the specified solution folder if provided.
36+
/// </summary>
37+
/// <param name="solution">The solution to add the project to.</param>
38+
/// <param name="projectFilePath">The full path to the project file.</param>
39+
/// <param name="parentSolutionFolder">The solution folder to add the project to, or null for solution root.</param>
40+
/// <returns>The added project.</returns>
41+
public static Project AddProjectToSolution(Solution solution, string projectFilePath, Project parentSolutionFolder)
42+
{
43+
ThreadHelper.ThrowIfNotOnUIThread();
44+
45+
if (parentSolutionFolder != null)
46+
{
47+
// Add to the solution folder
48+
var solutionFolder = (SolutionFolder)parentSolutionFolder.Object;
49+
return solutionFolder.AddFromFile(projectFilePath);
50+
}
51+
else
52+
{
53+
// Add to solution root
54+
return solution.AddFromFile(projectFilePath);
55+
}
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)