Exemplo n.º 1
0
            private void Parse(Span span)
            {
                List <Token> Tokens = null;

                Tokens = Lexer.Lex(Snapshot.GetText(span));

                for (int r = Regions.Count - 1; r >= 0; r--)
                {
                    if (span.Contains(new Span(Regions[r].StartIndex, Regions[r].Length)))
                    {
                        Regions.RemoveAt(r);
                    }
                }

                int t = 0;
                Stack <FoldRegion> regions = new Stack <FoldRegion>();

                while (t < Tokens.Count)
                {
                    Token token = Tokens[t];
                    if (token.Type == TokenType.Keyword)
                    {
                        if (token.Content == "begin")
                        {
                            FoldRegion newRegion = new FoldRegion(token.StartIndex);
                            if (t < Tokens.Count - 1)
                            {
                                Token blockType = Tokens[t + 1];
                                newRegion.CollapsedText = "begin " + blockType.Content;
                                if (blockType.Type == TokenType.Keyword && t < Tokens.Count - 2)
                                {
                                    if (blockType.Content == "class")
                                    {
                                        Token className = Tokens[t + 2];
                                        newRegion.CollapsedText += " " + className.Content;
                                    }

                                    /*else if (blockType.Content == "subroutine")
                                     * {
                                     *  Token subName = Tokens[t + 2];
                                     *  newRegion.CollapsedText += " " + subName.Content;
                                     * }*/
                                    else if (blockType.Content == "function" || blockType.Content == "method")
                                    {
                                        Token name = Tokens[t + 2];
                                        newRegion.CollapsedText += " " + name.Content;
                                    }
                                }
                            }
                            newRegion.CollapsedText += "...";
                            regions.Push(newRegion);
                        }
                        else if (token.Content == "end")
                        {
                            if (regions.Count > 0)
                            {
                                FoldRegion region = regions.Pop();
                                region.Length             = token.StartIndex + token.Length - region.StartIndex;
                                region.ClosingTokenLength = token.Content.Length;

                                // Adjust for the given span
                                region.StartIndex += span.Start;
                                Regions.Add(region);
                            }
                        }
                    }
                    t++;
                }

                this.TagsChanged?.Invoke(this, new SnapshotSpanEventArgs(new SnapshotSpan(Snapshot, span)));
            }
