Exemplo n.º 1
0
        private void BuildFolder()
        {
            if (StackedFolderStartingOffsets.Count == 0)
            {
                return;
            }

            FoldingStarting startOffset = StackedFolderStartingOffsets.Pop();

            if (startOffset.Offset < last_step_tablerow_offset)
            {
                NewFolding folding = new NewFolding(startOffset.Offset, last_step_tablerow_offset);
                if (startOffset.Type == FoldingType.Scenario)
                {
                    folding.DefaultClosed = IsCloseScenarioFolding;
                    folding.IsDefinition  = true;
                }
                else
                {
                    folding.DefaultClosed = IsCloseTablesFolding;
                }

                DocumentLine start_line = Document.GetLineByOffset(startOffset.Offset);
                folding.Name = GherkinFormatUtil.GetText(Document, start_line);
                newFoldings.Add(folding);
            }
        }
Exemplo n.º 2
0
        public override void MarkFoldEnd()
        {
            NewFolding f = openFoldings.Pop();

            f.EndOffset = this.TextLength;
            this.Foldings.Add(f);
        }
Exemplo n.º 3
0
		public static List<NewFolding> CreateFoldListWithOneFold()
		{
			NewFolding fold = CreateNewFold();
			List<NewFolding> folds = CreateFoldList();
			folds.Add(fold);
			return folds;
		}
Exemplo n.º 4
0
        private IEnumerable <NewFolding> CreateNewFoldings(TextDocument document)
        {
            var            newFoldings = new List <NewFolding>();
            Stack <int>    starts      = new Stack <int>();
            Stack <string> names       = new Stack <string>();

            foreach (var line in document.Lines)
            {
                var   text = document.GetText(line.Offset, line.Length).Trim();
                Match m    = Regex.Match(text, "#region(\\s.+)$", RegexOptions.Multiline);
                if (m.Success)
                {
                    starts.Push(line.Offset + m.Index);
                    names.Push(m.Groups[1].Value);
                }
                m = Regex.Match(text, "^\\s*#endregion", RegexOptions.Multiline);
                if (m.Success && starts.Count > 0)
                {
                    int        start = starts.Pop();
                    NewFolding fold  = new NewFolding(start, line.Offset + m.Length);
                    fold.Name          = names.Pop();
                    fold.DefaultClosed = true;
                    newFoldings.Add(fold);
                }
            }


            return(newFoldings);
        }
Exemplo n.º 5
0
        public override IEnumerable <NewFolding> CreateNewFoldings(TextDocument document, out int firstErrorOffset)
        {
            try
            {
                var timer = Stopwatch.StartNew();
                TimeSpan = timer.Elapsed;

                var result = new List <NewFolding>();
                foreach (var o in Outlining)
                {
                    var newFolding = new NewFolding
                    {
                        DefaultClosed = o.IsDefaultCollapsed,
                        StartOffset   = o.Span.StartPos,
                        EndOffset     = o.Span.EndPos
                    };
                    result.Add(newFolding);
                }
                result.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));

                firstErrorOffset = 0;
                return(result);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.GetType().Name + ":" + ex.Message);
                firstErrorOffset = 0;
                return(Enumerable.Empty <NewFolding>());
            }
        }
