Display sln explorer items

This commit is contained in:
Matt Parker
2025-08-01 00:11:28 +10:00
parent 5dc929f97a
commit d5605f0860
7 changed files with 180 additions and 78 deletions

View File

@@ -0,0 +1,18 @@
namespace SharpIDE.Application.Features.SolutionDiscovery;
public class SharpIdeFile
{
public required string Path { get; set; }
public required string Name { get; set; }
}
public class SharpIdeFolder
{
public required string Path { get; set; }
public required string Name { get; set; }
public required List<SharpIdeFile> Files { get; set; }
public required List<SharpIdeFolder> Folders { get; set; }
// public required int Depth { get; set; }
public bool Expanded { get; set; }
}

View File

@@ -0,0 +1,86 @@
using System.Collections.Concurrent;
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
namespace SharpIDE.Application.Features.SolutionDiscovery;
public static class TreeMapperV2
{
public static List<SharpIdeFolder> GetSubFolders(string csprojectPath)
{
var projectDirectory = Path.GetDirectoryName(csprojectPath)!;
var rootFolder = new SharpIdeFolder
{
Path = projectDirectory,
Name = null!,
Files = [],
Folders = []
};
var subFolders = rootFolder.GetSubFolders();
return subFolders;
}
public static List<SharpIdeFolder> GetSubFolders(this SharpIdeFolder folder)
{
var directoryInfo = new DirectoryInfo(folder.Path);
ConcurrentBag<SharpIdeFolder> subFolders = [];
List<DirectoryInfo> subFolderInfos;
try
{
subFolderInfos = directoryInfo.EnumerateDirectories("*", new EnumerationOptions
{
IgnoreInaccessible = false,
AttributesToSkip = FileAttributes.ReparsePoint
}).ToList();
}
catch (UnauthorizedAccessException)
{
return subFolders.ToList();
}
Parallel.ForEach(subFolderInfos, subFolderInfo =>
{
var subFolder = new SharpIdeFolder
{
Path = subFolderInfo.FullName,
Name = subFolderInfo.Name,
Files = GetFiles(subFolderInfo),
Folders = new SharpIdeFolder
{
Path = subFolderInfo.FullName,
Name = subFolderInfo.Name,
Files = [],
Folders = []
}.GetSubFolders()
};
subFolders.Add(subFolder);
});
return subFolders.ToList();
}
public static List<SharpIdeFile> GetFiles(string csprojectPath)
{
var projectDirectory = Path.GetDirectoryName(csprojectPath)!;
var directoryInfo = new DirectoryInfo(projectDirectory);
return GetFiles(directoryInfo);
}
public static List<SharpIdeFile> GetFiles(DirectoryInfo directoryInfo)
{
List<FileInfo> fileInfos;
try
{
fileInfos = directoryInfo.EnumerateFiles().ToList();
}
catch (UnauthorizedAccessException)
{
return [];
}
return fileInfos.Select(f => new SharpIdeFile
{
Path = f.FullName,
Name = f.Name
}).ToList();
}
}

View File

@@ -21,4 +21,5 @@ public class IntermediateProjectModel
{
public required SolutionProjectModel Model { get; set; }
public required string FullFilePath { get; set; }
public required Guid Id { get; set; }
}

View File

@@ -17,4 +17,6 @@ public class SharpIdeProjectModel
{
public required string Name { get; set; }
public required string FilePath { get; set; }
public required List<SharpIdeFolder> Folders { get; set; }
public required List<SharpIdeFile> Files { get; set; }
}

View File

@@ -27,11 +27,14 @@ public static class VsPersistenceMapper
return solutionModel;
}
private static SharpIdeProjectModel GetSharpIdeProjectModel(IntermediateProjectModel projectModel) => new SharpIdeProjectModel()
{
Name = projectModel.Model.DisplayName!,
FilePath = projectModel.Model.FilePath,
};
private static SharpIdeProjectModel GetSharpIdeProjectModel(IntermediateProjectModel projectModel) => new SharpIdeProjectModel
{
Name = projectModel.Model.ActualDisplayName,
FilePath = projectModel.Model.FilePath,
Files = TreeMapperV2.GetFiles(projectModel.FullFilePath),
Folders = TreeMapperV2.GetSubFolders(projectModel.FullFilePath)
};
private static SharpIdeSolutionFolder GetSharpIdeSolutionFolder(IntermediateSlnFolderModel folderModel) => new SharpIdeSolutionFolder()
{
@@ -49,7 +52,7 @@ public static class VsPersistenceMapper
var rootFolders = vsSolution.SolutionFolders
.Where(f => f.Parent is null)
.Select(f => BuildFolderTree(f, vsSolution.SolutionFolders, vsSolution.SolutionProjects))
.Select(f => BuildFolderTree(f, solutionFilePath, vsSolution.SolutionFolders, vsSolution.SolutionProjects))
.ToList();
var solutionModel = new IntermediateSolutionModel
@@ -59,19 +62,20 @@ public static class VsPersistenceMapper
Projects = vsSolution.SolutionProjects.Where(p => p.Parent is null).Select(s => new IntermediateProjectModel
{
Model = s,
FullFilePath = Path.GetFullPath(s.FilePath)
Id = s.Id,
FullFilePath = new DirectoryInfo(Path.Join(Path.GetDirectoryName(solutionFilePath), s.FilePath)).FullName
}).ToList(),
SolutionFolders = rootFolders
};
return solutionModel;
}
private static IntermediateSlnFolderModel BuildFolderTree(SolutionFolderModel folder,
private static IntermediateSlnFolderModel BuildFolderTree(SolutionFolderModel folder, string solutionFilePath,
IReadOnlyList<SolutionFolderModel> allSolutionFolders, IReadOnlyList<SolutionProjectModel> allSolutionProjects)
{
var childFolders = allSolutionFolders
.Where(f => f.Parent == folder)
.Select(f => BuildFolderTree(f, allSolutionFolders, allSolutionProjects))
.Select(f => BuildFolderTree(f, solutionFilePath, allSolutionFolders, allSolutionProjects))
.ToList();
var projectsInFolder = allSolutionProjects
@@ -79,7 +83,8 @@ public static class VsPersistenceMapper
.Select(s => new IntermediateProjectModel
{
Model = s,
FullFilePath = Path.GetFullPath(s.FilePath)
Id = s.Id,
FullFilePath = new DirectoryInfo(Path.Join(Path.GetDirectoryName(solutionFilePath), s.FilePath)).FullName
})
.ToList();