Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        /// <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);
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        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;
            }
        }
Esempio n. 6
0
        /// <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);
        }