Exemplo n.º 6
0
        void AddUsings(AstNode parent)
        {
            var firstChild = parent.Children.FirstOrDefault(child => child is UsingDeclaration || child is UsingAliasDeclaration);
            var node       = firstChild;

            while (node != null)
            {
                var next = node.GetNextNode();
                if (next is UsingDeclaration || next is UsingAliasDeclaration)
                {
                    node = next;
                }
                else
                {
                    break;
                }
            }
            if (firstChild != node)
            {
                NewFolding folding = AddFolding(firstChild.StartLocation, node.EndLocation);
                if (folding != null)
                {
                    folding.Name          = "using...";
                    folding.DefaultClosed = true;
                }
            }
        }
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            List <NewFolding> newFoldings = new List <NewFolding>();

            Stack <int> startOffsets      = new Stack <int>();
            int         lastNewLineOffset = 0;
            char        openingBrace      = OpeningBrace;
            char        closingBrace      = ClosingBrace;

            foreach (var startKeyword in foldingKeywords.Keys)
            {
                int lastKeywordPos = 0;
                int pos            = 0;

                while ((pos = document.Text.IndexOf(startKeyword, pos)) > lastKeywordPos)
                {
                    int endOffset = document.Text.IndexOf(foldingKeywords[startKeyword], pos);

                    if (endOffset > pos)
                    {
                        var offset  = document.Text.IndexOf("\r\n", pos);
                        var name    = document.Text.Substring(pos + 8, offset - (pos + 8));
                        var folding = new NewFolding(pos, endOffset + 10);
                        folding.Name = name;

                        // Add the folding
                        newFoldings.Add(folding);
                    }

                    lastKeywordPos = pos;
                }
            }

            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));

            return(newFoldings);
        }
Exemplo n.º 8
0
        List <NewFolding> CreateTestNewFoldingList()
        {
            NewFolding        fold  = CreateTestNewFolding();
            List <NewFolding> folds = new List <NewFolding>();

            folds.Add(fold);
            return(folds);
        }
Exemplo n.º 9
0
        NewFolding ConvertToNewFold(FoldingRegion foldingRegion)
        {
            NewFolding newFold = new NewFolding();

            newFold.Name        = foldingRegion.Name;
            newFold.StartOffset = GetStartOffset(foldingRegion.Region);
            newFold.EndOffset   = GetEndOffset(foldingRegion.Region);

            return(newFold);
        }
Exemplo n.º 10
0
        static int SortRange(NewFolding a, NewFolding b)
        {
            int v = a.StartOffset.CompareTo(b.StartOffset);

            if (v == 0)
            {
                return(a.EndOffset.CompareTo(b.EndOffset));
            }
            return(v);
        }
Exemplo n.º 11
0
        static public List <NewFolding> GetFoldingRanges(TextDocument document, List <NewFolding> list)
        {
            if (!DetectPragmaFolding)
            {
                return(new List <NewFolding>());
            }
            Stack <Match> stack = new Stack <Match>();

            foreach (Match m in PragmaRegion.Matches(document.Text))
            {
                if (m.Groups[1].Value == "#region")
                {
                    TextRange range = TextRange.FromMatch(m);
                    int       len   = m.Groups[1].Index - m.Groups[0].Index;
                    stack.Push(m);
                }
                else
                {
                    TextRange range = TextRange.FromMatch(m);

                    Match     peeek = stack.Peek();
                    TextRange peek  = TextRange.FromMatch(peeek);
                    int       len   = peeek.Groups[1].Index - peeek.Groups[0].Index;
                    Logger.Log(MessageType.White, "GetFoldingRanges", "{0}", peek.Position);
                    peek.ShrinkRight(len);
                    Logger.Log(MessageType.White, "GetFoldingRanges", "{0}", peek.Position);

                    NewFolding nf = new NewFolding((int)peek.Position, (int)range.EndPosition);
                    nf.Name          = "#pragma";
                    nf.DefaultClosed = UsePragmaFolding;
                    if (peeek.Groups[2].Value == string.Empty)
                    {
                        nf.Name = "‘…’";
                    }
                    else
                    {
                        nf.Name = string.Format("#region “{0}”", peeek.Groups[2].Value.Trim());
                    }
                    Logger.LogG("GetFoldingRanges", "folding - {0}, {1}", nf.StartOffset, nf.EndOffset);

                    if (document.GetLineByOffset(nf.StartOffset) == document.GetLineByOffset(nf.EndOffset))
                    {
                        continue;
                    }
                    else
                    {
                        list.Add(nf);
                    }
                    stack.Pop();
                }
            }
            list.Sort(SortRange);
            //			if (list.Count >0) list.Remove(list[list.Count-1]);
            return(list);
        }
