public override Task<ISearchDataSource> GetResults (SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { return Task.Factory.StartNew (delegate { if (searchPattern.Tag != null && !validTags.Contains (searchPattern.Tag)) return null; try { var newResult = new WorkerResult (widget); newResult.pattern = searchPattern.Pattern; newResult.IncludeFiles = true; newResult.IncludeTypes = true; newResult.IncludeMembers = true; string toMatch = searchPattern.Pattern; newResult.matcher = StringMatcher.GetMatcher (toMatch, false); newResult.FullSearch = true; AllResults (lastResult, newResult, token); newResult.results.SortUpToN (new DataItemComparer (token), resultsCount); lastResult = newResult; return (ISearchDataSource)newResult.results; } catch { token.ThrowIfCancellationRequested (); throw; } }, token); }
public override Task GetResults(ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { return(Task.Run(delegate { var files = AllFiles.ToList(); var matcher = StringMatcher.GetMatcher(pattern.Pattern, false); var savedMatches = new Dictionary <string, MatchResult> (); foreach (ProjectFile file in files) { if (token.IsCancellationRequested) { break; } int rank; string matchString = System.IO.Path.GetFileName(file.FilePath); if (MatchName(savedMatches, matcher, matchString, out rank)) { searchResultCallback.ReportResult(new FileSearchResult(pattern.Pattern, matchString, rank, file, true)); } matchString = FileSearchResult.GetRelProjectPath(file); if (MatchName(savedMatches, matcher, matchString, out rank)) { searchResultCallback.ReportResult(new FileSearchResult(pattern.Pattern, matchString, rank, file, true)); } } }, token)); }
public override Task GetResults(ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { if (pattern.HasLineNumber) { return(Task.CompletedTask); } var route = new CommandTargetRoute(IdeApp.CommandService.LastCommandTarget); var matcher = StringMatcher.GetMatcher(pattern.Pattern, false); foreach (var cmd in GetAllCommands()) { if (token.IsCancellationRequested) { break; } var matchString = cmd.DisplayName; if (matcher.CalcMatchRank(matchString, out var rank)) { if ((cmd as ActionCommand)?.RuntimeAddin == currentRuntimeAddin) { rank += 1; // we prefer commands comming from the addin } searchResultCallback.ReportResult(new CommandResult(cmd, null, route, pattern.Pattern, matchString, rank)); } } return(Task.CompletedTask); }
public void Update(string searchPattern) { if (src != null) { src.Cancel(); } HideTooltip(); src = new CancellationTokenSource(); isInSearch = true; if (results.Count == 0) { QueueDraw(); } pattern = SearchPopupSearchPattern.ParsePattern(searchPattern); incompleteResults.Clear(); foreach (var _cat in categories) { var cat = _cat; var token = src.Token; cat.GetResults(pattern, maxItems, token).ContinueWith(t => { if (t.IsFaulted) { LoggingService.LogError("Error getting search results", t.Exception); } else { Application.Invoke(delegate { ShowResult(cat, t.Result ?? new NullDataSource()); }); } }, token); } }
public override Task <ISearchDataSource> GetResults(SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { return(Task.Factory.StartNew(delegate { if (searchPattern.Tag != null && !validTags.Contains(searchPattern.Tag)) { return null; } try { var newResult = new WorkerResult(widget); newResult.pattern = searchPattern.Pattern; newResult.IncludeFiles = true; newResult.IncludeTypes = true; newResult.IncludeMembers = true; string toMatch = searchPattern.Pattern; newResult.matcher = StringMatcher.GetMatcher(toMatch, false); newResult.FullSearch = true; AllResults(lastResult, newResult, token); newResult.results.SortUpToN(new DataItemComparer(token), resultsCount); lastResult = newResult; return (ISearchDataSource)newResult.results; } catch { token.ThrowIfCancellationRequested(); throw; } }, token)); }
public override Task <ISearchDataSource> GetResults(SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { // NOTE: This is run on the UI thread as checking whether or not a command is enabled is not thread-safe return(Task.Factory.StartNew(delegate { try { if (searchPattern.Tag != null && !validTags.Contains(searchPattern.Tag) || searchPattern.HasLineNumber) { return null; } WorkerResult newResult = new WorkerResult(widget); newResult.pattern = searchPattern.Pattern; newResult.matcher = StringMatcher.GetMatcher(searchPattern.Pattern, false); newResult.FullSearch = true; AllResults(lastResult, newResult, token); newResult.results.SortUpToN(new DataItemComparer(token), resultsCount); lastResult = newResult; return (ISearchDataSource)newResult.results; } catch { token.ThrowIfCancellationRequested(); throw; } }, token, TaskCreationOptions.None, Xwt.Application.UITaskScheduler)); }
public override Task<ISearchDataSource> GetResults (SearchPopupSearchPattern s, int resultsCount, CancellationToken token) { return Task.Factory.StartNew (delegate { var l = new List<INode>(); foreach(var project in IdeApp.Workspace.GetAllProjects()) { var dprj = project as AbstractDProject; if(dprj == null) continue; ModulePackage pack; foreach (var p in dprj.GetSourcePaths()) if ((pack = GlobalParseCache.GetRootPackage (p)) != null) foreach (DModule m in pack) SearchResultsIn(m, s.Pattern, l, resultsCount); foreach (var p in dprj.IncludePaths) if ((pack = GlobalParseCache.GetRootPackage (p)) != null) foreach (DModule m in pack) SearchResultsIn(m, s.Pattern, l, resultsCount); } return (ISearchDataSource)new DSearchDataSource(l) { SearchPattern = s.Pattern }; }, token); }
public override Task GetResults(ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { return(Task.Run(delegate { try { if (pattern.HasLineNumber) { return; } CommandTargetRoute route = new CommandTargetRoute(MainToolbar.LastCommandTarget); var matcher = StringMatcher.GetMatcher(pattern.Pattern, false); foreach (var cmdTuple in allCommands) { token.ThrowIfCancellationRequested(); var cmd = cmdTuple.Item1; var matchString = cmdTuple.Item2; int rank; if (matcher.CalcMatchRank(matchString, out rank)) { searchResultCallback.ReportResult(new CommandResult(cmd, null, route, pattern.Pattern, matchString, rank)); } } } catch (OperationCanceledException) { } })); }
public override Task GetResults (ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { if (IsProjectSelected ()) { searchResultCallback.ReportResult (new SearchPackageSearchResult (pattern)); } return SpecializedTasks.EmptyTask; }
public override Task GetResults(ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { if (IdeApp.ProjectOperations.CurrentSelectedSolution != null) { searchResultCallback.ReportResult(new SearchInSolutionSearchResult(pattern)); } return(SpecializedTasks.EmptyTask); }
public override Task<ISearchDataSource> GetResults (SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { return Task.Factory.StartNew (() => { if ((searchPattern.Tag == null) || IsValidTag (searchPattern.Tag)) { return (ISearchDataSource)new InstallPackageDataSource (searchPattern); } return null; }); }
public override Task GetResults(ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { return(Task.Run(async delegate { List <Tuple <string, string, ProjectFile> > files; //This lock is here in case user quickly types 5 letters which triggers 5 threads //we don't want to use all CPU doing same thing, instead 1st one will create cache, others will wait here //and then all will use cached version... bool locked = false; try { locked = await allFilesLock.WaitAsync(System.Threading.Timeout.Infinite, token).ConfigureAwait(false); files = allFilesCache = allFilesCache ?? GenerateAllFiles(); if (token.IsCancellationRequested) { return; } } finally { if (locked) { allFilesLock.Release(); } } var matcher = StringMatcher.GetMatcher(pattern.Pattern, false); var savedMatches = new Dictionary <string, MatchResult> (files.Count * 2); foreach (var file in files) { if (token.IsCancellationRequested) { break; } int rank1; int rank2; var match1 = MatchName(savedMatches, matcher, file.Item1, out rank1); var match2 = MatchName(savedMatches, matcher, file.Item2, out rank2); if (match1 && match2) { if (rank1 > rank2 || (rank1 == rank2 && String.CompareOrdinal(file.Item1, file.Item2) > 0)) { searchResultCallback.ReportResult(new FileSearchResult(pattern.Pattern, file.Item1, rank1, file.Item3)); } else { searchResultCallback.ReportResult(new FileSearchResult(pattern.Pattern, file.Item2, rank2, file.Item3)); } } else if (match1) { searchResultCallback.ReportResult(new FileSearchResult(pattern.Pattern, file.Item1, rank1, file.Item3)); } else if (match2) { searchResultCallback.ReportResult(new FileSearchResult(pattern.Pattern, file.Item2, rank2, file.Item3)); } } }, token)); }
public override Task<ISearchDataSource> GetResults (SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { if (IdeApp.ProjectOperations.CurrentSelectedSolution != null) { return Task.Factory.StartNew (delegate { return (ISearchDataSource)new SearchInSolutionDataSource (searchPattern); }); } return Task.FromResult<ISearchDataSource> (default(ISearchDataSource)); }
public static SearchPopupSearchPattern ParsePattern(string searchPattern) { var result = new SearchPopupSearchPattern(); result.LineNumber = -1; const int maxTag = 3; string[] parts = new string[maxTag]; int foundTags = 0; int idx = 0; for (int i = 0; i < searchPattern.Length; i++) { if (searchPattern[i] == ':') { parts[foundTags++] = searchPattern.Substring(idx, i - idx); idx = i + 1; if (foundTags >= maxTag) { break; } } } if (foundTags < maxTag) { parts[foundTags++] = searchPattern.Substring(idx, searchPattern.Length - idx); } switch (foundTags) { case 1: result.SetPart(1, parts[0]); break; case 2: try { int.Parse(parts[1]); if (!string.IsNullOrEmpty(parts[0])) { result.SetPart(1, parts[0]); } result.SetPart(2, parts[1]); } catch (Exception) { result.SetPart(0, parts[0]); result.SetPart(1, parts[1]); } break; case 3: result.SetPart(0, parts[0]); result.SetPart(1, parts[1]); result.SetPart(2, parts[2]); break; } return(result); }
public override Task <ISearchDataSource> GetResults(SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { if (IdeApp.ProjectOperations.CurrentSelectedSolution != null) { return(Task.Factory.StartNew(delegate { return (ISearchDataSource) new SearchInSolutionDataSource(searchPattern); })); } return(Task.FromResult <ISearchDataSource> (default(ISearchDataSource))); }
public void Update(SearchPopupSearchPattern pattern) { // in case of 'string:' it's not clear if the user ment 'tag:pattern' or 'pattern:line' therefore guess // 'tag:', if no valid tag is found guess 'pattern:' if (!string.IsNullOrEmpty(pattern.Tag) && string.IsNullOrEmpty(pattern.Pattern) && !categories.Any(c => c.IsValidTag(pattern.Tag))) { pattern = new SearchPopupSearchPattern(null, pattern.Tag, pattern.LineNumber, pattern.Column, pattern.UnparsedPattern); } this.pattern = pattern; if (src != null) { src.Cancel(); } HideTooltip(); src = new CancellationTokenSource(); isInSearch = true; if (results.Count == 0) { QueueDraw(); } incompleteResults.Clear(); foreach (var _cat in categories) { var cat = _cat; var token = src.Token; cat.GetResults(pattern, maxItems, token).ContinueWith(t => { if (t.IsCanceled) { return; } if (t.IsFaulted) { LoggingService.LogError("Error getting search results", t.Exception); } else { Application.Invoke(delegate { ShowResult(cat, t.Result ?? new NullDataSource()); }); } }, token); } }
void HandleSearchEntryChanged(object sender, EventArgs e) { if (!string.IsNullOrEmpty(ToolbarView.SearchText)) { lastSearchText = ToolbarView.SearchText; } if (string.IsNullOrEmpty(ToolbarView.SearchText)) { DestroyPopup(); return; } var pattern = SearchPopupSearchPattern.ParsePattern(ToolbarView.SearchText); if (pattern.Pattern == null && pattern.LineNumber > 0 || pattern == emptyColonPattern) { if (popup != null) { popup.Hide(); } return; } else { if (popup != null && !popup.Visible) { popup.Show(); } } if (popup == null) { popup = new SearchPopupWindow(); popup.SearchForMembers = SearchForMembers; popup.Destroyed += delegate { popup = null; ToolbarView.SearchText = ""; }; PositionPopup(); popup.ShowAll(); } popup.Update(pattern); }
void HandleSearchEntryChanged(object sender, EventArgs e) { if (!string.IsNullOrEmpty (ToolbarView.SearchText)) lastSearchText = ToolbarView.SearchText; if (string.IsNullOrEmpty (ToolbarView.SearchText)){ DestroyPopup (); return; } var pattern = SearchPopupSearchPattern.ParsePattern (ToolbarView.SearchText); if (pattern.Pattern == null && pattern.LineNumber > 0 || pattern == emptyColonPattern) { if (popup != null) { popup.Hide (); } return; } else { if (popup != null && !popup.Visible) popup.Show (); } if (popup == null) { popup = new SearchPopupWindow (); popup.SearchForMembers = SearchForMembers; popup.Disposed += delegate { popup = null; ToolbarView.SearchText = ""; }; popup.SelectedItemChanged += delegate { var si = popup?.Content?.SelectedItem; if (si == null || si.Item < 0 || si.Item >= si.DataSource.Count) return; var text = si.DataSource [si.Item].AccessibilityMessage; if (string.IsNullOrEmpty (text)) return; ToolbarView.ShowAccessibilityAnnouncement (text); }; PositionPopup (); popup.Show (); } popup.Update (pattern); }
void HandleSearchEntryActivated(object sender, EventArgs e) { var pattern = SearchPopupSearchPattern.ParsePattern (ToolbarView.SearchText); if (pattern.Pattern == null && pattern.LineNumber > 0) { DestroyPopup (); var doc = IdeApp.Workbench.ActiveDocument; if (doc?.GetContent<ITextView> (true) is ITextView view) { doc.Select (); var snapshot = view.TextBuffer.CurrentSnapshot; var line = snapshot.GetLineFromLineNumber (pattern.LineNumber - 1); if (line != null) { view.Caret.MoveTo (new SnapshotPoint (snapshot, line.Start + Math.Min (pattern.Column - 1, line.Length))); IdeApp.CommandService.DispatchCommand (ViewCommands.CenterAndFocusCurrentDocument); } } return; } if (popup != null) popup.OpenFile (); }
public override Task GetResults (ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { return Task.Run (delegate { var files = AllFiles.ToList (); var matcher = StringMatcher.GetMatcher (pattern.Pattern, false); var savedMatches = new Dictionary<string, MatchResult> (); foreach (ProjectFile file in files) { if (token.IsCancellationRequested) break; int rank; string matchString = System.IO.Path.GetFileName (file.FilePath); if (MatchName (savedMatches, matcher, matchString, out rank)) searchResultCallback.ReportResult (new FileSearchResult (pattern.Pattern, matchString, rank, file, true)); matchString = FileSearchResult.GetRelProjectPath (file); if (MatchName (savedMatches, matcher, matchString, out rank)) searchResultCallback.ReportResult (new FileSearchResult (pattern.Pattern, matchString, rank, file, true)); } }, token); }
public static SearchPopupSearchPattern ParsePattern (string searchPattern) { var result = new SearchPopupSearchPattern (); result.LineNumber = -1; const int maxTag = 3; string[] parts = new string[maxTag]; int foundTags = 0; int idx = 0; for (int i = 0; i < searchPattern.Length; i++) { if (searchPattern[i] == ':') { parts[foundTags++] = searchPattern.Substring (idx, i - idx); idx = i + 1; if (foundTags >= maxTag) break; } } if (foundTags < maxTag) parts[foundTags++] = searchPattern.Substring (idx,searchPattern.Length - idx); switch (foundTags) { case 1: result.SetPart (1, parts[0]); break; case 2: try { int.Parse (parts[1]); if (!string.IsNullOrEmpty (parts[0])) result.SetPart (1, parts[0]); result.SetPart (2, parts[1]); } catch (Exception) { result.SetPart (0, parts[0]); result.SetPart (1, parts[1]); } break; case 3: result.SetPart (0, parts[0]); result.SetPart (1, parts[1]); result.SetPart (2, parts[2]); break; } return result; }
public override Task GetResults (ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { return Task.Run (delegate { try { if (pattern.HasLineNumber) return; CommandTargetRoute route = new CommandTargetRoute (MainToolbar.LastCommandTarget); var matcher = StringMatcher.GetMatcher (pattern.Pattern, false); foreach (var cmdTuple in allCommands) { token.ThrowIfCancellationRequested (); var cmd = cmdTuple.Item1; var matchString = cmdTuple.Item2; int rank; if (matcher.CalcMatchRank (matchString, out rank)) searchResultCallback.ReportResult (new CommandResult (cmd, null, route, pattern.Pattern, matchString, rank)); } } catch (OperationCanceledException) { } }); }
void HandleSearchEntryActivated(object sender, EventArgs e) { var pattern = SearchPopupSearchPattern.ParsePattern(ToolbarView.SearchText); if (pattern.Pattern == null && pattern.LineNumber > 0) { DestroyPopup(); var doc = IdeApp.Workbench.ActiveDocument; if (doc != null && doc.Editor != null) { doc.Select(); doc.Editor.CaretLocation = new MonoDevelop.Ide.Editor.DocumentLocation(pattern.LineNumber, pattern.Column > 0 ? pattern.Column : 1); doc.Editor.CenterToCaret(); doc.Editor.StartCaretPulseAnimation(); } return; } if (popup != null) { popup.OpenFile(); } }
public override Task GetResults(ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { return(Task.Run(delegate { var files = allFilesCache = allFilesCache ?? GenerateAllFiles(); var matcher = StringMatcher.GetMatcher(pattern.Pattern, false); var savedMatches = new Dictionary <string, MatchResult> (); foreach (var file in files) { if (token.IsCancellationRequested) { break; } int rank1; int rank2; var match1 = MatchName(savedMatches, matcher, file.Item1, out rank1); var match2 = MatchName(savedMatches, matcher, file.Item2, out rank2); if (match1 && match2) { if (rank1 > rank2 || (rank1 == rank2 && String.CompareOrdinal(file.Item1, file.Item2) > 0)) { searchResultCallback.ReportResult(new FileSearchResult(pattern.Pattern, file.Item1, rank1, file.Item3)); } else { searchResultCallback.ReportResult(new FileSearchResult(pattern.Pattern, file.Item2, rank2, file.Item3)); } } else if (match1) { searchResultCallback.ReportResult(new FileSearchResult(pattern.Pattern, file.Item1, rank1, file.Item3)); } else if (match2) { searchResultCallback.ReportResult(new FileSearchResult(pattern.Pattern, file.Item2, rank2, file.Item3)); } } }, token)); }
public override Task <ISearchDataSource> GetResults(SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { return(Task.Factory.StartNew(delegate { if (searchPattern.Tag != null && !(typeTags.Contains(searchPattern.Tag) || memberTags.Contains(searchPattern.Tag)) || searchPattern.HasLineNumber) { return null; } try { var newResult = new WorkerResult(widget); newResult.pattern = searchPattern.Pattern; newResult.IncludeFiles = true; newResult.Tag = searchPattern.Tag; newResult.IncludeTypes = searchPattern.Tag == null || typeTags.Contains(searchPattern.Tag); newResult.IncludeMembers = searchPattern.Tag == null || memberTags.Contains(searchPattern.Tag); var firstType = types.FirstOrDefault(); newResult.ambience = firstType != null ? AmbienceService.GetAmbienceForFile(firstType.Region.FileName) : AmbienceService.DefaultAmbience; string toMatch = searchPattern.Pattern; newResult.matcher = StringMatcher.GetMatcher(toMatch, false); newResult.FullSearch = toMatch.IndexOf('.') > 0; var oldLastResult = lastResult; if (newResult.FullSearch && oldLastResult != null && !oldLastResult.FullSearch) { oldLastResult = new WorkerResult(widget); } // var now = DateTime.Now; AllResults(oldLastResult, newResult, token); newResult.results.SortUpToN(new DataItemComparer(token), resultsCount); lastResult = newResult; // Console.WriteLine ((now - DateTime.Now).TotalMilliseconds); return (ISearchDataSource)newResult.results; } catch { token.ThrowIfCancellationRequested(); throw; } }, token)); }
public override Task<ISearchDataSource> GetResults(SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { // NOTE: This is run on the UI thread as checking whether or not a command is enabled is not thread-safe return Task.Factory.StartNew (delegate { try { if (searchPattern.Tag != null && !validTags.Contains (searchPattern.Tag) || searchPattern.HasLineNumber) return null; WorkerResult newResult = new WorkerResult (widget); newResult.pattern = searchPattern.Pattern; newResult.matcher = StringMatcher.GetMatcher (searchPattern.Pattern, false); newResult.FullSearch = true; AllResults (lastResult, newResult, token); newResult.results.SortUpToN (new DataItemComparer (token), resultsCount); lastResult = newResult; return (ISearchDataSource)newResult.results; } catch { token.ThrowIfCancellationRequested (); throw; } }, token, TaskCreationOptions.None, Xwt.Application.UITaskScheduler); }
public override Task GetResults (ISearchResultCallback searchResultCallback, SearchPopupSearchPattern searchPattern, CancellationToken token) { return Task.Run (async delegate { if (searchPattern.Tag != null && !(typeTags.Contains (searchPattern.Tag) || memberTags.Contains (searchPattern.Tag)) || searchPattern.HasLineNumber) return; try { if (SymbolInfoTask == null) SymbolInfoTask = Task.FromResult (default(SymbolCache)).ContinueWith(t => GetSymbolInfos (token)); var cache = await SymbolInfoTask.ConfigureAwait (false); var allTypes = cache.GetAllTypes (searchPattern.Tag, token); if (token.IsCancellationRequested) return; string toMatch = searchPattern.Pattern; var newResult = new WorkerResult (); newResult.pattern = searchPattern.Pattern; newResult.Tag = searchPattern.Tag; newResult.matcher = StringMatcher.GetMatcher (toMatch, false); newResult.FullSearch = toMatch.IndexOf ('.') > 0; var oldLastResult = lastResult; if (newResult.FullSearch && oldLastResult != null && !oldLastResult.FullSearch) oldLastResult = new WorkerResult (); // var now = DateTime.Now; AllResults (searchResultCallback, oldLastResult, newResult, allTypes, token); //newResult.results.SortUpToN (new DataItemComparer (token), resultsCount); lastResult = newResult; // Console.WriteLine ((now - DateTime.Now).TotalMilliseconds); } catch { token.ThrowIfCancellationRequested (); throw; } }, token); }
public override Task GetResults (ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { return Task.Run (delegate { List<Tuple<string, string, ProjectFile>> files; //This lock is here in case user quickly types 5 letters which triggers 5 threads //we don't want to use all CPU doing same thing, instead 1st one will create cache, others will wait here //and then all will use cached version... lock (allFilesLock) { files = allFilesCache = allFilesCache ?? GenerateAllFiles (); } var matcher = StringMatcher.GetMatcher (pattern.Pattern, false); var savedMatches = new Dictionary<string, MatchResult> (files.Count * 2); foreach (var file in files) { if (token.IsCancellationRequested) break; int rank1; int rank2; var match1 = MatchName (savedMatches, matcher, file.Item1, out rank1); var match2 = MatchName (savedMatches, matcher, file.Item2, out rank2); if (match1 && match2) { if (rank1 > rank2 || (rank1 == rank2 && String.CompareOrdinal (file.Item1, file.Item2) > 0)) { searchResultCallback.ReportResult (new FileSearchResult (pattern.Pattern, file.Item1, rank1, file.Item3)); } else { searchResultCallback.ReportResult (new FileSearchResult (pattern.Pattern, file.Item2, rank2, file.Item3)); } } else if (match1) { searchResultCallback.ReportResult (new FileSearchResult (pattern.Pattern, file.Item1, rank1, file.Item3)); } else if (match2) { searchResultCallback.ReportResult (new FileSearchResult (pattern.Pattern, file.Item2, rank2, file.Item3)); } } }, token); }
public abstract Task GetResults(ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token);
public override Task GetResults (ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { return Task.Run (delegate { var files = allFilesCache = allFilesCache ?? GenerateAllFiles (); var matcher = StringMatcher.GetMatcher (pattern.Pattern, false); var savedMatches = new Dictionary<string, MatchResult> (); foreach (var file in files) { if (token.IsCancellationRequested) break; int rank1; int rank2; var match1 = MatchName (savedMatches, matcher, file.Item1, out rank1); var match2 = MatchName (savedMatches, matcher, file.Item2, out rank2); if (match1 && match2) { if (rank1 > rank2 || (rank1 == rank2 && String.CompareOrdinal (file.Item1, file.Item2) > 0)) { searchResultCallback.ReportResult (new FileSearchResult (pattern.Pattern, file.Item1, rank1, file.Item3)); } else { searchResultCallback.ReportResult (new FileSearchResult (pattern.Pattern, file.Item2, rank2, file.Item3)); } } else if (match1) { searchResultCallback.ReportResult (new FileSearchResult (pattern.Pattern, file.Item1, rank1, file.Item3)); } else if (match2) { searchResultCallback.ReportResult (new FileSearchResult (pattern.Pattern, file.Item2, rank2, file.Item3)); } } }, token); }
public SearchInSolutionDataSource (SearchPopupSearchPattern searchPattern) { this.searchPattern = searchPattern; }
public NuGetPackageDataSource (SearchPopupSearchPattern searchPattern) { this.searchPattern = searchPattern; command = new PackageSearchCommand (searchPattern.Pattern); }
public void Update(SearchPopupSearchPattern pattern) { // in case of 'string:' it's not clear if the user ment 'tag:pattern' or 'pattern:line' therefore guess // 'tag:', if no valid tag is found guess 'pattern:' if (!string.IsNullOrEmpty(pattern.Tag) && string.IsNullOrEmpty(pattern.Pattern) && !categories.Any(c => c.IsValidTag(pattern.Tag))) { pattern = new SearchPopupSearchPattern(null, pattern.Tag, pattern.LineNumber, pattern.Column, pattern.UnparsedPattern); } this.pattern = pattern; if (src != null) { src.Cancel(); } HideTooltip(); src = new CancellationTokenSource(); isInSearch = true; if (results.Count == 0) { QueueDraw(); } var collectors = new List <SearchResultCollector> (); var token = src.Token; foreach (var _cat in categories) { var cat = _cat; if (!string.IsNullOrEmpty(pattern.Tag) && !cat.IsValidTag(pattern.Tag)) { continue; } var col = new SearchResultCollector(_cat); collectors.Add(col); col.Task = cat.GetResults(col, pattern, token); } Task.WhenAll(collectors.Select(c => c.Task)).ContinueWith(t => { Application.Invoke(delegate { if (token.IsCancellationRequested) { return; } var newResults = new List <Tuple <SearchCategory, IReadOnlyList <SearchResult> > > (collectors.Count); foreach (var col in collectors) { if (col.Task.IsCanceled) { continue; } else if (col.Task.IsFaulted) { LoggingService.LogError($"Error getting search results for {col.Category}", col.Task.Exception); } else { newResults.Add(Tuple.Create(col.Category, col.Results)); } } ShowResults(newResults); isInSearch = false; AnimatedResize(); }); }, token); }
public override Task GetResults (ISearchResultCallback searchResultCallback, SearchPopupSearchPattern pattern, CancellationToken token) { if (IdeApp.ProjectOperations.CurrentSelectedSolution != null) searchResultCallback.ReportResult (new SearchInSolutionSearchResult (pattern)); return SpecializedTasks.EmptyTask; }
public SearchInSolutionSearchResult (SearchPopupSearchPattern pattern) : base ("", "", 0) { this.pattern = pattern; }
public override Task <ISearchDataSource> GetResults(SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { return(Task.Factory.StartNew(delegate { return (ISearchDataSource) new SearchInSolutionDataSource(searchPattern); })); }
public InstallPackageDataSource (SearchPopupSearchPattern searchPattern) { this.searchPattern = searchPattern; command = new InstallPackageCommand (searchPattern.Pattern); }
public SearchPackagesDataSource (SearchPopupSearchPattern searchPattern) { this.searchPattern = searchPattern; }
public void Update (SearchPopupSearchPattern pattern) { // in case of 'string:' it's not clear if the user ment 'tag:pattern' or 'pattern:line' therefore guess // 'tag:', if no valid tag is found guess 'pattern:' if (!string.IsNullOrEmpty (pattern.Tag) && string.IsNullOrEmpty (pattern.Pattern) && !categories.Any (c => c.IsValidTag (pattern.Tag))) { pattern = new SearchPopupSearchPattern (null, pattern.Tag, pattern.LineNumber, pattern.Column, pattern.UnparsedPattern); } this.pattern = pattern; if (src != null) src.Cancel (); HideTooltip (); src = new CancellationTokenSource (); isInSearch = true; if (results.Count == 0) { QueueDraw (); } var collectors = new List<SearchResultCollector> (); var token = src.Token; foreach (var _cat in categories) { var cat = _cat; if (!string.IsNullOrEmpty (pattern.Tag) && !cat.IsValidTag (pattern.Tag)) continue; var col = new SearchResultCollector (_cat); collectors.Add (col); col.Task = cat.GetResults (col, pattern, token); } Task.WhenAll (collectors.Select (c => c.Task)).ContinueWith (t => { if (token.IsCancellationRequested) return; var newResults = new List<Tuple<SearchCategory, IReadOnlyList<SearchResult>>> (collectors.Count); foreach (var col in collectors) { if (col.Task.IsCanceled) { continue; } else if (col.Task.IsFaulted) { LoggingService.LogError ($"Error getting search results for {col.Category}", col.Task.Exception); } else { newResults.Add (Tuple.Create (col.Category, col.Results)); } } List<Tuple<SearchCategory, IReadOnlyList<SearchResult>>> failedResults = null; ItemIdentifier topResult = null; for (int i = 0; i < newResults.Count; i++) { var tuple = newResults [i]; try { if (tuple.Item2.Count == 0) continue; if (topResult == null || topResult.DataSource [topResult.Item].Weight < tuple.Item2 [0].Weight) topResult = new ItemIdentifier (tuple.Item1, tuple.Item2, 0); } catch (Exception e) { LoggingService.LogError ("Error while showing result " + i, e); if (failedResults == null) failedResults = new List<Tuple<SearchCategory, IReadOnlyList<SearchResult>>> (); failedResults.Add (newResults [i]); continue; } } if (failedResults != null) failedResults.ForEach (failedResult => newResults.Remove (failedResult)); Application.Invoke (delegate { ShowResults (newResults, topResult); isInSearch = false; AnimatedResize (); }); }, token); }
public void Update(SearchPopupSearchPattern pattern) { Content.Update(pattern); }
public abstract Task <ISearchDataSource> GetResults(SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token);
public SearchInSolutionDataSource(SearchPopupSearchPattern searchPattern) { this.searchPattern = searchPattern; }
public MainToolbar() { executionTargetsChanged = DispatchService.GuiDispatch(new EventHandler(HandleExecutionTargetsChanged)); IdeApp.Workspace.ActiveConfigurationChanged += (sender, e) => UpdateCombos(); IdeApp.Workspace.ConfigurationsChanged += (sender, e) => UpdateCombos(); IdeApp.Workspace.SolutionLoaded += (sender, e) => UpdateCombos(); IdeApp.Workspace.SolutionUnloaded += (sender, e) => UpdateCombos(); IdeApp.ProjectOperations.CurrentSelectedSolutionChanged += HandleCurrentSelectedSolutionChanged; WidgetFlags |= Gtk.WidgetFlags.AppPaintable; AddWidget(button); AddSpace(8); configurationCombo = new Gtk.ComboBox(); configurationCombo.Model = configurationStore; var ctx = new Gtk.CellRendererText(); configurationCombo.PackStart(ctx, true); configurationCombo.AddAttribute(ctx, "text", 0); configurationCombosBox = new HBox(false, 8); var configurationComboVBox = new VBox(); configurationComboVBox.PackStart(configurationCombo, true, false, 0); configurationCombosBox.PackStart(configurationComboVBox, false, false, 0); runtimeCombo = new Gtk.ComboBox(); runtimeCombo.Model = runtimeStore; ctx = new Gtk.CellRendererText(); runtimeCombo.PackStart(ctx, true); runtimeCombo.SetCellDataFunc(ctx, RuntimeRenderCell); runtimeCombo.RowSeparatorFunc = RuntimeIsSeparator; var runtimeComboVBox = new VBox(); runtimeComboVBox.PackStart(runtimeCombo, true, false, 0); configurationCombosBox.PackStart(runtimeComboVBox, false, false, 0); AddWidget(configurationCombosBox); buttonBarBox = new Alignment(0.5f, 0.5f, 0, 0); buttonBarBox.LeftPadding = (uint)7; buttonBarBox.Add(buttonBar); buttonBarBox.NoShowAll = true; AddWidget(buttonBarBox); AddSpace(24); statusArea = new StatusArea(); statusArea.ShowMessage(BrandingService.ApplicationName); var statusAreaAlign = new Alignment(0, 0, 1, 1); statusAreaAlign.Add(statusArea); contentBox.PackStart(statusAreaAlign, true, true, 0); AddSpace(24); statusAreaAlign.SizeAllocated += (object o, SizeAllocatedArgs args) => { Gtk.Widget toplevel = this.Toplevel; if (toplevel == null) { return; } var pixel_scale = GtkWorkarounds.GetPixelScale(); int windowWidth = toplevel.Allocation.Width; int center = windowWidth / 2; int left = Math.Max(center - (int)(300 * pixel_scale), args.Allocation.Left); int right = Math.Min(left + (int)(600 * pixel_scale), args.Allocation.Right); uint left_padding = (uint)(left - args.Allocation.Left); uint right_padding = (uint)(args.Allocation.Right - right); if (left_padding != statusAreaAlign.LeftPadding || right_padding != statusAreaAlign.RightPadding) { statusAreaAlign.SetPadding(0, 0, (uint)left_padding, (uint)right_padding); } }; matchEntry = new SearchEntry(); var searchFiles = this.matchEntry.AddMenuItem(GettextCatalog.GetString("Search Files")); searchFiles.Activated += delegate { SetSearchCategory("files"); }; var searchTypes = this.matchEntry.AddMenuItem(GettextCatalog.GetString("Search Types")); searchTypes.Activated += delegate { SetSearchCategory("type"); }; var searchMembers = this.matchEntry.AddMenuItem(GettextCatalog.GetString("Search Members")); searchMembers.Activated += delegate { SetSearchCategory("member"); }; matchEntry.ForceFilterButtonVisible = true; matchEntry.Entry.FocusOutEvent += delegate { matchEntry.Entry.Text = ""; }; var cmd = IdeApp.CommandService.GetCommand(Commands.NavigateTo); cmd.KeyBindingChanged += delegate { UpdateSearchEntryLabel(); }; UpdateSearchEntryLabel(); matchEntry.Ready = true; matchEntry.Visible = true; matchEntry.IsCheckMenu = true; matchEntry.Entry.ModifyBase(StateType.Normal, Style.White); matchEntry.WidthRequest = 240; if (!Platform.IsMac && !Platform.IsWindows) { matchEntry.Entry.ModifyFont(Pango.FontDescription.FromString("Sans 9")); // TODO: VV: "Segoe UI 9" } matchEntry.RoundedShape = true; matchEntry.Entry.Changed += HandleSearchEntryChanged; matchEntry.Activated += (sender, e) => { var pattern = SearchPopupSearchPattern.ParsePattern(matchEntry.Entry.Text); if (pattern.Pattern == null && pattern.LineNumber > 0) { popup.Destroy(); var doc = IdeApp.Workbench.ActiveDocument; if (doc != null && doc.Editor != null) { doc.Select(); doc.Editor.Caret.Location = new Mono.TextEditor.DocumentLocation(pattern.LineNumber, pattern.Column > 0 ? pattern.Column : 1); doc.Editor.CenterToCaret(); doc.Editor.Parent.StartCaretPulseAnimation(); } return; } if (popup != null) { popup.OpenFile(); } }; matchEntry.Entry.KeyPressEvent += (o, args) => { if (args.Event.Key == Gdk.Key.Escape) { var doc = IdeApp.Workbench.ActiveDocument; if (doc != null) { if (popup != null) { popup.Destroy(); } doc.Select(); } return; } if (popup != null) { args.RetVal = popup.ProcessKey(args.Event.Key, args.Event.State); } }; IdeApp.Workbench.RootWindow.WidgetEvent += delegate(object o, WidgetEventArgs args) { if (args.Event is Gdk.EventConfigure) { PositionPopup(); } }; SizeAllocated += delegate { PositionPopup(); }; BuildToolbar(); IdeApp.CommandService.RegisterCommandBar(buttonBar); AddinManager.ExtensionChanged += OnExtensionChanged; contentBox.PackStart(matchEntry, false, false, 0); var align = new Gtk.Alignment(0, 0, 1f, 1f); align.Show(); align.TopPadding = (uint)5; align.LeftPadding = (uint)9; align.RightPadding = (uint)18; align.BottomPadding = (uint)10; align.Add(contentBox); Add(align); SetDefaultSizes(-1, 21); configurationCombo.Changed += HandleConfigurationChanged; runtimeCombo.Changed += HandleRuntimeChanged; UpdateCombos(); button.Clicked += HandleStartButtonClicked; IdeApp.CommandService.RegisterCommandBar(this); IdeApp.CommandService.ActiveWidgetChanged += (sender, e) => { lastCommandTarget = new WeakReference(e.OldActiveWidget); }; this.ShowAll(); this.statusArea.statusIconBox.HideAll(); }
public override Task<ISearchDataSource> GetResults(SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { return Task.Factory.StartNew (delegate { return (ISearchDataSource)new SearchInSolutionDataSource (searchPattern); }); }
public PortableClassLibraryDataSource (SearchPopupSearchPattern searchPattern) { this.searchPattern = searchPattern; }
public override Task<ISearchDataSource> GetResults (SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { return Task.Factory.StartNew (() => (ISearchDataSource)new SearchPackagesDataSource (searchPattern)); }
public void Update(SearchPopupSearchPattern pattern) { // in case of 'string:' it's not clear if the user ment 'tag:pattern' or 'pattern:line' therefore guess // 'tag:', if no valid tag is found guess 'pattern:' if (!string.IsNullOrEmpty(pattern.Tag) && string.IsNullOrEmpty(pattern.Pattern) && !categories.Any(c => c.IsValidTag(pattern.Tag))) { pattern = new SearchPopupSearchPattern(null, pattern.Tag, pattern.LineNumber, pattern.Column, pattern.UnparsedPattern); } this.pattern = pattern; if (src != null) { src.Cancel(); } HideTooltip(); src = new CancellationTokenSource(); isInSearch = true; if (results.Count == 0) { QueueDraw(); } var collectors = new List <SearchResultCollector> (); var token = src.Token; foreach (var _cat in categories) { var cat = _cat; if (!string.IsNullOrEmpty(pattern.Tag) && !cat.IsValidTag(pattern.Tag)) { continue; } var col = new SearchResultCollector(_cat); collectors.Add(col); col.Task = cat.GetResults(col, pattern, token); } Task.WhenAll(collectors.Select(c => c.Task)).ContinueWith(t => { if (token.IsCancellationRequested) { return; } var newResults = new List <Tuple <SearchCategory, IReadOnlyList <SearchResult> > > (collectors.Count); foreach (var col in collectors) { if (col.Task.IsCanceled) { continue; } else if (col.Task.IsFaulted) { LoggingService.LogError($"Error getting search results for {col.Category}", col.Task.Exception); } else { newResults.Add(Tuple.Create(col.Category, col.Results)); } } List <Tuple <SearchCategory, IReadOnlyList <SearchResult> > > failedResults = null; ItemIdentifier topResult = null; for (int i = 0; i < newResults.Count; i++) { var tuple = newResults [i]; try { if (tuple.Item2.Count == 0) { continue; } if (topResult == null || topResult.DataSource [topResult.Item].Weight < tuple.Item2 [0].Weight) { topResult = new ItemIdentifier(tuple.Item1, tuple.Item2, 0); } } catch (Exception e) { LoggingService.LogError("Error while showing result " + i, e); if (failedResults == null) { failedResults = new List <Tuple <SearchCategory, IReadOnlyList <SearchResult> > > (); } failedResults.Add(newResults [i]); continue; } } if (failedResults != null) { failedResults.ForEach(failedResult => newResults.Remove(failedResult)); } Application.Invoke(delegate { ShowResults(newResults, topResult); isInSearch = false; AnimatedResize(); }); }, token); }
public override Task<ISearchDataSource> GetResults (SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token) { return Task.Factory.StartNew (delegate { if (searchPattern.Tag != null && !(typeTags.Contains (searchPattern.Tag) || memberTags.Contains (searchPattern.Tag)) || searchPattern.HasLineNumber) return null; try { var newResult = new WorkerResult (widget); newResult.pattern = searchPattern.Pattern; newResult.IncludeFiles = true; newResult.Tag = searchPattern.Tag; newResult.IncludeTypes = searchPattern.Tag == null || typeTags.Contains (searchPattern.Tag) ; newResult.IncludeMembers = searchPattern.Tag == null || memberTags.Contains (searchPattern.Tag); var firstType = types.FirstOrDefault (); newResult.ambience = firstType != null ? AmbienceService.GetAmbienceForFile (firstType.Region.FileName) : AmbienceService.DefaultAmbience; string toMatch = searchPattern.Pattern; newResult.matcher = StringMatcher.GetMatcher (toMatch, false); newResult.FullSearch = toMatch.IndexOf ('.') > 0; var oldLastResult = lastResult; if (newResult.FullSearch && oldLastResult != null && !oldLastResult.FullSearch) oldLastResult = new WorkerResult (widget); // var now = DateTime.Now; AllResults (oldLastResult, newResult, token); newResult.results.SortUpToN (new DataItemComparer (token), resultsCount); lastResult = newResult; // Console.WriteLine ((now - DateTime.Now).TotalMilliseconds); return (ISearchDataSource)newResult.results; } catch { token.ThrowIfCancellationRequested (); throw; } }, token); }
public void Update (SearchPopupSearchPattern pattern) { // in case of 'string:' it's not clear if the user ment 'tag:pattern' or 'pattern:line' therefore guess // 'tag:', if no valid tag is found guess 'pattern:' if (!string.IsNullOrEmpty (pattern.Tag) && string.IsNullOrEmpty (pattern.Pattern) && !categories.Any (c => c.IsValidTag (pattern.Tag))) { pattern = new SearchPopupSearchPattern (null, pattern.Tag, pattern.LineNumber, pattern.Column, pattern.UnparsedPattern); } this.pattern = pattern; if (src != null) src.Cancel (); HideTooltip (); src = new CancellationTokenSource (); isInSearch = true; if (results.Count == 0) { QueueDraw (); } incompleteResults.Clear (); foreach (var _cat in categories) { var cat = _cat; var token = src.Token; cat.GetResults (pattern, maxItems, token).ContinueWith (t => { if (t.IsCanceled) return; if (t.IsFaulted) { LoggingService.LogError ("Error getting search results", t.Exception); } else { Application.Invoke (delegate { ShowResult (cat, t.Result ?? new NullDataSource ()); }); } }, token); } }
public override Task GetResults(ISearchResultCallback searchResultCallback, SearchPopupSearchPattern searchPattern, CancellationToken token) { if (string.IsNullOrEmpty(searchPattern.Pattern)) { return(Task.CompletedTask); } if (searchPattern.Tag != null && !tags.Contains(searchPattern.Tag) || searchPattern.HasLineNumber) { return(Task.CompletedTask); } return(Task.Run(async delegate { try { var kinds = GetTagKinds(searchPattern.Tag); // Maybe use language services instead of AbstractNavigateToSearchService var aggregatedResults = await Task.WhenAll(TypeSystemService.AllWorkspaces .Select(ws => ws.CurrentSolution) .SelectMany(sol => sol.Projects) .Select(async proj => { using (proj.Solution.Services.CacheService?.EnableCaching(proj.Id)) { var searchService = TryGetNavigateToSearchService(proj); if (searchService == null) { return ImmutableArray <INavigateToSearchResult> .Empty; } return await searchService.SearchProjectAsync(proj, searchPattern.Pattern, kinds ?? searchService.KindsProvided, token).ConfigureAwait(false); } }) ).ConfigureAwait(false); foreach (var results in aggregatedResults) { foreach (var result in results) { int laneLength = result.NameMatchSpans.Length; int index = laneLength > 0 ? result.NameMatchSpans [0].Start : -1; int rank = 0; if (result.MatchKind == NavigateToMatchKind.Exact) { rank = int.MaxValue; } else { int patternLength = searchPattern.Pattern.Length; rank = searchPattern.Pattern.Length - result.Name.Length; rank -= index; rank -= laneLength * 100; // Favor matches with less splits. That is, 'abc def' is better than 'ab c def'. int baseRank = (patternLength - laneLength - 1) * 5000; // First matching letter close to the begining is better // The more matched letters the better rank = baseRank - (index + (laneLength - patternLength)); // rank up matches which start with a filter substring if (index == 0) { rank += result.NameMatchSpans [0].Length * 50; } } if (!result.IsCaseSensitive) { rank /= 2; } searchResultCallback.ReportResult(new DeclaredSymbolInfoResult( searchPattern.Pattern, result.Name, rank, result )); } } } catch { token.ThrowIfCancellationRequested(); throw; } }, token)); }
public SearchPackageSearchResult (SearchPopupSearchPattern pattern) : base ("", "", 0) { this.pattern = pattern; }
public void Update (string searchPattern) { if (src != null) src.Cancel (); HideTooltip (); src = new CancellationTokenSource (); isInSearch = true; if (results.Count == 0) { QueueDraw (); } pattern = SearchPopupSearchPattern.ParsePattern (searchPattern); incompleteResults.Clear (); foreach (var _cat in categories) { var cat = _cat; var token = src.Token; cat.GetResults (pattern, maxItems, token).ContinueWith (t => { if (t.IsFaulted) { LoggingService.LogError ("Error getting search results", t.Exception); } else { Application.Invoke (delegate { ShowResult (cat, t.Result ?? new NullDataSource ()); }); } }, token); } }
public SearchInSolutionSearchResult(SearchPopupSearchPattern pattern) : base("", "", 0) { this.pattern = pattern; }
public void Update (SearchPopupSearchPattern pattern) { // in case of 'string:' it's not clear if the user ment 'tag:pattern' or 'pattern:line' therefore guess // 'tag:', if no valid tag is found guess 'pattern:' if (!string.IsNullOrEmpty (pattern.Tag) && string.IsNullOrEmpty (pattern.Pattern) && !categories.Any (c => c.IsValidTag (pattern.Tag))) { pattern = new SearchPopupSearchPattern (null, pattern.Tag, pattern.LineNumber, pattern.Column, pattern.UnparsedPattern); } this.pattern = pattern; if (src != null) src.Cancel (); HideTooltip (); src = new CancellationTokenSource (); isInSearch = true; if (results.Count == 0) { QueueDraw (); } var collectors = new List<SearchResultCollector> (); var token = src.Token; foreach (var _cat in categories) { var cat = _cat; if (!string.IsNullOrEmpty (pattern.Tag) && !cat.IsValidTag (pattern.Tag)) continue; var col = new SearchResultCollector (_cat); collectors.Add (col); col.Task = cat.GetResults (col, pattern, token); } Task.WhenAll (collectors.Select (c => c.Task)).ContinueWith (t => { Application.Invoke (delegate { if (token.IsCancellationRequested) return; var newResults = new List<Tuple<SearchCategory, IReadOnlyList<SearchResult>>> (collectors.Count); foreach (var col in collectors) { if (col.Task.IsCanceled) { continue; } else if (col.Task.IsFaulted) { LoggingService.LogError ($"Error getting search results for {col.Category}", col.Task.Exception); } else { newResults.Add (Tuple.Create (col.Category, col.Results)); } } ShowResults (newResults); isInSearch = false; AnimatedResize (); }); }, token); }