public ColoredSegment(ISegment segment, ScopeStack scopeStack) : base(segment) { this.scopeStack = scopeStack; }
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); var initialState = state.Clone(); int timeoutOccursAt; unchecked { timeoutOccursAt = Environment.TickCount + (int)matchTimeout.TotalMilliseconds; } 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 (Environment.TickCount >= timeoutOccursAt) { 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) })); }
public RoslynClassificationHighlighting(MonoDevelopWorkspace workspace, DocumentId documentId, string defaultScope) { this.workspace = workspace; this.documentId = documentId; this.defaultScope = new ScopeStack(defaultScope); this.userScope = this.defaultScope.Push(EditorThemeColors.UserTypes); classificationMap = new Dictionary <string, ScopeStack> { [ClassificationTypeNames.Comment] = MakeScope("comment." + defaultScope), [ClassificationTypeNames.ExcludedCode] = MakeScope("comment.excluded." + defaultScope), [ClassificationTypeNames.Identifier] = MakeScope(defaultScope), [ClassificationTypeNames.Keyword] = MakeScope("keyword." + defaultScope), [ClassificationTypeNames.NumericLiteral] = MakeScope("constant.numeric." + defaultScope), [ClassificationTypeNames.Operator] = MakeScope(defaultScope), [ClassificationTypeNames.PreprocessorKeyword] = MakeScope("meta.preprocessor." + defaultScope), [ClassificationTypeNames.StringLiteral] = MakeScope("string." + defaultScope), [ClassificationTypeNames.WhiteSpace] = MakeScope("text." + defaultScope), [ClassificationTypeNames.Text] = MakeScope("text." + defaultScope), [ClassificationTypeNames.PreprocessorText] = MakeScope("meta.preprocessor.region.name." + defaultScope), [ClassificationTypeNames.Punctuation] = MakeScope("punctuation." + defaultScope), [ClassificationTypeNames.VerbatimStringLiteral] = MakeScope("string.verbatim." + defaultScope), [ClassificationTypeNames.ClassName] = MakeScope("entity.name.class." + defaultScope), [ClassificationTypeNames.DelegateName] = MakeScope("entity.name.delegate." + defaultScope), [ClassificationTypeNames.EnumName] = MakeScope("entity.name.enum." + defaultScope), [ClassificationTypeNames.InterfaceName] = MakeScope("entity.name.interface." + defaultScope), [ClassificationTypeNames.ModuleName] = MakeScope("entity.name.module." + defaultScope), [ClassificationTypeNames.StructName] = MakeScope("entity.name.struct." + defaultScope), [ClassificationTypeNames.TypeParameterName] = MakeScope("entity.name.typeparameter." + defaultScope), [ClassificationTypeNames.FieldName] = MakeScope("entity.name.field." + defaultScope), [ClassificationTypeNames.EnumMemberName] = MakeScope("entity.name.enummember." + defaultScope), [ClassificationTypeNames.ConstantName] = MakeScope("entity.name.constant." + defaultScope), [ClassificationTypeNames.LocalName] = MakeScope("entity.name.local." + defaultScope), [ClassificationTypeNames.ParameterName] = MakeScope("entity.name.parameter." + defaultScope), [ClassificationTypeNames.ExtensionMethodName] = MakeScope("entity.name.extensionmethod." + defaultScope), [ClassificationTypeNames.MethodName] = MakeScope("entity.name.function." + defaultScope), [ClassificationTypeNames.PropertyName] = MakeScope("entity.name.property." + defaultScope), [ClassificationTypeNames.EventName] = MakeScope("entity.name.event." + defaultScope), [ClassificationTypeNames.XmlDocCommentAttributeName] = MakeScope("comment.line.documentation." + defaultScope), [ClassificationTypeNames.XmlDocCommentAttributeQuotes] = MakeScope("comment.line.documentation." + defaultScope), [ClassificationTypeNames.XmlDocCommentAttributeValue] = MakeScope("comment.line.documentation." + defaultScope), [ClassificationTypeNames.XmlDocCommentCDataSection] = MakeScope("comment.line.documentation." + defaultScope), [ClassificationTypeNames.XmlDocCommentComment] = MakeScope("comment.line.documentation." + defaultScope), [ClassificationTypeNames.XmlDocCommentDelimiter] = MakeScope("comment.line.documentation." + defaultScope), [ClassificationTypeNames.XmlDocCommentEntityReference] = MakeScope("comment.line.documentation." + defaultScope), [ClassificationTypeNames.XmlDocCommentName] = MakeScope("comment.line.documentation." + defaultScope), [ClassificationTypeNames.XmlDocCommentProcessingInstruction] = MakeScope("comment.line.documentation." + defaultScope), [ClassificationTypeNames.XmlDocCommentText] = MakeScope("comment.line.documentation." + defaultScope), [ClassificationTypeNames.XmlLiteralAttributeName] = MakeScope("entity.other.attribute-name." + defaultScope), [ClassificationTypeNames.XmlLiteralAttributeQuotes] = MakeScope("punctuation.definition.string." + defaultScope), [ClassificationTypeNames.XmlLiteralAttributeValue] = MakeScope("string.quoted." + defaultScope), [ClassificationTypeNames.XmlLiteralCDataSection] = MakeScope("text." + defaultScope), [ClassificationTypeNames.XmlLiteralComment] = MakeScope("comment.block." + defaultScope), [ClassificationTypeNames.XmlLiteralDelimiter] = MakeScope(defaultScope), [ClassificationTypeNames.XmlLiteralEmbeddedExpression] = MakeScope(defaultScope), [ClassificationTypeNames.XmlLiteralEntityReference] = MakeScope(defaultScope), [ClassificationTypeNames.XmlLiteralName] = MakeScope("entity.name.tag.localname." + defaultScope), [ClassificationTypeNames.XmlLiteralProcessingInstruction] = MakeScope(defaultScope), [ClassificationTypeNames.XmlLiteralText] = MakeScope("text." + defaultScope), }; }
public ColoredSegment(int offset, int length, ScopeStack scopeStack) : base(offset, length) { this.scopeStack = scopeStack; }
public abstract Tuple <bool, ScopeStack> MatchesStack(ScopeStack scopeStack, ref string matchExpr);
public override int GetHashCode() { unchecked { return((ScopeStack != null ? ScopeStack.GetHashCode() : 0) ^ Foreground.GetHashCode() ^ Background.GetHashCode() ^ FontWeight.GetHashCode() ^ FontStyle.GetHashCode()); } }
public abstract (bool, ScopeStack) MatchesStack(ScopeStack scopeStack, ref string matchExpr);
public static Dictionary <string, ScopeStack> GetClassificationMap(string scope) { Dictionary <string, ScopeStack> result; if (classificationMapCache.TryGetValue(scope, out result)) { return(result); } var defaultScopeStack = new ScopeStack(scope); result = new Dictionary <string, ScopeStack> { [ClassificationTypeNames.Comment] = MakeScope(defaultScopeStack, "comment." + scope), [ClassificationTypeNames.ExcludedCode] = MakeScope(defaultScopeStack, "comment.excluded." + scope), [ClassificationTypeNames.Identifier] = MakeScope(defaultScopeStack, scope), [ClassificationTypeNames.Keyword] = MakeScope(defaultScopeStack, "keyword." + scope), [ClassificationTypeNames.NumericLiteral] = MakeScope(defaultScopeStack, "constant.numeric." + scope), [ClassificationTypeNames.Operator] = MakeScope(defaultScopeStack, scope), [ClassificationTypeNames.PreprocessorKeyword] = MakeScope(defaultScopeStack, "meta.preprocessor." + scope), [ClassificationTypeNames.StringLiteral] = MakeScope(defaultScopeStack, "string." + scope), [ClassificationTypeNames.WhiteSpace] = MakeScope(defaultScopeStack, "text." + scope), [ClassificationTypeNames.Text] = MakeScope(defaultScopeStack, "text." + scope), [ClassificationTypeNames.PreprocessorText] = MakeScope(defaultScopeStack, "meta.preprocessor.region.name." + scope), [ClassificationTypeNames.Punctuation] = MakeScope(defaultScopeStack, "punctuation." + scope), [ClassificationTypeNames.VerbatimStringLiteral] = MakeScope(defaultScopeStack, "string.verbatim." + scope), [ClassificationTypeNames.ClassName] = MakeScope(defaultScopeStack, "entity.name.class." + scope), [ClassificationTypeNames.DelegateName] = MakeScope(defaultScopeStack, "entity.name.delegate." + scope), [ClassificationTypeNames.EnumName] = MakeScope(defaultScopeStack, "entity.name.enum." + scope), [ClassificationTypeNames.InterfaceName] = MakeScope(defaultScopeStack, "entity.name.interface." + scope), [ClassificationTypeNames.ModuleName] = MakeScope(defaultScopeStack, "entity.name.module." + scope), [ClassificationTypeNames.StructName] = MakeScope(defaultScopeStack, "entity.name.struct." + scope), [ClassificationTypeNames.TypeParameterName] = MakeScope(defaultScopeStack, "entity.name.typeparameter." + scope), [ClassificationTypeNames.FieldName] = MakeScope(defaultScopeStack, "entity.name.field." + scope), [ClassificationTypeNames.EnumMemberName] = MakeScope(defaultScopeStack, "entity.name.enummember." + scope), [ClassificationTypeNames.ConstantName] = MakeScope(defaultScopeStack, "entity.name.constant." + scope), [ClassificationTypeNames.LocalName] = MakeScope(defaultScopeStack, "entity.name.local." + scope), [ClassificationTypeNames.ParameterName] = MakeScope(defaultScopeStack, "entity.name.parameter." + scope), [ClassificationTypeNames.ExtensionMethodName] = MakeScope(defaultScopeStack, "entity.name.extensionmethod." + scope), [ClassificationTypeNames.MethodName] = MakeScope(defaultScopeStack, "entity.name.function." + scope), [ClassificationTypeNames.PropertyName] = MakeScope(defaultScopeStack, "entity.name.property." + scope), [ClassificationTypeNames.EventName] = MakeScope(defaultScopeStack, "entity.name.event." + scope), [ClassificationTypeNames.XmlDocCommentAttributeName] = MakeScope(defaultScopeStack, "comment.line.documentation." + scope), [ClassificationTypeNames.XmlDocCommentAttributeQuotes] = MakeScope(defaultScopeStack, "comment.line.documentation." + scope), [ClassificationTypeNames.XmlDocCommentAttributeValue] = MakeScope(defaultScopeStack, "comment.line.documentation." + scope), [ClassificationTypeNames.XmlDocCommentCDataSection] = MakeScope(defaultScopeStack, "comment.line.documentation." + scope), [ClassificationTypeNames.XmlDocCommentComment] = MakeScope(defaultScopeStack, "comment.line.documentation." + scope), [ClassificationTypeNames.XmlDocCommentDelimiter] = MakeScope(defaultScopeStack, "comment.line.documentation." + scope), [ClassificationTypeNames.XmlDocCommentEntityReference] = MakeScope(defaultScopeStack, "comment.line.documentation." + scope), [ClassificationTypeNames.XmlDocCommentName] = MakeScope(defaultScopeStack, "comment.line.documentation." + scope), [ClassificationTypeNames.XmlDocCommentProcessingInstruction] = MakeScope(defaultScopeStack, "comment.line.documentation." + scope), [ClassificationTypeNames.XmlDocCommentText] = MakeScope(defaultScopeStack, "comment.line.documentation." + scope), [ClassificationTypeNames.XmlLiteralAttributeName] = MakeScope(defaultScopeStack, "entity.other.attribute-name." + scope), [ClassificationTypeNames.XmlLiteralAttributeQuotes] = MakeScope(defaultScopeStack, "punctuation.definition.string." + scope), [ClassificationTypeNames.XmlLiteralAttributeValue] = MakeScope(defaultScopeStack, "string.quoted." + scope), [ClassificationTypeNames.XmlLiteralCDataSection] = MakeScope(defaultScopeStack, "text." + scope), [ClassificationTypeNames.XmlLiteralComment] = MakeScope(defaultScopeStack, "comment.block." + scope), [ClassificationTypeNames.XmlLiteralDelimiter] = MakeScope(defaultScopeStack, scope), [ClassificationTypeNames.XmlLiteralEmbeddedExpression] = MakeScope(defaultScopeStack, scope), [ClassificationTypeNames.XmlLiteralEntityReference] = MakeScope(defaultScopeStack, scope), [ClassificationTypeNames.XmlLiteralName] = MakeScope(defaultScopeStack, "entity.name.tag.localname." + scope), [ClassificationTypeNames.XmlLiteralProcessingInstruction] = MakeScope(defaultScopeStack, scope), [ClassificationTypeNames.XmlLiteralText] = MakeScope(defaultScopeStack, "text." + scope), }; classificationMapCache = classificationMapCache.SetItem(scope, result); return(result); }
static ScopeStack MakeScope(ScopeStack defaultScope, string scope) { return(defaultScope.Push(scope)); }