Exemplo n.º 12
0
        public IList <NewFolding> ConvertFoldRegionsToNewFolds(IEnumerable <FoldingRegion> folds)
        {
            List <NewFolding> newFolds = new List <NewFolding>();

            foreach (FoldingRegion foldingRegion in folds)
            {
                NewFolding newFold = ConvertToNewFold(foldingRegion);
                newFolds.Add(newFold);
            }
            return(newFolds);
        }
Exemplo n.º 13
0
        public void MarkFoldEnd()
        {
            if (!USE_FOLDING)
            {
                return;
            }
            NewFolding f = openFoldings.Pop();

            f.EndOffset = this.TextLength;
            this.Foldings.Add(f);
        }
Exemplo n.º 14
0
        NewFolding CreateTestNewFolding()
        {
            NewFolding expectedFold = new NewFolding();

            expectedFold.DefaultClosed = false;
            expectedFold.StartOffset   = 5;
            expectedFold.EndOffset     = 10;
            expectedFold.Name          = "test";

            return(expectedFold);
        }
Exemplo n.º 15
0
        NewFolding ConvertToNewFold(FoldingRegion foldingRegion)
        {
            var newFold = new NewFolding
            {
                Name        = foldingRegion.Name,
                StartOffset = GetStartOffset(foldingRegion.Region),
                EndOffset   = GetEndOffset(foldingRegion.Region)
            };


            return(newFold);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable <NewFolding> CreateNewFoldings(TextDocument document, out int firstErrorOffset)
        {
            firstErrorOffset = -1;

            var foldings = new List <NewFolding>();
            var stack    = new Stack <int>();

            foreach (var line in document.Lines)
            {
                var text = document.GetText(line.Offset, line.Length);

                // комментарии пропускаем
                if (commentPattern.IsMatch(text))
                {
                    continue;
                }

                foreach (Match match in startPattern.Matches(text))
                {
                    var element = match.Groups["start"];
                    if (element.Success)
                    {
                        stack.Push(line.EndOffset);
                    }
                }

                foreach (Match match in endPattern.Matches(text))
                {
                    var element = match.Groups["end"];
                    if (element.Success)
                    {
                        if (stack.Count > 0)
                        {
                            var first   = stack.Pop();
                            var folding = new NewFolding(first, line.EndOffset);
                            foldings.Add(folding);
                        }
                        else
                        {
                            firstErrorOffset = line.Offset;
                        }
                    }
                }
            }

            if (stack.Count > 0)
            {
                firstErrorOffset = stack.Pop();
            }

            foldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return(foldings);
        }
Exemplo n.º 17
0
        NewFolding AddFolding(TextLocation start, TextLocation end, bool isDefinition = false)
        {
            if (end.Line <= start.Line || start.IsEmpty || end.IsEmpty)
            {
                return(null);
            }
            NewFolding folding = new NewFolding(GetOffset(start), GetOffset(end));

            folding.IsDefinition = isDefinition;
            foldings.Add(folding);
            return(folding);
        }
Exemplo n.º 18
0
        private List <NewFolding> CreateFoldings(LinkedListNode <ActualDocument.ActualLine> linkedLine, Stack <NewFolding> offsetStack)
        {
            List <NewFolding> foldings = new List <NewFolding>();

            if (linkedLine.Next == null)
            {
                while (offsetStack.Count > 0)
                {
                    NewFolding folding = offsetStack.Pop();
                    folding.EndOffset = linkedLine.Value.DocumentLine.EndOffset;
                    foldings.Add(folding);
                }

                return(foldings);
            }

            int thisLineOffset = linkedLine.Value.FrontOffset;
            int nextLineOffset = linkedLine.Next.Value.FrontOffset;

            //This is the first line of a folding
            if (nextLineOffset > thisLineOffset)
            {
                int        documentOffset = linkedLine.Value.DocumentLine.Offset;
                NewFolding folding        = new NewFolding();
                folding.Name        = linkedLine.Value.Line;
                folding.StartOffset = documentOffset;
                offsetStack.Push(folding);
            }

            //This is the last line of a folding
            while (thisLineOffset > nextLineOffset)
            {
                if (offsetStack.Count > 0)
                {
                    NewFolding folding = offsetStack.Pop();
                    folding.EndOffset = linkedLine.Value.DocumentLine.EndOffset;
                    foldings.Add(folding);
                }

                thisLineOffset -= 2;
            }

            if (linkedLine.Next != null)
            {
                foldings.AddRange(CreateFoldings(linkedLine.Next, offsetStack));
            }


            return(foldings);
        }
Exemplo n.º 19
0
        public void GenerateFolds_MethodCalled_FoldsFromFoldParserUsedToUpdateTextEditor()
        {
            CreateFakeTextEditor();
            CreateFoldGenerator();
            string html = "<p></p>";

            SetTextInTextEditor(html);
            var expectedFolds = new NewFolding[] {
                new NewFolding()
            };

            SetFoldsToReturnFromFoldParserForHtml(expectedFolds, html);

            foldGenerator.GenerateFolds();

            fakeTextEditor.AssertWasCalled(textEditor => textEditor.UpdateFolds(expectedFolds));
        }
Exemplo n.º 20
0
        /// <summary>
        /// Central routine of the folding strategy. Uses the provided syntax tree in <paramref name="parseInfo"/>
        /// to calculate all folding positions.
        /// </summary>
        /// <param name="parseInfo">The syntax tree of a document.</param>
        /// <returns>Enumeration of foldings.</returns>
        public virtual IEnumerable <NewFolding> GetNewFoldings(SyntaxTree parseInfo)
        {
            var newFoldMarkers = new List <NewFolding>();

            if (parseInfo != null)
            {
                var root = parseInfo.GetRoot();
                // 1st) add foldings for all class declarations
                foreach (var classInfo in root.DescendantNodes().OfType <Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax>())
                {
                    newFoldMarkers.Add(new NewFolding(classInfo.Identifier.Span.End, classInfo.Span.End));
                }

                // 2nd) add foldings for #region / #endregion pairs
                var regionStack = new Stack <Microsoft.CodeAnalysis.SyntaxTrivia>();

                foreach (var trivia in root.DescendantTrivia())
                {
                    if (trivia.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.RegionDirectiveTrivia))
                    {
                        regionStack.Push(trivia);
                    }
                    else if (trivia.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.EndRegionDirectiveTrivia) && regionStack.Count > 0)
                    {
                        var regionStartTrivia = regionStack.Pop();

                        var name = regionStartTrivia.ToFullString().Trim();
                        if (regionStartTrivia.HasStructure && regionStartTrivia.GetStructure() is Microsoft.CodeAnalysis.CSharp.Syntax.RegionDirectiveTriviaSyntax node)
                        {
                            name = node.EndOfDirectiveToken.ToFullString().Trim();
                        }

                        var newFolding = new NewFolding(regionStartTrivia.Span.Start, trivia.Span.End)
                        {
                            DefaultClosed = _isFirstUpdate,
                            Name          = name
                        };
                        newFoldMarkers.Add(newFolding);
                    }
                }
            }
            return(newFoldMarkers.OrderBy(f => f.StartOffset));
        }
