public override bool BuildRegions(OutlineRegionCollection newRegions) { lock (_threadLock) { if (IsDisposed || !EditorTree.IsReady) { return(false); } AstRoot rootNode = null; try { // We are in a background thread so in order to walk the tree // we must obtain the read lock first. rootNode = EditorTree.AcquireReadLock(_treeUserId); if (rootNode != null) { OutliningContext context = new OutliningContext(); context.Regions = newRegions; // Walk the tree and construct new regions rootNode.Accept(this, context); OutlineSections(rootNode, context); } } catch (Exception) { } finally { if (rootNode != null) { EditorTree.ReleaseReadLock(_treeUserId); } else { // Tree was busy. Will try again later. GuardedOperations.DispatchInvoke(() => BackgroundTask.DoTaskOnIdle(), DispatcherPriority.Normal); } } return(true); } }
public bool Visit(IAstNode node, object param) { OutliningContext context = param as OutliningContext; int startLineNumber, endLineNumber; if (OutlineNode(node, out startLineNumber, out endLineNumber)) { if (context.LastRegionStartLineNumber == startLineNumber && context.LastRegionEndLineNumber != endLineNumber) { // Always prefer outer (bigger) region. var lastRegion = context.Regions[context.Regions.Count - 1]; if (lastRegion.Length < node.Length) { context.Regions.RemoveAt(context.Regions.Count - 1); context.Regions.Add(new ROutlineRegion(EditorDocument.TextBuffer, node)); } } else if (context.LastRegionStartLineNumber != startLineNumber) { context.Regions.Add(new ROutlineRegion(EditorDocument.TextBuffer, node)); context.LastRegionStartLineNumber = startLineNumber; context.LastRegionEndLineNumber = endLineNumber; } } return(true); }
/// <summary> /// Outlines comments that define sections such as /// # NAME --- /// </summary> /// <returns>True if names changed and outline regions need to be rebuilt</returns> private void OutlineSections(AstRoot ast, OutliningContext context) { // Collect comments that define sections var snapshot = EditorTree.TextSnapshot; var sections = ast.Comments.Where(c => { var text = snapshot.GetText(new Span(c.Start, c.Length)); // Section looks like # [NAME] -------- return(text.TrimEnd().EndsWithOrdinal("---") && text.IndexOfAny(CharExtensions.LineBreakChars) < 0); }).ToArray(); // Construct collapsible regions var ranges = new List <ITextRange>(); for (int i = 0; i < sections.Length; i++) { var startLine = snapshot.GetLineFromPosition(sections[i].Start); int end = -1; var text = snapshot.GetText(new Span(sections[i].Start, sections[i].Length)); var displayText = text.Substring(0, text.IndexOfOrdinal("---")).Trim(); if (i < sections.Length - 1) { var endLineNumber = snapshot.GetLineNumberFromPosition(sections[i + 1].Start); if (endLineNumber > startLine.LineNumber) { end = snapshot.GetLineFromLineNumber(endLineNumber - 1).End; } } else { end = snapshot.Length; } if (end > startLine.Start) { ranges.Add(sections[i]); // Trim trailing whitespace in user-defined regions var range = TextRange.FromBounds(startLine.Start, end); text = snapshot.GetText(new Span(range.Start, range.Length)); var trimBy = text.Length - text.TrimEnd().Length; range = TextRange.FromBounds(range.Start, range.End - trimBy); context.Regions.Add(new ROutlineRegion(EditorDocument.TextBuffer, range, displayText)); } } // Track changes in section names _forceRegionsChange = _sections != null && _sections.Changed; _sections?.Dispose(); _sections = new RSectionsCollection(EditorTree, ranges); }
public override bool BuildRegions(OutlineRegionCollection newRegions) { lock (_threadLock) { if (IsDisposed || !EditorTree.IsReady) { return(false); } AstRoot rootNode = null; try { rootNode = EditorTree.AcquireReadLock(_treeUserId); if (rootNode != null) { OutliningContext context = new OutliningContext(); context.Regions = newRegions; rootNode.Accept(this, context); } } catch (Exception ex) { Debug.Fail(String.Format(CultureInfo.CurrentCulture, "Exception in outliner: {0}", ex.Message)); } finally { if (rootNode != null) { EditorTree.ReleaseReadLock(_treeUserId); } else { // Tree was busy. Will try again later. GuardedOperations.DispatchInvoke(() => BackgroundTask.DoTaskOnIdle(), DispatcherPriority.Normal); } } return(true); } }
public override bool BuildRegions(OutlineRegionCollection newRegions) { lock (_threadLock) { if (IsDisposed || !EditorTree.IsReady) { return false; } AstRoot rootNode = null; try { // We are in a background thread so in order to walk the tree // we must obtain the read lock first. rootNode = EditorTree.AcquireReadLock(_treeUserId); if (rootNode != null) { OutliningContext context = new OutliningContext(); context.Regions = newRegions; // Walk the tree and construct new regions rootNode.Accept(this, context); OutlineSections(rootNode, context); } } catch (Exception) { } finally { if (rootNode != null) { EditorTree.ReleaseReadLock(_treeUserId); } else { // Tree was busy. Will try again later. GuardedOperations.DispatchInvoke(() => BackgroundTask.DoTaskOnIdle(), DispatcherPriority.Normal); } } return true; } }
/// <summary> /// Outlines comments that define sections such as /// # NAME --- /// </summary> /// <returns>True if names changed and outline regions need to be rebuilt</returns> private void OutlineSections(AstRoot ast, OutliningContext context) { // Collect comments that define sections var snapshot = EditorTree.TextSnapshot; var sections = ast.Comments.Where(c => { var text = snapshot.GetText(new Span(c.Start, c.Length)); // Section looks like # [NAME] -------- return text.TrimEnd().EndsWithOrdinal("---") && text.IndexOfAny(CharExtensions.LineBreakChars) < 0; }).ToArray(); // Construct collapsible regions var ranges = new List<ITextRange>(); for (int i = 0; i < sections.Length; i++) { var startLine = snapshot.GetLineFromPosition(sections[i].Start); int end = -1; var text = snapshot.GetText(new Span(sections[i].Start, sections[i].Length)); var displayText = text.Substring(0, text.IndexOfOrdinal("---")).Trim(); if (i < sections.Length - 1) { var endLineNumber = snapshot.GetLineNumberFromPosition(sections[i + 1].Start); if (endLineNumber > startLine.LineNumber) { end = snapshot.GetLineFromLineNumber(endLineNumber - 1).End; } } else { end = snapshot.Length; } if (end > startLine.Start) { ranges.Add(sections[i]); // Trim trailing whitespace in user-defined regions var range = TextRange.FromBounds(startLine.Start, end); text = snapshot.GetText(new Span(range.Start, range.Length)); var trimBy = text.Length - text.TrimEnd().Length; range = TextRange.FromBounds(range.Start, range.End - trimBy); context.Regions.Add(new ROutlineRegion(EditorDocument.TextBuffer, range, displayText)); } } // Track changes in section names _forceRegionsChange = _sections != null && _sections.Changed; _sections?.Dispose(); _sections = new RSectionsCollection(EditorTree, ranges); }