diff --git a/src/SharpIDE.Application/Features/Search/FindFilesSearchResult.cs b/src/SharpIDE.Application/Features/Search/FindFilesSearchResult.cs new file mode 100644 index 0000000..a8a696f --- /dev/null +++ b/src/SharpIDE.Application/Features/Search/FindFilesSearchResult.cs @@ -0,0 +1,9 @@ +using OneOf; +using SharpIDE.Application.Features.SolutionDiscovery; + +namespace SharpIDE.Application.Features.Search; + +public class FindFilesSearchResult +{ + public required SharpIdeFile File { get; set; } +} diff --git a/src/SharpIDE.Application/Features/Search/SearchResult.cs b/src/SharpIDE.Application/Features/Search/FindInFilesSearchResult.cs similarity index 88% rename from src/SharpIDE.Application/Features/Search/SearchResult.cs rename to src/SharpIDE.Application/Features/Search/FindInFilesSearchResult.cs index 9bd86cd..b0b9e3e 100644 --- a/src/SharpIDE.Application/Features/Search/SearchResult.cs +++ b/src/SharpIDE.Application/Features/Search/FindInFilesSearchResult.cs @@ -2,7 +2,7 @@ namespace SharpIDE.Application.Features.Search; -public class SearchResult +public class FindInFilesSearchResult { public required SharpIdeFile File { get; set; } public required int Line { get; set; } diff --git a/src/SharpIDE.Application/Features/Search/SearchService.cs b/src/SharpIDE.Application/Features/Search/SearchService.cs index aa546b4..6ab9391 100644 --- a/src/SharpIDE.Application/Features/Search/SearchService.cs +++ b/src/SharpIDE.Application/Features/Search/SearchService.cs @@ -7,16 +7,16 @@ namespace SharpIDE.Application.Features.Search; public static class SearchService { - public static async Task> FindInFiles(SharpIdeSolutionModel solutionModel, string searchTerm, CancellationToken cancellationToken) + public static async Task> FindInFiles(SharpIdeSolutionModel solutionModel, string searchTerm, CancellationToken cancellationToken) { - if (searchTerm.Length < 4) + if (searchTerm.Length < 4) // TODO: halt search once 100 results are found, and remove this restriction { return []; } var timer = Stopwatch.StartNew(); var files = solutionModel.AllFiles; - ConcurrentBag results = []; + ConcurrentBag results = []; await Parallel.ForEachAsync(files, cancellationToken, async (file, ct) => { if (cancellationToken.IsCancellationRequested) return; @@ -25,7 +25,7 @@ public static class SearchService if (cancellationToken.IsCancellationRequested) return; if (line.Contains(searchTerm, StringComparison.OrdinalIgnoreCase)) { - results.Add(new SearchResult + results.Add(new FindInFilesSearchResult { File = file, Line = index + 1, @@ -40,4 +40,31 @@ public static class SearchService Console.WriteLine($"Search completed in {timer.ElapsedMilliseconds} ms. Found {results.Count} results. {(cancellationToken.IsCancellationRequested ? "(Cancelled)" : "")}"); return results.ToList(); } + + public static async Task> FindFiles(SharpIdeSolutionModel solutionModel, string searchTerm, CancellationToken cancellationToken) + { + if (searchTerm.Length < 2) // TODO: halt search once 100 results are found, and remove this restriction + { + return []; + } + + var timer = Stopwatch.StartNew(); + var files = solutionModel.AllFiles; + ConcurrentBag results = []; + await Parallel.ForEachAsync(files, cancellationToken, async (file, ct) => + { + if (cancellationToken.IsCancellationRequested) return; + if (file.Name.Contains(searchTerm, StringComparison.OrdinalIgnoreCase)) + { + results.Add(new FindFilesSearchResult + { + File = file + }); + } + } + ).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); + timer.Stop(); + Console.WriteLine($"File search completed in {timer.ElapsedMilliseconds} ms. Found {results.Count} results. {(cancellationToken.IsCancellationRequested ? "(Cancelled)" : "")}"); + return results.ToList(); + } } diff --git a/src/SharpIDE.Godot/Features/Search/SearchAllFiles/SearchAllFilesResultComponent.cs b/src/SharpIDE.Godot/Features/Search/SearchAllFiles/SearchAllFilesResultComponent.cs new file mode 100644 index 0000000..d7306f8 --- /dev/null +++ b/src/SharpIDE.Godot/Features/Search/SearchAllFiles/SearchAllFilesResultComponent.cs @@ -0,0 +1,43 @@ +using Godot; +using SharpIDE.Application.Features.Analysis; +using SharpIDE.Application.Features.Search; + +namespace SharpIDE.Godot.Features.Search.SearchAllFiles; + +public partial class SearchAllFilesResultComponent : MarginContainer +{ + private TextureRect _textureRect = null!; + private Label _fileNameLabel = null!; + private Label _filePathLabel = null!; + private Button _button = null!; + + private Texture2D _csharpFileIcon = ResourceLoader.Load("uid://do0edciarrnp0"); + private Texture2D _folderIcon = ResourceLoader.Load("uid://xc8srvqwlwng"); + + public SearchAllFilesWindow ParentSearchAllFilesWindow { get; set; } = null!; + public FindFilesSearchResult Result { get; set; } = null!; + + public override void _Ready() + { + _button = GetNode