Exemplo n.º 21
0
        private static int CreateNewFoldings(List <NewFolding> foldings, string s, int start)
        {
            var i = start;

            while (i < s.Length && s[i] != '{')
            {
                if (s[i] == '}')
                {
                    return(-1);
                }
                else
                {
                    i++;
                }
            }

            if (i > -1 && i < s.Length)
            {
                var fold = new NewFolding {
                    StartOffset = i + 1
                };
                foldings.Add(fold);

                var innerEnd = i;
                int innerStart;
                do
                {
                    innerStart = innerEnd + 1;
                    innerEnd   = CreateNewFoldings(foldings, s, innerStart);
                } while (innerEnd > -1);

                fold.EndOffset = s.IndexOf(@"}", innerStart);
                if (fold.EndOffset < 0)
                {
                    foldings.Remove(fold);
                }
                else
                {
                    return(fold.EndOffset);
                }
            }
            return(-1);
        }
Exemplo n.º 22
0
        public void ConvertToStrings_OneFoldInList_ReturnsStringArrayWithOneItem()
        {
            folds = NewFoldingHelper.CreateFoldList();
            NewFolding fold = NewFoldingHelper.CreateNewFold();

            fold.Name          = "test";
            fold.DefaultClosed = true;
            fold.StartOffset   = 3;
            fold.EndOffset     = 5;

            folds.Add(fold);

            string[] actualStrings = NewFoldingHelper.ConvertToStrings(folds);

            string[] expectedStrings = new string[] {
                "Name: 'test' StartOffset: 3 EndOffset: 5 DefaultClosed: True"
            };

            Assert.AreEqual(expectedStrings, actualStrings);
        }