Exemplo n.º 2
0
            private void Buffer_Changed(object sender, TextContentChangedEventArgs e)
            {
                if (e.Changes.Count == 0)
                {
                    return;
                }
                //throw new NotImplementedException();
                Snapshot = e.After;

                // Update the already changed regions
                Span invalidateRange = e.Changes[0].NewSpan; // All fold regions contained here will be deleted and reparsed

                foreach (ITextChange change in e.Changes)
                {
                    // expand invalidateRange to include change.NewSpan
                    invalidateRange = invalidateRange.Union(change.NewSpan);

                    // - Fix up starts and lengths of spans before/after/around
                    // - Invalidate spans intersecting
                    for (int r = Regions.Count - 1; r >= 0; r--)
                    {
                        FoldRegion region = Regions[r];
                        if (region.StartIndex < change.OldPosition)
                        {
                            // Starts before the change - check end position
                            if (region.StartIndex + region.Length < change.OldPosition)
                            {
                                // Ends before the change - do nothing
                            }
                            else if (region.StartIndex + region.Length - region.ClosingTokenLength > change.OldEnd)
                            {
                                // Ends after the change - adjust length
                                region.Length += change.Delta;
                            }
                            else
                            {
                                // Ends during the change - delete and invalidate
                                Regions.RemoveAt(r);
                                invalidateRange = invalidateRange.Union(new Span(region.StartIndex, region.Length));
                            }
                        }
                        else if (region.StartIndex >= change.OldEnd)
                        {
                            // Starts after the change - adjust start
                            region.StartIndex += change.Delta;
                        }
                        else
                        {
                            // Starts in the change - delete and invalidate
                            Regions.RemoveAt(r);
                            invalidateRange = invalidateRange.Union(new Span(region.StartIndex, region.Length));
                        }
                    }

                    // Check to see if we just added a tail part to a now-valid folding region, and if we did, seek upwards until we find the corresponding top.
                    for (int line = Snapshot.GetLineNumberFromPosition(change.NewPosition); line <= Snapshot.GetLineNumberFromPosition(change.NewEnd); line++)
                    {
                        string       lineText   = Snapshot.GetLineFromLineNumber(line).GetText();
                        List <Token> lineTokens = Lexer.Lex(lineText);
                        if (lineTokens.Count > 0 && lineTokens[0].Type == TokenType.Keyword && lineTokens[0].Content == "end")
                        {
                            if (lineTokens[0].Content == "end")
                            {
                                // Scan upwards until we find a matching begin, or the beginning of the file.
                                int startLine = line - 1;
                                int endCount  = 1; // increase by one for every end that we pass, and decrease for every begin.
                                while (startLine >= 0 && endCount > 0)
                                {
                                    string       startLineText   = Snapshot.GetLineFromLineNumber(startLine).GetText();
                                    List <Token> startLineTokens = Lexer.Lex(startLineText);
                                    if (startLineTokens.Count > 0 && startLineTokens[0].Type == TokenType.Keyword)
                                    {
                                        if (startLineTokens[0].Content == "end")
                                        {
                                            endCount++;
                                        }
                                        else if (startLineTokens[0].Content == "begin")
                                        {
                                            endCount--;
                                        }
                                    }
                                    startLine--;
                                }
                                startLine++;
                                int start = Snapshot.GetLineFromLineNumber(startLine).Start.Position;
                                int end   = Snapshot.GetLineFromLineNumber(line).End.Position;

                                invalidateRange = invalidateRange.Union(new Span(start, end - start));
                            }
                            else if (lineTokens[0].Content == "begin")
                            {
                                // Scan downwards until we find a matching end, or the end of the file.
                                int endLine    = line + 1;
                                int beginCount = 1;
                                while (endLine < Snapshot.LineCount && beginCount > 0)
                                {
                                    string       endLineText   = Snapshot.GetLineFromLineNumber(endLine).GetText();
                                    List <Token> endLineTokens = Lexer.Lex(endLineText);
                                    if (endLineTokens.Count > 0 && endLineTokens[0].Type == TokenType.Keyword)
                                    {
                                        if (endLineTokens[0].Content == "begin")
                                        {
                                            beginCount++;
                                        }
                                        else if (endLineTokens[0].Content == "end")
                                        {
                                            beginCount--;
                                        }
                                    }
                                    endLine++;
                                }
                                endLine--;
                                int start = Snapshot.GetLineFromLineNumber(line).Start.Position;
                                int end   = Snapshot.GetLineFromLineNumber(endLine).End.Position;

                                invalidateRange = invalidateRange.Union(new Span(start, end - start));
                            }
                        }
                    }
                }

                // Make sure we don't invalidate past the end of the file (can be caused by killing fold regions that were where we would now consider out of bounds)
                if (invalidateRange.End > Snapshot.Length)
                {
                    invalidateRange = new Span(invalidateRange.Start, Snapshot.Length - invalidateRange.Start);
                }

                Parse(invalidateRange);
            }
Exemplo n.º 3
0
        private void ProcessRegion(ref int pos, int prevLevel, Dictionary <Int32, FoldRegion> regions, FoldRegion reg)
        {
            @ref.Send(Sci.SCI_SETFOLDLEVEL, pos, prevLevel | Sci.SC_FOLDLEVELHEADERFLAG | Sci.SC_FOLDLEVELBASE);
            pos++;

            for (; pos < reg.EndLine; pos++)
            {
                FoldRegion child;

                if (regions.TryGetValue(pos, out child))
                {
                    ProcessRegion(ref pos, reg.Level, regions, child);
                }

                @ref.Send(Sci.SCI_SETFOLDLEVEL, pos, reg.Level | Sci.SC_FOLDLEVELBASE);
            }
        }