diff --git a/src/SharpIDE.Application/Features/Analysis/RoslynAnalysis.cs b/src/SharpIDE.Application/Features/Analysis/RoslynAnalysis.cs index 5a5095f..ebaeed5 100644 --- a/src/SharpIDE.Application/Features/Analysis/RoslynAnalysis.cs +++ b/src/SharpIDE.Application/Features/Analysis/RoslynAnalysis.cs @@ -745,7 +745,7 @@ public class RoslynAnalysis using var _ = SharpIdeOtel.Source.StartActivity($"{nameof(RoslynAnalysis)}.{nameof(AddDocument)}"); await _solutionLoadedTcs.Task; Guard.Against.Null(fileModel, nameof(fileModel)); - Guard.Against.NullOrEmpty(content, nameof(content)); + Guard.Against.Null(content, nameof(content)); var project = _workspace!.CurrentSolution.Projects.Single(s => s.FilePath == ((IChildSharpIdeNode)fileModel).GetNearestProjectNode()!.FilePath); diff --git a/src/SharpIDE.Application/Features/FileWatching/IdeFileExternalChangeHandler.cs b/src/SharpIDE.Application/Features/FileWatching/IdeFileExternalChangeHandler.cs index d48a09e..2a9bd8b 100644 --- a/src/SharpIDE.Application/Features/FileWatching/IdeFileExternalChangeHandler.cs +++ b/src/SharpIDE.Application/Features/FileWatching/IdeFileExternalChangeHandler.cs @@ -23,6 +23,19 @@ public class IdeFileExternalChangeHandler if (sharpIdeFile == null) { // If sharpIdeFile is null, it means the file was created externally, and we need to create it and add it to the solution model + var createdFileDirectory = Path.GetDirectoryName(filePath)!; + + // TODO: Handle being contained by a project directly + //var containingProject = SolutionModel.AllProjects.SingleOrDefault(p => createdFileDirectory == Path.GetDirectoryName(p.FilePath)); + var containingFolder = SolutionModel.AllFolders.SingleOrDefault(f => f.Path == createdFileDirectory); + if (containingFolder is null) + { + // TODO: Create the folder and add it to the solution model + } + + sharpIdeFile = new SharpIdeFile(filePath, Path.GetFileName(filePath), containingFolder, []); + containingFolder.Files.Add(sharpIdeFile); + SolutionModel.AllFiles.Add(sharpIdeFile); // sharpIdeFile = TODO; } Guard.Against.Null(sharpIdeFile, nameof(sharpIdeFile)); diff --git a/src/SharpIDE.Application/Features/FileWatching/IdeFileWatcher.cs b/src/SharpIDE.Application/Features/FileWatching/IdeFileWatcher.cs index e01045a..0d5b59d 100644 --- a/src/SharpIDE.Application/Features/FileWatching/IdeFileWatcher.cs +++ b/src/SharpIDE.Application/Features/FileWatching/IdeFileWatcher.cs @@ -73,7 +73,9 @@ public sealed class IdeFileWatcher : IDisposable private void HandleCreated(string fullPath) { - Console.WriteLine($"FileSystemWatcher: Created - {fullPath}"); + if (Path.HasExtension(fullPath) is false) return; // we don't care about directory changes + //Console.WriteLine($"FileSystemWatcher: Created - {fullPath}"); + GlobalEvents.Instance.FileSystemWatcherInternal.FileCreated.InvokeParallelFireAndForget(fullPath); } // The only changed event we care about is files, not directories diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/SharpIdeFolder.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/SharpIdeFolder.cs index a5a8a18..c37a640 100644 --- a/src/SharpIDE.Application/Features/SolutionDiscovery/SharpIdeFolder.cs +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/SharpIdeFolder.cs @@ -14,13 +14,13 @@ public class SharpIdeFolder : ISharpIdeNode, IExpandableSharpIdeNode, IChildShar public bool Expanded { get; set; } [SetsRequiredMembers] - public SharpIdeFolder(DirectoryInfo folderInfo, IExpandableSharpIdeNode parent, ConcurrentBag allFiles) + public SharpIdeFolder(DirectoryInfo folderInfo, IExpandableSharpIdeNode parent, ConcurrentBag allFiles, ConcurrentBag allFolders) { Parent = parent; Path = folderInfo.FullName; Name = folderInfo.Name; Files = folderInfo.GetFiles(this, allFiles); - Folders = this.GetSubFolders(this, allFiles); + Folders = this.GetSubFolders(this, allFiles, allFolders); } public SharpIdeFolder() diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapperV2.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapperV2.cs index b6e90d7..96cf55a 100644 --- a/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapperV2.cs +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapperV2.cs @@ -10,7 +10,7 @@ public static class TreeMapperV2 return folder.Files .Concat(folder.Folders.SelectMany(sub => sub.GetAllFiles())); } - public static List GetSubFolders(string csprojectPath, SharpIdeProjectModel sharpIdeProjectModel, ConcurrentBag allFiles) + public static List GetSubFolders(string csprojectPath, SharpIdeProjectModel sharpIdeProjectModel, ConcurrentBag allFiles, ConcurrentBag allFolders) { var projectDirectory = Path.GetDirectoryName(csprojectPath)!; var rootFolder = new SharpIdeFolder @@ -21,12 +21,12 @@ public static class TreeMapperV2 Files = [], Folders = [] }; - var subFolders = rootFolder.GetSubFolders(sharpIdeProjectModel, allFiles); + var subFolders = rootFolder.GetSubFolders(sharpIdeProjectModel, allFiles, allFolders); return subFolders; } private static readonly string[] _excludedFolders = ["bin", "obj", "node_modules"]; - public static List GetSubFolders(this SharpIdeFolder folder, IExpandableSharpIdeNode parent, ConcurrentBag allFiles) + public static List GetSubFolders(this SharpIdeFolder folder, IExpandableSharpIdeNode parent, ConcurrentBag allFiles, ConcurrentBag allFolders) { var directoryInfo = new DirectoryInfo(folder.Path); ConcurrentBag subFolders = []; @@ -47,8 +47,9 @@ public static class TreeMapperV2 Parallel.ForEach(subFolderInfos, subFolderInfo => { - var subFolder = new SharpIdeFolder(subFolderInfo, parent, allFiles); + var subFolder = new SharpIdeFolder(subFolderInfo, parent, allFiles, allFolders); subFolders.Add(subFolder); + allFolders.Add(subFolder); }); return subFolders.ToList(); diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/SharpIdeModels.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/SharpIdeModels.cs index 0bda2c8..1e79dcd 100644 --- a/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/SharpIdeModels.cs +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/SharpIdeModels.cs @@ -36,9 +36,10 @@ public class SharpIdeSolutionModel : ISharpIdeNode, IExpandableSharpIdeNode public required string FilePath { get; set; } public required string DirectoryPath { get; set; } public required List Projects { get; set; } - public required List Folders { get; set; } + public required List SlnFolders { get; set; } public required HashSet AllProjects { get; set; } public required HashSet AllFiles { get; set; } + public required HashSet AllFolders { get; set; } public bool Expanded { get; set; } [SetsRequiredMembers] @@ -47,13 +48,15 @@ public class SharpIdeSolutionModel : ISharpIdeNode, IExpandableSharpIdeNode var solutionName = Path.GetFileName(solutionFilePath); var allProjects = new ConcurrentBag(); var allFiles = new ConcurrentBag(); + var allFolders = new ConcurrentBag(); Name = solutionName; FilePath = solutionFilePath; DirectoryPath = Path.GetDirectoryName(solutionFilePath)!; - Projects = intermediateModel.Projects.Select(s => new SharpIdeProjectModel(s, allProjects, allFiles, this)).ToList(); - Folders = intermediateModel.SolutionFolders.Select(s => new SharpIdeSolutionFolder(s, allProjects, allFiles, this)).ToList(); + Projects = intermediateModel.Projects.Select(s => new SharpIdeProjectModel(s, allProjects, allFiles, allFolders, this)).ToList(); + SlnFolders = intermediateModel.SolutionFolders.Select(s => new SharpIdeSolutionFolder(s, allProjects, allFiles, allFolders, this)).ToList(); AllProjects = allProjects.ToHashSet(); AllFiles = allFiles.ToHashSet(); + AllFolders = allFolders.ToHashSet(); } } public class SharpIdeSolutionFolder : ISharpIdeNode, IExpandableSharpIdeNode, IChildSharpIdeNode @@ -66,13 +69,13 @@ public class SharpIdeSolutionFolder : ISharpIdeNode, IExpandableSharpIdeNode, IC public required IExpandableSharpIdeNode Parent { get; set; } [SetsRequiredMembers] - internal SharpIdeSolutionFolder(IntermediateSlnFolderModel intermediateModel, ConcurrentBag allProjects, ConcurrentBag allFiles, IExpandableSharpIdeNode parent) + internal SharpIdeSolutionFolder(IntermediateSlnFolderModel intermediateModel, ConcurrentBag allProjects, ConcurrentBag allFiles, ConcurrentBag allFolders, IExpandableSharpIdeNode parent) { Name = intermediateModel.Model.Name; Parent = parent; Files = intermediateModel.Files.Select(s => new SharpIdeFile(s.FullPath, s.Name, this, allFiles)).ToList(); - Folders = intermediateModel.Folders.Select(x => new SharpIdeSolutionFolder(x, allProjects, allFiles, this)).ToList(); - Projects = intermediateModel.Projects.Select(x => new SharpIdeProjectModel(x, allProjects, allFiles, this)).ToList(); + Folders = intermediateModel.Folders.Select(x => new SharpIdeSolutionFolder(x, allProjects, allFiles, allFolders, this)).ToList(); + Projects = intermediateModel.Projects.Select(x => new SharpIdeProjectModel(x, allProjects, allFiles, allFolders, this)).ToList(); } } public class SharpIdeProjectModel : ISharpIdeNode, IExpandableSharpIdeNode, IChildSharpIdeNode @@ -88,13 +91,13 @@ public class SharpIdeProjectModel : ISharpIdeNode, IExpandableSharpIdeNode, IChi public required Task MsBuildEvaluationProjectTask { get; set; } [SetsRequiredMembers] - internal SharpIdeProjectModel(IntermediateProjectModel projectModel, ConcurrentBag allProjects, ConcurrentBag allFiles, IExpandableSharpIdeNode parent) + internal SharpIdeProjectModel(IntermediateProjectModel projectModel, ConcurrentBag allProjects, ConcurrentBag allFiles, ConcurrentBag allFolders, IExpandableSharpIdeNode parent) { Parent = parent; Name = projectModel.Model.ActualDisplayName; FilePath = projectModel.FullFilePath; Files = TreeMapperV2.GetFiles(projectModel.FullFilePath, this, allFiles); - Folders = TreeMapperV2.GetSubFolders(projectModel.FullFilePath, this, allFiles); + Folders = TreeMapperV2.GetSubFolders(projectModel.FullFilePath, this, allFiles, allFolders); MsBuildEvaluationProjectTask = ProjectEvaluation.GetProject(projectModel.FullFilePath); allProjects.Add(this); } diff --git a/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs b/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs index 07fbe40..b0a004f 100644 --- a/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs +++ b/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs @@ -101,7 +101,7 @@ public partial class SolutionExplorerPanel : MarginContainer } // Add folders under solution - foreach (var folder in SolutionModel.Folders) + foreach (var folder in SolutionModel.SlnFolders) { AddSlnFolderToTree(rootItem, folder); } diff --git a/src/SharpIDE.Photino/Components/SolutionExplorer.razor b/src/SharpIDE.Photino/Components/SolutionExplorer.razor index ffd863c..2a09f9b 100644 --- a/src/SharpIDE.Photino/Components/SolutionExplorer.razor +++ b/src/SharpIDE.Photino/Components/SolutionExplorer.razor @@ -20,7 +20,7 @@ - @foreach (var folder in SolutionModel.Folders) + @foreach (var folder in SolutionModel.SlnFolders) { @GetSolutionFolderFragment(folder) }