Exemplo n.º 23
0
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            List <NewFolding> newFoldings = new List <NewFolding>();

            Stack <int> startOffsets      = new Stack <int>();
            int         lastNewLineOffset = 0;
            char        openingBrace      = this.OpeningBrace;
            char        closingBrace      = this.ClosingBrace;

            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        var folding = new NewFolding(startOffset, i + 1);

                        if (newFoldings.Count > 0)
                        {
                            folding.DefaultClosed = true;
                        }

                        newFoldings.Add(folding);
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            newFoldings.RemoveAt(0);
            return(newFoldings);
        }
        private NewFolding CreateElementFold(TextDocument document, HtmlNode node)
        {
            NewFolding newFold = new NewFolding();

            if (node.Line != node.LastChild.Line)
            {
                if (this.ShowAttributesWhenFolded && node.HasAttributes)
                {
                    newFold.Name = String.Concat("<", node.Name, " ", GetAttributeFoldText(node), ">");
                }
                else
                {
                    newFold.Name = String.Concat("<", node.Name, ">");
                }

                newFold.StartOffset = document.GetOffset(node.Line, node.LinePosition - 1);
                newFold.EndOffset   = document.GetOffset(node.LastChild.Line, node.LastChild.LinePosition + node.OriginalName.Length + 3);
            }

            return(newFold);
        }
Exemplo n.º 25
0
        /// <summary>
        /// Get foldings.
        /// </summary>
        /// <param name="document">The document to provide foldings for.</param>
        /// <param name="firstErrorOffset">Not used.</param>
        /// <returns>The foldings for this document.</returns>
        public IEnumerable <NewFolding> CreateNewFoldings(TextDocument document, out int firstErrorOffset)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document");
            }

            firstErrorOffset = -1;

            List <NewFolding> result  = new List <NewFolding>();
            MatchCollection   regions = Regex.Matches(document.Text, "^[ \t]*//(end)?region.*", RegexOptions.IgnoreCase | RegexOptions.Multiline);

            Stack <Match> startStack = new Stack <Match>();

            foreach (Match region in regions)
            {
                if (region.Value.Trim().StartsWith("//region", StringComparison.CurrentCultureIgnoreCase))
                {
                    startStack.Push(region);
                }
                else
                {
                    if (startStack.Count > 0)
                    {
                        Match      startRegion = startStack.Pop();
                        NewFolding folding     = new NewFolding(startRegion.Index, region.Index + region.Length);
                        int        index       = startRegion.Value.IndexOf("//region", StringComparison.CurrentCultureIgnoreCase);
                        index += 8;
                        if (index < startRegion.Value.Length)
                        {
                            folding.Name = String.Format("{0}", startRegion.Value.Substring(index).Trim());
                        }

                        result.Add(folding);
                    }
                }
            }

            return(result.OrderBy(f => f.StartOffset));
        }
