diff --git a/src/CodingWithCalvin.ProjectRenamifier/CodingWithCalvin.ProjectRenamifier.csproj b/src/CodingWithCalvin.ProjectRenamifier/CodingWithCalvin.ProjectRenamifier.csproj index e409917..e5e3a35 100644 --- a/src/CodingWithCalvin.ProjectRenamifier/CodingWithCalvin.ProjectRenamifier.csproj +++ b/src/CodingWithCalvin.ProjectRenamifier/CodingWithCalvin.ProjectRenamifier.csproj @@ -72,6 +72,7 @@ + True diff --git a/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs b/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs index 5842831..9434166 100644 --- a/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs +++ b/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs @@ -84,6 +84,9 @@ private void RenameProject(Project project, DTE2 dte) var referencingProjects = ProjectReferenceService.FindProjectsReferencingTarget(dte.Solution, projectFilePath); var oldProjectFilePath = projectFilePath; + // Capture the parent solution folder before removal + var parentSolutionFolder = SolutionFolderService.GetParentSolutionFolder(project); + // Remove project from solution before file operations dte.Solution.Remove(project); @@ -102,15 +105,14 @@ private void RenameProject(Project project, DTE2 dte) // Update references in projects that referenced this project ProjectReferenceService.UpdateProjectReferences(referencingProjects, oldProjectFilePath, projectFilePath); - // Re-add project to solution with new path - dte.Solution.AddFromFile(projectFilePath); + // Re-add project to solution, preserving solution folder location + SolutionFolderService.AddProjectToSolution(dte.Solution, projectFilePath, parentSolutionFolder); // Update using statements across the entire solution SourceFileService.UpdateUsingStatementsInSolution(dte.Solution, currentName, newName); // TODO: Implement remaining rename operations // See open issues for requirements: - // - #11: Solution folder support // - #12: Progress indication // - #13: Error handling and rollback } diff --git a/src/CodingWithCalvin.ProjectRenamifier/Services/SolutionFolderService.cs b/src/CodingWithCalvin.ProjectRenamifier/Services/SolutionFolderService.cs new file mode 100644 index 0000000..793b844 --- /dev/null +++ b/src/CodingWithCalvin.ProjectRenamifier/Services/SolutionFolderService.cs @@ -0,0 +1,58 @@ +using EnvDTE; +using EnvDTE80; + +namespace CodingWithCalvin.ProjectRenamifier.Services +{ + /// + /// Service for managing solution folder operations. + /// + internal static class SolutionFolderService + { + /// + /// Gets the solution folder that contains the specified project, if any. + /// + /// The project to find the parent folder for. + /// The parent solution folder project, or null if the project is at the solution root. + public static Project GetParentSolutionFolder(Project project) + { + ThreadHelper.ThrowIfNotOnUIThread(); + + if (project?.ParentProjectItem?.ContainingProject != null) + { + var parent = project.ParentProjectItem.ContainingProject; + + // Verify it's actually a solution folder + if (parent.Kind == EnvDTE.Constants.vsProjectKindSolutionItems) + { + return parent; + } + } + + return null; + } + + /// + /// Adds a project to the solution, placing it in the specified solution folder if provided. + /// + /// The solution to add the project to. + /// The full path to the project file. + /// The solution folder to add the project to, or null for solution root. + /// The added project. + public static Project AddProjectToSolution(Solution solution, string projectFilePath, Project parentSolutionFolder) + { + ThreadHelper.ThrowIfNotOnUIThread(); + + if (parentSolutionFolder != null) + { + // Add to the solution folder + var solutionFolder = (SolutionFolder)parentSolutionFolder.Object; + return solutionFolder.AddFromFile(projectFilePath); + } + else + { + // Add to solution root + return solution.AddFromFile(projectFilePath); + } + } + } +}