void PushScopeStack(IReadOnlyList <string> scopeList) { if (scopeList == null) { return; } foreach (var scope in scopeList) { ScopeStack = ScopeStack.Push(scope); } }
void PushScopeStack(IReadOnlyList <string> scopeList) { if (scopeList == null) { return; } for (int i = 0; i < scopeList.Count; ++i) { var scope = scopeList[i]; ScopeStack = ScopeStack.Push(scope); } }
public async Task <HighlightedLine> GetHighlightedLineAsync(IDocumentLine line, CancellationToken cancellationToken) { List <ColoredSegment> coloredSegments = new List <ColoredSegment> (); int offset = line.Offset; int length = line.Length; var span = new TextSpan(offset, length); var classifications = Classifier.GetClassifiedSpans(await workspace.GetDocument(documentId).GetSemanticModelAsync(), span, workspace, cancellationToken); int lastClassifiedOffsetEnd = offset; ScopeStack scopeStack; foreach (var curSpan in classifications) { if (curSpan.TextSpan.Start > lastClassifiedOffsetEnd) { scopeStack = defaultScopeStack.Push(EditorThemeColors.UserTypes); ColoredSegment whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd - offset, curSpan.TextSpan.Start - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } string styleName = GetStyleNameFromClassificationType(curSpan.ClassificationType); scopeStack = defaultScopeStack.Push(styleName); ColoredSegment curColoredSegment = new ColoredSegment(curSpan.TextSpan.Start - offset, curSpan.TextSpan.Length, scopeStack); coloredSegments.Add(curColoredSegment); lastClassifiedOffsetEnd = curSpan.TextSpan.End; } if (offset + length > lastClassifiedOffsetEnd) { scopeStack = defaultScopeStack.Push(EditorThemeColors.UserTypes); ColoredSegment whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd - offset, offset + length - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } return(new HighlightedLine(line, coloredSegments)); }
public Task <HighlightedLine> GetColoredSegments(ITextSource text, int startOffset, int length, CancellationToken cancellationToken = default) { if (ContextStack.IsEmpty || length > maxLineLength) { return(Task.FromResult(new HighlightedLine(new TextSegment(startOffset, length), new [] { new ColoredSegment(0, length, ScopeStack.Empty) }))); } SyntaxContext currentContext = null; Match match = null; SyntaxMatch curMatch = null; var segments = new List <ColoredSegment> (); int offset = 0; int curSegmentOffset = 0; int endOffset = offset + length; int lastMatch = -1; var highlightedSegment = new TextSegment(startOffset, length); string lineText = text.GetTextAt(startOffset, length); var initialState = state.Clone(); int timeoutOccursAt; unchecked { timeoutOccursAt = Environment.TickCount + (int)matchTimeout.TotalMilliseconds; } restart: if (cancellationToken.IsCancellationRequested) { return(Task.FromResult(new HighlightedLine(new TextSegment(startOffset, length), new [] { new ColoredSegment(0, length, ScopeStack.Empty) }))); } if (offset >= lineText.Length) { goto end; } lastMatch = offset; currentContext = ContextStack.Peek(); match = null; curMatch = null; foreach (var m in currentContext.Matches) { if (m.GotTimeout) { continue; } var r = m.GetRegex(); if (r == null) { continue; } try { Match possibleMatch; if (r.pattern == "(?<=\\})" && offset > 0) // HACK to fix typescript highlighting. { possibleMatch = r.Match(lineText, offset - 1, length, matchTimeout); } else { possibleMatch = r.Match(lineText, offset, length, matchTimeout); } if (possibleMatch.Success) { if (match == null || possibleMatch.Index < match.Index) { match = possibleMatch; curMatch = m; // Console.WriteLine (match.Index + " possible match : " + m + "/" + possibleMatch.Index + "-" + possibleMatch.Length); } else { // Console.WriteLine (match.Index + " skip match : " + m + "/" + possibleMatch.Index + "-" + possibleMatch.Length); } } else { // Console.WriteLine ("fail match : " + m); } } catch (RegexMatchTimeoutException) { LoggingService.LogWarning("Warning: Regex " + m.Match + " timed out on line:" + text.GetTextAt(offset, length)); m.GotTimeout = true; continue; } } if (length <= 0 && curMatch == null) { goto end; } if (Environment.TickCount >= timeoutOccursAt) { if (curMatch != null) { curMatch.GotTimeout = true; } goto end; } if (match != null) { // Console.WriteLine (match.Index + " taken match : " + curMatch + "/" + match.Index + "-" + match.Length); var matchEndOffset = match.Index + match.Length; if (curSegmentOffset < match.Index && match.Length > 0) { segments.Add(new ColoredSegment(curSegmentOffset, match.Index - curSegmentOffset, ScopeStack)); curSegmentOffset = match.Index; } if (curMatch.Pop) { PopMetaContentScopeStack(currentContext, curMatch); } PushScopeStack(curMatch.Scope); if (curMatch.Captures.Groups.Count > 0) { for (int i = 0; i < curMatch.Captures.Groups.Count; ++i) { var capture = curMatch.Captures.Groups[i]; var grp = match.Groups [capture.Item1]; if (grp == null || grp.Length == 0) { continue; } if (curSegmentOffset < grp.Index) { ReplaceSegment(segments, new ColoredSegment(curSegmentOffset, grp.Index - curSegmentOffset, ScopeStack)); } ReplaceSegment(segments, new ColoredSegment(grp.Index, grp.Length, ScopeStack.Push(capture.Item2))); curSegmentOffset = Math.Max(curSegmentOffset, grp.Index + grp.Length); } } if (curMatch.Captures.NamedGroups.Count > 0) { for (int i = 0; i < curMatch.Captures.NamedGroups.Count; ++i) { var capture = curMatch.Captures.NamedGroups[i]; var grp = match.Groups [capture.Item1]; if (grp == null || grp.Length == 0) { continue; } if (curSegmentOffset < grp.Index) { ReplaceSegment(segments, new ColoredSegment(curSegmentOffset, grp.Index - curSegmentOffset, ScopeStack)); } ReplaceSegment(segments, new ColoredSegment(grp.Index, grp.Length, ScopeStack.Push(capture.Item2))); curSegmentOffset = grp.Index + grp.Length; } } if (curMatch.Scope.Count > 0 && curSegmentOffset < matchEndOffset && match.Length > 0) { segments.Add(new ColoredSegment(curSegmentOffset, matchEndOffset - curSegmentOffset, ScopeStack)); curSegmentOffset = matchEndOffset; } if (curMatch.Pop) { if (matchEndOffset - curSegmentOffset > 0) { segments.Add(new ColoredSegment(curSegmentOffset, matchEndOffset - curSegmentOffset, ScopeStack)); } //if (curMatch.Scope != null) // scopeStack = scopeStack.Pop (); PopStack(currentContext, curMatch); curSegmentOffset = matchEndOffset; } else if (curMatch.Set != null) { // if (matchEndOffset - curSegmentOffset > 0) // segments.Add (new ColoredSegment (curSegmentOffset, matchEndOffset - curSegmentOffset, ScopeStack)); //if (curMatch.Scope != null) // scopeStack = scopeStack.Pop (); PopMetaContentScopeStack(currentContext, curMatch); PopStack(currentContext, curMatch); //curSegmentOffset = matchEndOffset; var nextContexts = curMatch.Set.GetContexts(currentContext); PushStack(curMatch, nextContexts); goto skip; } else if (curMatch.Push != null) { var nextContexts = curMatch.Push.GetContexts(currentContext); PushStack(curMatch, nextContexts); } else { if (curMatch.Scope.Count > 0) { for (int i = 0; i < curMatch.Scope.Count; i++) { ScopeStack = ScopeStack.Pop(); } } } if (curSegmentOffset < matchEndOffset && match.Length > 0) { segments.Add(new ColoredSegment(curSegmentOffset, matchEndOffset - curSegmentOffset, ScopeStack)); curSegmentOffset = matchEndOffset; } skip: length -= curSegmentOffset - offset; offset = curSegmentOffset; goto restart; } end: if (endOffset - curSegmentOffset > 0) { segments.Add(new ColoredSegment(curSegmentOffset, endOffset - curSegmentOffset, ScopeStack)); } return(Task.FromResult(new HighlightedLine(highlightedSegment, segments) { IsContinuedBeyondLineEnd = !initialState.Equals(state) })); }
static ScopeStack MakeScope(ScopeStack defaultScope, string scope) { return(defaultScope.Push(scope)); }
ScopeStack MakeScope(string scope) { return(defaultScope.Push(scope)); }
public Task <HighlightedLine> GetColoredSegments(ITextSource text, int startOffset, int length) { if (ContextStack.IsEmpty) { return(Task.FromResult(new HighlightedLine(new TextSegment(startOffset, length), new [] { new ColoredSegment(0, length, ScopeStack.Empty) }))); } SyntaxContext currentContext = null; List <SyntaxContext> lastContexts = new List <SyntaxContext> (); Match match = null; SyntaxMatch curMatch = null; var segments = new List <ColoredSegment> (); int offset = 0; int curSegmentOffset = 0; int endOffset = offset + length; int lastMatch = -1; var highlightedSegment = new TextSegment(startOffset, length); string lineText = text.GetTextAt(startOffset, length); restart: if (lastMatch == offset) { if (lastContexts.Contains(currentContext)) { offset++; length--; } else { lastContexts.Add(currentContext); } } else { lastContexts.Clear(); lastContexts.Add(currentContext); } if (length <= 0) { goto end; } lastMatch = offset; currentContext = ContextStack.Peek(); match = null; curMatch = null; foreach (var m in currentContext.Matches) { if (m.GotTimeout) { continue; } var r = m.GetRegex(); if (r == null) { continue; } try { var possibleMatch = r.Match(lineText, offset, length, matchTimeout); if (possibleMatch.Success) { if (match == null || possibleMatch.Index < match.Index) { match = possibleMatch; curMatch = m; // Console.WriteLine (match.Index + " possible match : " + m + "/" + possibleMatch.Index + "-" + possibleMatch.Length); } else { // Console.WriteLine (match.Index + " skip match : " + m + "/" + possibleMatch.Index + "-" + possibleMatch.Length); } } else { // Console.WriteLine ("fail match : " + m); } } catch (RegexMatchTimeoutException) { LoggingService.LogWarning("Warning: Regex " + m.Match + " timed out on line:" + text.GetTextAt(offset, length)); m.GotTimeout = true; continue; } } if (match != null) { // Console.WriteLine (match.Index + " taken match : " + curMatch + "/" + match.Index + "-" + match.Length); var matchEndOffset = match.Index + match.Length; if (curSegmentOffset < match.Index && match.Length > 0) { segments.Add(new ColoredSegment(curSegmentOffset, match.Index - curSegmentOffset, ScopeStack)); curSegmentOffset = match.Index; } if (curMatch.Pop) { PopMetaContentScopeStack(currentContext, curMatch); } PushScopeStack(curMatch.Scope); if (curMatch.Captures.Groups.Count > 0) { for (int i = 0; i < curMatch.Captures.Groups.Count; ++i) { var capture = curMatch.Captures.Groups[i]; var grp = match.Groups [capture.Item1]; if (grp == null || grp.Length == 0) { continue; } if (curSegmentOffset < grp.Index) { ReplaceSegment(segments, new ColoredSegment(curSegmentOffset, grp.Index - curSegmentOffset, ScopeStack)); } ReplaceSegment(segments, new ColoredSegment(grp.Index, grp.Length, ScopeStack.Push(capture.Item2))); curSegmentOffset = Math.Max(curSegmentOffset, grp.Index + grp.Length); } } if (curMatch.Captures.NamedGroups.Count > 0) { for (int i = 0; i < curMatch.Captures.NamedGroups.Count; ++i) { var capture = curMatch.Captures.NamedGroups[i]; var grp = match.Groups [capture.Item1]; if (grp == null || grp.Length == 0) { continue; } if (curSegmentOffset < grp.Index) { ReplaceSegment(segments, new ColoredSegment(curSegmentOffset, grp.Index - curSegmentOffset, ScopeStack)); } ReplaceSegment(segments, new ColoredSegment(grp.Index, grp.Length, ScopeStack.Push(capture.Item2))); curSegmentOffset = grp.Index + grp.Length; } } if (curMatch.Scope.Count > 0 && curSegmentOffset < matchEndOffset && match.Length > 0) { segments.Add(new ColoredSegment(curSegmentOffset, matchEndOffset - curSegmentOffset, ScopeStack)); curSegmentOffset = matchEndOffset; } if (curMatch.Pop) { if (matchEndOffset - curSegmentOffset > 0) { segments.Add(new ColoredSegment(curSegmentOffset, matchEndOffset - curSegmentOffset, ScopeStack)); } //if (curMatch.Scope != null) // scopeStack = scopeStack.Pop (); PopStack(currentContext, curMatch); curSegmentOffset = matchEndOffset; } else if (curMatch.Set != null) { // if (matchEndOffset - curSegmentOffset > 0) // segments.Add (new ColoredSegment (curSegmentOffset, matchEndOffset - curSegmentOffset, ScopeStack)); //if (curMatch.Scope != null) // scopeStack = scopeStack.Pop (); PopMetaContentScopeStack(currentContext, curMatch); PopStack(currentContext, curMatch); //curSegmentOffset = matchEndOffset; var nextContexts = curMatch.Set.GetContexts(currentContext); PushStack(curMatch, nextContexts); goto skip; } else if (curMatch.Push != null) { var nextContexts = curMatch.Push.GetContexts(currentContext); PushStack(curMatch, nextContexts); } else { if (curMatch.Scope.Count > 0) { for (int i = 0; i < curMatch.Scope.Count; i++) { ScopeStack = ScopeStack.Pop(); } } } if (curSegmentOffset < matchEndOffset && match.Length > 0) { segments.Add(new ColoredSegment(curSegmentOffset, matchEndOffset - curSegmentOffset, ScopeStack)); curSegmentOffset = matchEndOffset; } skip: length -= curSegmentOffset - offset; offset = curSegmentOffset; goto restart; } end: if (endOffset - curSegmentOffset > 0) { segments.Add(new ColoredSegment(curSegmentOffset, endOffset - curSegmentOffset, ScopeStack)); } return(Task.FromResult(new HighlightedLine(highlightedSegment, segments))); }