Exemplo n.º 26
0
        private IEnumerable <NewFolding> CreateNewFoldings()
        {
            List <NewFolding>            newFoldings  = new List <NewFolding>();
            Stack <Tuple <int, string> > startOffsets = new Stack <Tuple <int, string> >();

            foreach (Tuple <string, string> foldingString in FoldingStrings)
            {
                foreach (var line in m_Document.Lines)
                {
                    string text = m_Document.GetText(line.Offset, line.TotalLength).ToUpper();
                    text = text.Replace(Environment.NewLine, "");
                    int openingOffset = text.IndexOf(foldingString.Item1, StringComparison.Ordinal);
                    int closingoffset = text.IndexOf(foldingString.Item2, StringComparison.Ordinal);

                    if (openingOffset > -1 && closingoffset > -1)
                    {
                        // The opening and the closing are in the same line
                        continue;
                    }
                    if (openingOffset > -1)
                    {
                        int    foldingStart = line.Offset + openingOffset;
                        string foldingName  = text.Substring(openingOffset + foldingString.Item1.Length);
                        startOffsets.Push(new Tuple <int, string>(foldingStart, foldingName));
                    }
                    else if (closingoffset > -1 && startOffsets.Count > 0)
                    {
                        Tuple <int, string> tuple = startOffsets.Pop();
                        var folding = new NewFolding(tuple.Item1, line.EndOffset)
                        {
                            Name = tuple.Item2
                        };
                        newFoldings.Add(folding);
                    }
                }
            }

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return(newFoldings);
        }
Exemplo n.º 27
0
        public override void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective)
        {
            switch (preProcessorDirective.Type)
            {
            case PreProcessorDirectiveType.Region:
                NewFolding folding = new NewFolding();
                folding.DefaultClosed = true;
                folding.Name          = preProcessorDirective.Argument;
                folding.StartOffset   = GetOffset(preProcessorDirective.StartLocation);
                regions.Push(folding);
                break;

            case PreProcessorDirectiveType.Endregion:
                if (regions.Count > 0)
                {
                    folding           = regions.Pop();
                    folding.EndOffset = GetOffset(preProcessorDirective.EndLocation);
                    foldings.Add(folding);
                }
                break;
            }
        }
        public void GetFolds(TextDocument document, HtmlNodeCollection nodes)
        {
            foreach (HtmlNode node in nodes)
            {
                switch (node.NodeType)
                {
                case HtmlNodeType.Element:
                    NewFolding newFold = CreateElementFold(document, node);

                    if (newFold != null)
                    {
                        foldMarkers.Add(newFold);
                    }

                    if (node.ChildNodes.Count > 0)
                    {
                        GetFolds(document, node.ChildNodes);
                    }

                    break;
                }
            }
        }
        /// <inheritdoc/>
        protected override IEnumerable <NewFolding> CreateNewFoldings(
            AvalonEditDocument document, out int firstErrorOffset)
        {
            firstErrorOffset = -1;

            List <NewFolding> foldings = new List <NewFolding>();

            Stack <NewFolding> activeFoldings     = new Stack <NewFolding>();
            Stack <int>        activeIndentations = new Stack <int>();

            NewFolding activeFolding               = null;
            int        activeIndentation           = -1;
            int        endOffsetOfLastNonEmptyLine = 0;

            for (int lineNumber = 1; lineNumber <= document.LineCount; lineNumber++)
            {
                var line = document.GetLineByNumber(lineNumber);

                // Determine indentation of line.
                int  offset      = line.Offset;
                int  indentation = 0;
                bool isLineEmpty = true;
                for (int i = 0; i < line.Length; i++)
                {
                    if (char.IsWhiteSpace(document.GetCharAt(offset + i)))
                    {
                        indentation++;
                    }
                    else
                    {
                        // Found the first non-white space character.
                        isLineEmpty = false;
                        break;
                    }
                }

                // Skip empty lines.
                if (isLineEmpty)
                {
                    continue;
                }

                // If the indentation is less than the previous, then we close the last active
                // folding.
                if (indentation < activeIndentation)
                {
                    // ReSharper disable once PossibleNullReferenceException
                    activeFolding.EndOffset = endOffsetOfLastNonEmptyLine;

                    // Keep foldings which span more than one line.
                    if (document.GetLineByOffset(activeFolding.StartOffset) != document.GetLineByOffset(activeFolding.EndOffset))
                    {
                        foldings.Add(activeFolding);
                    }

                    if (activeFoldings.Count > 0)
                    {
                        activeFolding     = activeFoldings.Pop();
                        activeIndentation = activeIndentations.Pop();
                    }
                    else
                    {
                        activeFolding     = null;
                        activeIndentation = -1;
                    }

                    // Test same line again. The previous folding could also end on this line.
                    lineNumber--;
                    continue;
                }

                endOffsetOfLastNonEmptyLine = line.EndOffset;

                // If the indentation is larger than the previous indentation, we start a new
                // folding.
                if (indentation > 0 && indentation > activeIndentation)
                {
                    // Store current folding on stack.
                    if (activeFolding != null)
                    {
                        activeFoldings.Push(activeFolding);
                        activeIndentations.Push(activeIndentation);
                    }

                    activeFolding = new NewFolding {
                        StartOffset = offset + indentation,
                    };
                    activeIndentation = indentation;
                }
            }

            // Close all open foldings.
            while (activeFoldings.Count > 0)
            {
                var folding = activeFoldings.Pop();
                folding.EndOffset = endOffsetOfLastNonEmptyLine;
                foldings.Add(folding);
            }

            foldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return(foldings);
        }
