public void CreateHiddenRegion(string bannerText, TextSpan ts) { IVsHiddenTextSession session = HiddenTextSession; if (session != null) { NewHiddenRegion[] NewHiddenRegionArray = new NewHiddenRegion[1]; NewHiddenRegionArray[0].dwBehavior = (uint)HIDDEN_REGION_BEHAVIOR.hrbClientControlled; //NewHiddenRegionArray[0].dwClient = 0x2cff; NewHiddenRegionArray[0].dwState = (uint)HIDDEN_REGION_STATE.hrsDefault; NewHiddenRegionArray[0].iType = (int)HIDDEN_REGION_TYPE.hrtCollapsible; NewHiddenRegionArray[0].pszBanner = bannerText; NewHiddenRegionArray[0].tsHiddenText = ts; int isOk = session.AddHiddenRegions( (uint)CHANGE_HIDDEN_REGION_FLAGS.chrDefault, 1, NewHiddenRegionArray, null); if (isOk != VSConstants.S_OK) { MessageBox.Show("error"); } } }
// Produces tags on the snapshot that the tag consumer asked for. public IEnumerable <ITagSpan <DocumentationTag> > GetTags(NormalizedSnapshotSpanCollection spans) { var documentation = Services.DocumentationFileSerializer.Deserialize(_codyDocsFilename); List <ITagSpan <DocumentationTag> > res = new List <ITagSpan <DocumentationTag> >(); var currentSnapshot = _buffer.CurrentSnapshot; var hiddenTextManager = ServiceProvider.GlobalProvider.GetService(typeof(SVsTextManager)) as IVsHiddenTextManager; var service = ServiceProvider.GlobalProvider.GetService(typeof(SVsTextManager)); var textManager = service as IVsTextManager2; IVsTextView view; int result = textManager.GetActiveView2(1, null, (uint)_VIEWFRAMETYPE.vftCodeWindow, out view); IVsHiddenTextSession hiddenSession = null; IVsEnumHiddenRegions[] hiddenRegions = null; int hRetVal = hiddenTextManager.GetHiddenTextSession( _buffer, out hiddenSession); if (hRetVal != 0) { hRetVal = hiddenTextManager.CreateHiddenTextSession( 0, _buffer, null, out hiddenSession); } if (hiddenSession != null) { foreach (var fragment in documentation.Fragments) { int startPos = fragment.Selection.StartPosition; int length = fragment.Selection.EndPosition - fragment.Selection.StartPosition; var snapshotSpan = new SnapshotSpan( currentSnapshot, new Span(startPos, length)); view.GetLineAndColumn(fragment.Selection.StartPosition, out int startLine, out int startIdx); view.GetLineAndColumn(fragment.Selection.EndPosition, out int endLine, out int endIdx); var hidRegion = new NewHiddenRegion() { dwBehavior = (uint)HIDDEN_REGION_BEHAVIOR.hrbClientControlled, dwState = (uint)HIDDEN_REGION_STATE.hrsDefault, iType = (int)HIDDEN_REGION_TYPE.hrtConcealed, pszBanner = fragment.Documentation, tsHiddenText = new TextSpan() { iStartLine = startLine, iStartIndex = startIdx, iEndLine = endLine, iEndIndex = endIdx } }; hiddenSession.AddHiddenRegions(0, 1, new[] { hidRegion }, hiddenRegions); res.Add(new TagSpan <DocumentationTag>(snapshotSpan, new DocumentationTag(fragment.Selection.Text, snapshot.CreateTrackingSpan(startPos, length, SpanTrackingMode.EdgeInclusive), _buffer))); } } return(res); }
/// <include file='doc\LanguageService.uex' path='docs/doc[@for="AuthoringSink.AddHiddenRegion"]/*' /> /// <summary> /// AddHiddenRegion calls this for you, you can call it directly or override it /// to modify the default behavior. /// </summary> public virtual void AddHiddenRegion(NewHiddenRegion r) { if (!HiddenRegions) return; // Sort the regions by their start positions so that if they add more than // MaxRegions then they get the outer top level ones first. int i = this.hiddenRegions.Count - 1; while (i >= 0) { NewHiddenRegion s = (NewHiddenRegion)this.hiddenRegions[i]; if (TextSpanHelper.StartsAfterStartOf(r.tsHiddenText, s.tsHiddenText)) break; i--; } this.hiddenRegions.Insert(i + 1, r); }
/// <include file='doc\LanguageService.uex' path='docs/doc[@for="AuthoringSink.AddHiddenRegion"]/*' /> /// <summary> /// This is in support of outlining. /// </summary> public virtual void AddHiddenRegion(TextSpan context) { if (!HiddenRegions) return; NewHiddenRegion r = new NewHiddenRegion(); r.iType = (int)HIDDEN_REGION_TYPE.hrtCollapsible; r.dwBehavior = (int)HIDDEN_REGION_BEHAVIOR.hrbEditorControlled; //hrbClientControlled; r.dwState = (int)HIDDEN_REGION_STATE.hrsExpanded; r.tsHiddenText = context; r.pszBanner = null; r.dwClient = (uint)Source.HiddenRegionCookie; AddHiddenRegion(r); }
//Banner comparison: in the case of editor controlled region, this is a noop //otherwise, compare banners //caveat is that GetBanner rountrips null to "...". private bool HasSameBanner(NewHiddenRegion r,IVsHiddenRegion region) { uint behavior; region.GetBehavior(out behavior); if (behavior == (uint)HIDDEN_REGION_BEHAVIOR.hrbEditorControlled && r.dwBehavior == (uint)HIDDEN_REGION_BEHAVIOR.hrbEditorControlled) { return true; //the banner text is always a fixed string, which is "..." by default } string currBanner; region.GetBanner(out currBanner); //<STRIP>DevDiv185498: Regression from RTM: Collapsed portions of XAML do not stay collapsed</STRIP> return r.pszBanner == currBanner || (r.pszBanner == null && currBanner == "..."); }
/// <include file='doc\Source.uex' path='docs/doc[@for="Source.ProcessHiddenRegions"]/*' /> public virtual void ProcessHiddenRegions(ArrayList hiddenRegions) { if (!this.doOutlining) { return; } // Compare the existing regions with the new regions and // remove any that do not match the new regions. IVsHiddenTextSession session = GetHiddenTextSession(); IVsEnumHiddenRegions ppenum; TextSpan[] aspan = new TextSpan[1]; aspan[0] = GetDocumentSpan(); NativeMethods.ThrowOnFailure(session.EnumHiddenRegions((uint)FIND_HIDDEN_REGION_FLAGS.FHR_BY_CLIENT_DATA, (uint)Source.HiddenRegionCookie, aspan, out ppenum)); uint fetched; IVsHiddenRegion[] aregion = new IVsHiddenRegion[1]; int matched = 0; int removed = 0; int added = 0; // Create a list of IVsHiddenRegion objects, sorted in the same order that the // authoring sink sorts. This is necessary because VS core editor does NOT return // the regions in the same order that we add them. ArrayList regions = new ArrayList(); ArrayList spans = new ArrayList(); while (ppenum.Next(1, aregion, out fetched) == NativeMethods.S_OK && fetched == 1) { NativeMethods.ThrowOnFailure(aregion[0].GetSpan(aspan)); TextSpan s = aspan[0]; int i = spans.Count - 1; while (i >= 0) { TextSpan s2 = (TextSpan)spans[i]; if (TextSpanHelper.StartsAfterStartOf(s, s2)) break; i--; } spans.Insert(i + 1, s); regions.Insert(i + 1, aregion[0]); } // Iterate over session hidden regions // Session hidden regions are the ones the editor currently knows about ArrayList regionsToAdd = new ArrayList(); int iHiddenRegion = 0; int cHiddenRegion = hiddenRegions.Count; for (int i = 0; i < regions.Count; ++i) { IVsHiddenRegion sessionHiddenRegion = (IVsHiddenRegion)regions[i]; TextSpan sessionSpan = (TextSpan)spans[i]; // Iterate over preceeding sink hidden regions // Sink hidden regions are the ones which resulted from a parse NewHiddenRegion hiddenRegion = new NewHiddenRegion(); while (iHiddenRegion < cHiddenRegion) { hiddenRegion = (NewHiddenRegion)hiddenRegions[iHiddenRegion]; if (hiddenRegion.tsHiddenText.iStartLine >= sessionSpan.iStartLine) { break; } // Add to "ToAdd" regions (add boxed copy to avoid duplicate copies in sink and "ToAdd" collections) // DevNote: Collect "ToAdd" regions rather than doing a hiddenRegions.RemoveAt() to avoid quadratic perf regionsToAdd.Add(hiddenRegions[iHiddenRegion]); ++iHiddenRegion; } // Check whether matching sink region if ((iHiddenRegion < cHiddenRegion) && TextSpanHelper.IsSameSpan(hiddenRegion.tsHiddenText, sessionSpan) && HasSameBanner(hiddenRegion, sessionHiddenRegion)) { // Match (and continue) ++matched; ++iHiddenRegion; } else { // Remove from session (and continue) NativeMethods.ThrowOnFailure(sessionHiddenRegion.Invalidate((int)CHANGE_HIDDEN_REGION_FLAGS.chrNonUndoable)); ++removed; } } // Add following sink hidden regions to "ToAdd" regions if (iHiddenRegion < cHiddenRegion) { regionsToAdd.AddRange(hiddenRegions.GetRange(iHiddenRegion, (cHiddenRegion - iHiddenRegion))); } // Populate given hidden region collection with regions to add // DevNote: This side effect existed in an earlier quadratic algorithm based on removing from // the given collection using hiddenRegions.RemoveAt(). Some VSIP may depend on this side effect hiddenRegions.Clear(); hiddenRegions.AddRange(regionsToAdd); int start = Environment.TickCount; int count = hiddenRegions.Count; int iRegion = 0; if (count > 0) { // For very large documents this can take a while, so add them in chunks of // 1000 and stop after 5 seconds. int maxTime = this.LanguageService.Preferences.MaxRegionTime; int chunkSize = 1000; NewHiddenRegion[] chunk = new NewHiddenRegion[chunkSize]; while (iRegion < count && TimeUtilities.TimeSince(start) < maxTime) { int j = 0; NewHiddenRegion r; while (iRegion < count && j < chunkSize) { r = (NewHiddenRegion)hiddenRegions[iRegion]; if (!TextSpanHelper.ValidSpan(this, r.tsHiddenText)) { #if LANGTRACE Debug.Assert(false, "Invalid span " + r.tsHiddenText.iStartLine + "," + r.tsHiddenText.iStartIndex + "," + r.tsHiddenText.iEndLine + "," + r.tsHiddenText.iEndIndex); #endif break; } else { chunk[j] = r; added++; } iRegion++; j++; } int hr = session.AddHiddenRegions((int)CHANGE_HIDDEN_REGION_FLAGS.chrNonUndoable, j, chunk, null); if (NativeMethods.Failed(hr)) { break; // stop adding if we start getting errors. } } } // Check whether all hidden regions processed if (iRegion == count) { // Depersist outlining (only once) if (!haveDepersistedOutlining) { haveDepersistedOutlining = true; IVsTextViewEx view = this.service.GetPrimaryViewForSource(this) as IVsTextViewEx; if (view != null) { view.PersistOutliningState(); } } } #if PERFTRACE int diff = TimeUtilities.TimeSince(start); Trace.WriteLine(String.Format(CultureInfo.InvariantCulture, "Hidden Regions: Matched={0}, Removed={1}, Addded={2}/{3} in {4} ms", matched, removed, added, hiddenRegions.Count, diff)); #endif }
private TextViewSelection GetSelection(IServiceProvider serviceProvider) { var service = serviceProvider.GetService(typeof(SVsTextManager)); var textManager = service as IVsTextManager2; IVsTextView view; int result = textManager.GetActiveView2(1, null, (uint)_VIEWFRAMETYPE.vftCodeWindow, out view); view.GetSelection(out int startLine, out int startColumn, out int endLine, out int endColumn);//end could be before beginning var hiddenTextManager = serviceProvider.GetService(typeof(SVsTextManager)) as IVsHiddenTextManager; IVsHiddenTextSession hiddenSession = null; IVsTextLines lines = null; IVsEnumHiddenRegions[] hiddenRegions = null; view.GetBuffer(out lines); int hRetVal = hiddenTextManager.GetHiddenTextSession( lines, out hiddenSession); if (hRetVal != 0) { hRetVal = hiddenTextManager.CreateHiddenTextSession( 0, lines, null, out hiddenSession); //if (hRetVal != 0) // return null; } if (hiddenSession != null) { var hidRegion = new NewHiddenRegion() { dwBehavior = (uint)HIDDEN_REGION_BEHAVIOR.hrbClientControlled, dwState = (uint)HIDDEN_REGION_STATE.hrsDefault, iType = (int)HIDDEN_REGION_TYPE.hrtConcealed, pszBanner = "Testing!!", tsHiddenText = new TextSpan() { iStartLine = startLine, iStartIndex = startColumn, iEndLine = endLine, iEndIndex = endColumn } }; hiddenSession.AddHiddenRegions(0, 1, new[] { hidRegion }, hiddenRegions); } int ok = view.GetNearestPosition(startLine, startColumn, out int position1, out int piVirtualSpaces); ok = view.GetNearestPosition(endLine, endColumn, out int position2, out piVirtualSpaces); var startPosition = Math.Min(position1, position2); var endPosition = Math.Max(position1, position2); view.GetSelectedText(out string selectedText); TextViewSelection selection = new TextViewSelection(startPosition, endPosition, selectedText); return(selection); }