Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added method to parser for decomposing a buffer into sections, and us…

…e this from the OutliningTagger.
  • Loading branch information...
commit 43dfe34394d00ce8c75adb32279d194b1404994a 1 parent bae470a
Noah Richards authored
Showing with 66 additions and 63 deletions.
  1. +55 −0 MarkdownParser.cs
  2. +11 −63 Outlining/OutliningTagger.cs
View
55 MarkdownParser.cs
@@ -121,6 +121,56 @@ public static bool ParagraphContainsMultilineTokens(string text)
return false;
}
+
+ /// <summary>
+ /// Parse a text snapshot into markdown sections. This is only part of the markdown parser that is really aware of the editor,
+ /// but it keeps us from re-creating all the "GetLineFromLineNumber"-type methods.
+ /// </summary>
+ /// <param name="snapshot"></param>
+ /// <returns></returns>
+ public static IEnumerable<Token> ParseMarkdownSections(ITextSnapshot snapshot)
+ {
+ string text = snapshot.GetText();
+
+ List<Tuple<int, TokenType>> startPoints =
+ new List<Tuple<int, TokenType>>(ParseMarkdownParagraph(text).Where(t => IsHeaderToken(t))
+ .Select(t => Tuple.Create(t.Span.Start, t.TokenType)));
+
+ List<Token> sections = new List<Token>();
+ Stack<Tuple<int, TokenType>> regions = new Stack<Tuple<int, TokenType>>();
+
+ foreach (var start in startPoints)
+ {
+ int previousLineNumber = Math.Max(0, snapshot.GetLineNumberFromPosition(start.Item1) - 1);
+ int end = snapshot.GetLineFromLineNumber(previousLineNumber).End;
+
+ while (regions.Count > 0 && regions.Peek().Item2 >= start.Item2)
+ {
+ var region = regions.Pop();
+ var span = Span.FromBounds(region.Item1, end);
+ sections.Add(new Token(region.Item2, span));
+ }
+
+ regions.Push(start);
+ }
+
+ while (regions.Count > 0)
+ {
+ var region = regions.Pop();
+ var span = Span.FromBounds(region.Item1, snapshot.Length);
+ sections.Add(new Token(region.Item2, span));
+ }
+
+ sections.Sort((left, right) =>
+ {
+ if (left.Span.Start != right.Span.Start)
+ return left.Span.Start.CompareTo(right.Span.Start);
+
+ return right.Span.Length.CompareTo(left.Span.Length);
+ });
+
+ return sections;
+ }
/// <summary>
/// Markdown token types.
@@ -453,6 +503,11 @@ static IEnumerable<Token> ParseItalicsAndBold(ref string text, int offset = 0)
#region Helpers
+ static bool IsHeaderToken(MarkdownParser.Token token)
+ {
+ return token.TokenType >= MarkdownParser.TokenType.H1 && token.TokenType <= MarkdownParser.TokenType.H6;
+ }
+
static string DestroyHtmlTags(string text)
{
int pos = 0;
View
74 Outlining/OutliningTagger.cs
@@ -31,73 +31,27 @@ sealed class OutliningTagger : ITagger<IOutliningRegionTag>, IDisposable
ITextBuffer _buffer;
List<MarkdownSection> _sections;
- DispatcherTimer _timer;
public OutliningTagger(ITextBuffer buffer)
{
_buffer = buffer;
_sections = new List<MarkdownSection>();
- TriggerReparse();
-
- _buffer.Changed += (sender, args) => TriggerReparse();
- }
-
- void TriggerReparse()
- {
- if (_timer == null)
- {
- _timer = new DispatcherTimer(DispatcherPriority.ApplicationIdle)
- {
- Interval = TimeSpan.FromMilliseconds(500)
- };
-
- _timer.Tick += (sender, args) =>
- {
- _timer.Stop();
- ReparseFile();
- };
- }
-
- _timer.Stop();
- _timer.Start();
+ ReparseFile(null, EventArgs.Empty);
+ BufferIdleEventUtil.AddBufferIdleEventListener(buffer, ReparseFile);
}
- void ReparseFile()
+ void ReparseFile(object sender, EventArgs args)
{
ITextSnapshot snapshot = _buffer.CurrentSnapshot;
- string text = snapshot.GetText();
-
- List<Tuple<int, MarkdownParser.TokenType>> startPoints =
- new List<Tuple<int, MarkdownParser.TokenType>>(MarkdownParser.ParseMarkdownParagraph(text)
- .Where(t => IsHeaderToken(t))
- .Select(t => Tuple.Create(t.Span.Start, t.TokenType)));
-
- List<MarkdownSection> newSections = new List<MarkdownSection>();
- Stack<Tuple<int, MarkdownParser.TokenType>> regions = new Stack<Tuple<int,MarkdownParser.TokenType>>();
-
- foreach (var start in startPoints)
- {
- int previousLineNumber = Math.Max(0, snapshot.GetLineNumberFromPosition(start.Item1) - 1);
- int end = snapshot.GetLineFromLineNumber(previousLineNumber).End;
-
- while(regions.Count > 0 && regions.Peek().Item2 >= start.Item2)
- {
- var region = regions.Pop();
- var trackingSpan = snapshot.CreateTrackingSpan(Span.FromBounds(region.Item1, end), SpanTrackingMode.EdgeExclusive);
- newSections.Add(new MarkdownSection() { TokenType = region.Item2, Span = trackingSpan });
- }
-
- regions.Push(start);
- }
-
- while (regions.Count > 0)
- {
- var region = regions.Pop();
- var trackingSpan = snapshot.CreateTrackingSpan(Span.FromBounds(region.Item1, snapshot.Length), SpanTrackingMode.EdgeExclusive);
- newSections.Add(new MarkdownSection() { TokenType = region.Item2, Span = trackingSpan });
- }
+ List<MarkdownSection> newSections = new List<MarkdownSection>(
+ MarkdownParser.ParseMarkdownSections(snapshot)
+ .Select(t => new MarkdownSection()
+ {
+ TokenType = t.TokenType,
+ Span = snapshot.CreateTrackingSpan(t.Span, SpanTrackingMode.EdgeExclusive)
+ }));
// For now, just dirty the entire file
_sections = newSections;
@@ -107,11 +61,6 @@ void ReparseFile()
temp(this, new SnapshotSpanEventArgs(new SnapshotSpan(snapshot, 0, snapshot.Length)));
}
- static bool IsHeaderToken(MarkdownParser.Token token)
- {
- return token.TokenType >= MarkdownParser.TokenType.H1 && token.TokenType <= MarkdownParser.TokenType.H6;
- }
-
public IEnumerable<ITagSpan<IOutliningRegionTag>> GetTags(NormalizedSnapshotSpanCollection spans)
{
if (_sections == null || _sections.Count == 0 || spans.Count == 0)
@@ -143,8 +92,7 @@ public IEnumerable<ITagSpan<IOutliningRegionTag>> GetTags(NormalizedSnapshotSpan
public void Dispose()
{
- if (_timer != null)
- _timer.Stop();
+ BufferIdleEventUtil.RemoveBufferIdleEventListener(_buffer, ReparseFile);
}
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.