Exemplo n.º 30
0
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            List <NewFolding> newFoldings = new List <NewFolding>();

            Stack <int> startOffsets      = new Stack <int>();
            int         lastNewLineOffset = 0;
            char        openingBrace      = this.OpeningBrace;
            char        closingBrace      = this.ClosingBrace;

            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }

                int    slen = document.Text.Length < openingBraceStr.Length + i ? 1 : openingBraceStr.Length;
                string st   = document.GetText(i, slen).ToLower();
                int    elen = document.Text.Length < closingBraceStr.Length + i ? 1 : closingBraceStr.Length;
                string et   = document.GetText(i, elen).ToLower();
                if (st == openingBraceStr)
                {
                    startOffsets.Push(i);
                }
                else if (et == closingBraceStr && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        var textDocument = (TextDocument)document;
                        int regionOffset = startOffset + slen;
                        var line         = textDocument.GetLineByOffset(regionOffset);
                        if (regionOffset < line.EndOffset)
                        {
                            int    regionToLineEndOffset = line.EndOffset - regionOffset;
                            string foldingName           = document.GetText(startOffset + slen, regionToLineEndOffset);
                            var    folding = new NewFolding(startOffset, i + elen);
                            folding.Name = foldingName;
                            newFoldings.Add(folding);
                        }
                    }
                }

                var    doc     = (TextDocument)document;
                var    sline   = doc.GetLineByOffset(i);
                string lineStr = doc.GetText(sline.Offset, sline.Length);
                if (lineStr.StartsWith("using") || lineStr.StartsWith("#r"))
                {
                    if (firstUsing == -1)
                    {
                        firstUsing     = sline.LineNumber;
                        firstUsingline = sline;
                    }
                    else if (lastUsing != firstUsing)
                    {
                        lastNewLineOffset = sline.LineNumber;
                        lastUsingline     = sline;
                    }
                }
                else
                {
                    if (firstUsing != -1 && firstUsingline.Offset < lastUsingline.EndOffset)
                    {
                        var folding = new NewFolding(firstUsingline.Offset, lastUsingline.EndOffset);
                        folding.Name = "using";
                        newFoldings.Add(folding);
                    }
                }



                if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }


            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return(newFoldings);
        }