/// <summary> /// Get a read only collection of all the unique visible documents in the workspace that are /// contained within <paramref name="solution"/>. /// </summary> public static ImmutableArray <Document> GetVisibleDocuments( this IDocumentTrackingService service, Solution solution ) => service .GetVisibleDocuments() .Select(d => solution.GetDocument(d)) .WhereNotNull() .Distinct() .ToImmutableArray();
private async Task SearchProjectsInPriorityOrder(IDocumentTrackingService docTrackingService) { var processedProjects = new HashSet <Project>(); var activeDocOpt = docTrackingService.GetActiveDocument(_solution); var visibleDocs = docTrackingService.GetVisibleDocuments(_solution) .Where(d => d != activeDocOpt) .ToImmutableArray(); // First, if there's an active document, search that project first, prioritizing // that active document and all visible documents from it. if (activeDocOpt != null) { var activeProject = activeDocOpt.Project; processedProjects.Add(activeProject); var visibleDocsFromProject = visibleDocs.Where(d => d.Project == activeProject); var priorityDocs = ImmutableArray.Create(activeDocOpt).AddRange(visibleDocsFromProject); // Search the active project first. That way we can deliver results that are // closer in scope to the user quicker without forcing them to do something like // NavToInCurrentDoc await Task.Run(() => SearchAsync(activeProject, priorityDocs), _cancellationToken).ConfigureAwait(false); } // Now, process all visible docs that were not from the active project. var tasks = new List <Task>(); foreach (var(currentProject, priorityDocs) in visibleDocs.GroupBy(d => d.Project)) { // make sure we only process this project if we didn't already process it above. if (processedProjects.Add(currentProject)) { tasks.Add(Task.Run(() => SearchAsync(currentProject, priorityDocs.ToImmutableArray()), _cancellationToken)); } } await Task.WhenAll(tasks).ConfigureAwait(false); // Now, process the remainder of projects tasks.Clear(); foreach (var currentProject in _solution.Projects) { // make sure we only process this project if we didn't already process it above. if (processedProjects.Add(currentProject)) { tasks.Add(Task.Run(() => SearchAsync(currentProject, ImmutableArray <Document> .Empty), _cancellationToken)); } } await Task.WhenAll(tasks).ConfigureAwait(false); }
public ImmutableArray <DocumentId> GetVisibleDocuments() { return(_inner.GetVisibleDocuments()); }
private bool TryGetNextBestItemToReport_NoLock(out ValueTuple <object, VisualStudioTaskItem[]> bestItemToReport) { bestItemToReport = default(ValueTuple <object, VisualStudioTaskItem[]>); // no item to report if (!this.HasPendingTaskItemsToReport) { return(false); } // order of process is like this // 1. active document var activeDocumentId = _documentTracker.GetActiveDocument(); if (activeDocumentId != null && TryGetNextBestItemToReport_NoLock(_notReportedDocumentItemMap, activeDocumentId, out bestItemToReport)) { return(true); } // 2. visible documents foreach (var visibleDocumentId in _documentTracker.GetVisibleDocuments()) { if (TryGetNextBestItemToReport_NoLock(_notReportedDocumentItemMap, visibleDocumentId, out bestItemToReport)) { return(true); } } // 3. opened documents if (TryGetNextBestItemToReportFromOpenedFiles_NoLock(out bestItemToReport)) { return(true); } if (!this.IsUnderThreshold) { return(false); } // 4. documents in the project where active document is in if (activeDocumentId != null) { if (TryGetNextBestItemToReport_NoLock( _notReportedDocumentItemMap, keys => keys.FirstOrDefault(k => k.ProjectId == activeDocumentId.ProjectId), (s, k) => s.ContainsDocument(k), out bestItemToReport)) { return(true); } } // just take random one from the document map if (_notReportedDocumentItemMap.Count > 0) { if (TryGetNextBestItemToReport_NoLock(_notReportedDocumentItemMap, keys => keys.FirstOrDefault(), (s, k) => s.ContainsDocument(k), out bestItemToReport)) { return(true); } } if (_notReportedProjectItemsMap.Count > 0) { if (TryGetNextBestItemToReport_NoLock(_notReportedProjectItemsMap, keys => keys.FirstOrDefault(), (s, k) => s.ContainsProject(k), out bestItemToReport)) { return(true); } } return(false); }