public FixedHighlighter(IDocument document, HighlightedLine[] lines) { if (lines.Length != document.LineCount) throw new ArgumentException("Wrong number of highlighted lines"); this.document = document; this.lines = lines; }
/// <summary> /// Creates a HTML fragment from a part of a document. /// </summary> /// <param name="document">The document to create HTML from.</param> /// <param name="highlighter">The highlighter used to highlight the document. <c>null</c> is valid and will create HTML without any highlighting.</param> /// <param name="segment">The part of the document to create HTML for. You can pass <c>null</c> to create HTML for the whole document.</param> /// <param name="options">The options for the HTML creation.</param> /// <returns>HTML code for the document part.</returns> public static string CreateHtmlFragment(TextDocument document, IHighlighter highlighter, ISegment segment, HtmlOptions options) { if (document == null) throw new ArgumentNullException("document"); if (options == null) throw new ArgumentNullException("options"); if (highlighter != null && highlighter.Document != document) throw new ArgumentException("Highlighter does not belong to the specified document."); if (segment == null) segment = new SimpleSegment(0, document.TextLength); StringBuilder html = new StringBuilder(); int segmentEndOffset = segment.EndOffset; DocumentLine line = document.GetLineByOffset(segment.Offset); while (line != null && line.Offset < segmentEndOffset) { HighlightedLine highlightedLine; if (highlighter != null) highlightedLine = highlighter.HighlightLine(line.LineNumber); else highlightedLine = new HighlightedLine(document, line); SimpleSegment s = segment.GetOverlap(line); if (html.Length > 0) html.AppendLine("<br>"); html.Append(highlightedLine.ToHtml(s.Offset, s.EndOffset, options)); line = line.NextLine; } return html.ToString(); }
/// <summary> /// Creates a new <see cref="FixedHighlighter"/> for a copy of a portion /// of the input document (including the original highlighting). /// </summary> public static FixedHighlighter CreateView(IHighlighter highlighter, int offset, int endOffset) { var oldDocument = highlighter.Document; // ReadOnlyDocument would be better; but displaying the view in AvalonEdit // requires a TextDocument var newDocument = new TextDocument(oldDocument.CreateSnapshot(offset, endOffset - offset)); var oldStartLine = oldDocument.GetLineByOffset(offset); var oldEndLine = oldDocument.GetLineByOffset(endOffset); int oldStartLineNumber = oldStartLine.LineNumber; HighlightedLine[] newLines = new HighlightedLine[oldEndLine.LineNumber - oldStartLineNumber + 1]; highlighter.BeginHighlighting(); try { for (int i = 0; i < newLines.Length; i++) { HighlightedLine oldHighlightedLine = highlighter.HighlightLine(oldStartLineNumber + i); IDocumentLine newLine = newDocument.GetLineByNumber(1 + i); HighlightedLine newHighlightedLine = new HighlightedLine(newDocument, newLine); MoveSections(oldHighlightedLine.Sections, -offset, newLine.Offset, newLine.EndOffset, newHighlightedLine.Sections); newHighlightedLine.ValidateInvariants(); newLines[i] = newHighlightedLine; } } finally { highlighter.EndHighlighting(); } return new FixedHighlighter(newDocument, newLines); }
bool UpdateLineHighlight(int lineNumber, HighlightedLine oldLine, HighlightedLine newLine) { if (oldLine != null && ShouldUpdateSpan(oldLine, newLine)) { textEditor.TextViewMargin.PurgeLayoutCacheAfter(lineNumber); textEditor.QueueDraw(); HasUpdatedMultilineSpan = true; return(false); } return(true); }
void PrintWords(TextWriter writer, HighlightedLine line, string text) { if (line != null) { writer.Write(line.ToHtml(new MyHtmlOptions(this))); } else { writer.Write(text); } }
private HighlightedLine DoHighlightLine(IDocumentLine documentLine) { var line = new HighlightedLine(_document, documentLine); // since we don't want to block the UI thread // we'll enqueue the request and process it asynchornously EnqueueLine(line); CacheLine(line); return(line); }
public async Task <HighlightedLine> HighlightLineAsync(int lineNumber) { var documentLine = _avalonEditTextDocument.GetLineByNumber(lineNumber); var currentDocumentVersion = _avalonEditTextDocument.Version; // line properties to evaluate in Gui context var documentTextLength = _avalonEditTextDocument.TextLength; var offset = documentLine.Offset; var totalLength = documentLine.TotalLength; var endOffset = documentLine.EndOffset; if (_cachedLines.TryGetValue(lineNumber, out var cachedLine) && cachedLine.OldVersion == currentDocumentVersion) { //System.Diagnostics.Debug.WriteLine("SemanticHightlighter2 Line[{0}] from cache.", lineNumber); return(cachedLine.HighlightedLine); // old info is still valid, thus we return it } else { //System.Diagnostics.Debug.WriteLine("SemanticHightlighter2 Line[{0}] from fresh.", lineNumber); } // get classified spans var document = _workspace.CurrentSolution.GetDocument(_documentId); if (documentTextLength >= offset + totalLength) { var classifiedSpans = await Classifier.GetClassifiedSpansAsync( document, new TextSpan(offset, totalLength), default(CancellationToken)).ConfigureAwait(true); // back to Gui context var highlightedLine = new HighlightedLine(_avalonEditTextDocument, documentLine); foreach (var classifiedSpan in classifiedSpans) { if (IsSpanIntersectingDocumentLine(classifiedSpan, offset, endOffset, out var startOfIntersection, out var lengthOfIntersection)) { highlightedLine.Sections.Add(new HighlightedSection { Color = _highlightingColors.GetColor(classifiedSpan.ClassificationType), Offset = startOfIntersection, Length = lengthOfIntersection }); } } _cachedLines[lineNumber] = new CachedLine(highlightedLine, currentDocumentVersion); return(highlightedLine); } else { return(null); } }
static bool ShouldUpdateSpan(HighlightedLine line1, HighlightedLine line2) { if (line1.IsContinuedBeyondLineEnd != line2.IsContinuedBeyondLineEnd) { return(true); } if (line1.IsContinuedBeyondLineEnd == true) { return(line1.Segments.Last().ScopeStack.Peek() != line2.Segments.Last().ScopeStack.Peek()); } return(false); }
public HighlightedLine HighlightLine(int lineNumber) { var documentLine = _document.GetLineByNumber(lineNumber); var newVersion = _document.Version; CachedLine cachedLine = null; if (_cachedLines != null) { for (var i = 0; i < _cachedLines.Count; i++) { var line = _cachedLines[i]; if (line.DocumentLine != documentLine) { continue; } if (newVersion == null || !newVersion.BelongsToSameDocumentAs(line.OldVersion)) { // cannot list changes from old to new: we can't update the cache, so we'll remove it _cachedLines.RemoveAt(i); } else { cachedLine = line; } } if (cachedLine != null && cachedLine.IsValid && newVersion.CompareAge(cachedLine.OldVersion) == 0) { // the file hasn't changed since the cache was created, so just reuse the old highlighted line return(cachedLine.HighlightedLine); } } var wasInHighlightingGroup = _inHighlightingGroup; if (!_inHighlightingGroup) { BeginHighlighting(); } try { return(DoHighlightLine(documentLine)); } finally { _line = null; if (!wasInHighlightingGroup) { EndHighlighting(); } } }
private void CacheLine(HighlightedLine line) { if (_cachedLines != null && _document.Version != null) { _cachedLines.Add(new CachedLine(line, _document.Version)); // Clean cache once it gets too big if (_cachedLines.Count > CacheSize) { _cachedLines.RemoveRange(0, CacheSize / 2); } } }
/// <summary> /// Highlights the specified line in the specified document. /// /// Before calling this method, <see cref="CurrentSpanStack"/> must be set to the proper /// state for the beginning of this line. After highlighting has completed, /// <see cref="CurrentSpanStack"/> will be updated to represent the state after the line. /// </summary> public HighlightedLine HighlightLine(IDocument document, IDocumentLine line) { this.lineStartOffset = line.Offset; this.lineText = document.GetText(line); try { this.highlightedLine = new HighlightedLine(document, line); HighlightLineInternal(); return this.highlightedLine; } finally { this.highlightedLine = null; this.lineText = null; this.lineStartOffset = 0; } }
private void UpdateHighlightingSections(HighlightedLine line, List <HighlightedSection> sections) { var lineNumber = line.DocumentLine.LineNumber; _syncContext.Post(o => { line.Sections.Clear(); foreach (var section in sections) { line.Sections.Add(section); } HighlightingStateChanged?.Invoke(lineNumber, lineNumber); }, null); }
public CachedLine(HighlightedLine highlightedLine, ITextSourceVersion fileVersion) { if (highlightedLine == null) { throw new ArgumentNullException("highlightedLine"); } if (fileVersion == null) { throw new ArgumentNullException("fileVersion"); } this.HighlightedLine = highlightedLine; this.OldVersion = fileVersion; this.IsValid = true; }
public CachedLine(HighlightedLine highlightedLine, ITextSourceVersion fileVersion) { if (highlightedLine == null) { throw new ArgumentNullException(nameof(highlightedLine)); } if (fileVersion == null) { throw new ArgumentNullException(nameof(fileVersion)); } HighlightedLine = highlightedLine; OldVersion = fileVersion; IsValid = true; }
public async Task <HighlightedLine> GetHighlightedLineAsync(IDocumentLine line, CancellationToken cancellationToken) { //TODO verify that the snapshot line from this.textBuffer is equivalent to the document line converted to a snapshotline. //Possibly take in a TextDataModel as a parameter and verify the buffers are appropriate. //ITextSnapshotLine snapshotLine = (line as Mono.TextEditor.TextDocument.DocumentLineFromTextSnapshotLine)?.Line; ITextSnapshotLine snapshotLine = textBuffer.CurrentSnapshot.GetLineFromLineNumber(line.LineNumber - 1); if ((this.classifier == null) || (snapshotLine == null)) { return(new HighlightedLine(line, new[] { new ColoredSegment(0, line.Length, ScopeStack.Empty) })); } List <ColoredSegment> coloredSegments = new List <ColoredSegment>(); SnapshotSpan snapshotSpan = snapshotLine.Extent; int lastClassifiedOffsetEnd = snapshotSpan.Start; ScopeStack scopeStack; IList <ClassificationSpan> classifications = await MonoDevelop.Core.Runtime.RunInMainThread(() => this.classifier.GetClassificationSpans(snapshotSpan)); foreach (ClassificationSpan curSpan in classifications) { if (curSpan.Span.Start > lastClassifiedOffsetEnd) { scopeStack = new ScopeStack(EditorThemeColors.Foreground); ColoredSegment whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd - snapshotLine.Start, curSpan.Span.Start - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } string styleName = GetStyleNameFromClassificationType(curSpan.ClassificationType); scopeStack = new ScopeStack(styleName); ColoredSegment curColoredSegment = new ColoredSegment(curSpan.Span.Start - snapshotLine.Start, curSpan.Span.Length, scopeStack); coloredSegments.Add(curColoredSegment); lastClassifiedOffsetEnd = curSpan.Span.End; } if (snapshotLine.End.Position > lastClassifiedOffsetEnd) { scopeStack = new ScopeStack(EditorThemeColors.Foreground); ColoredSegment whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd - snapshotLine.Start, snapshotLine.End.Position - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } HighlightedLine result = new HighlightedLine(line, coloredSegments); return(result); }
public SearchResultNode(SearchResultMatch result) { this.result = result; IDocument document = result.CreateDocument(); var startPosition = result.GetStartPosition(document); int lineNumber = startPosition.Line; int column = startPosition.Column; this.anchor = new PermanentAnchor(result.FileName, lineNumber, column); anchor.SurviveDeletion = true; if (lineNumber >= 1 && lineNumber <= document.TotalNumberOfLines) { IDocumentLine matchedLine = document.GetLine(lineNumber); inlineBuilder = new HighlightedInlineBuilder(matchedLine.Text); inlineBuilder.SetFontFamily(0, inlineBuilder.Text.Length, resultLineFamily); IHighlighter highlighter = document.GetService(typeof(IHighlighter)) as IHighlighter; if (highlighter != null) { HighlightedLine highlightedLine = highlighter.HighlightLine(lineNumber); int startOffset = highlightedLine.DocumentLine.Offset; // copy only the foreground color foreach (HighlightedSection section in highlightedLine.Sections) { if (section.Color.Foreground != null) { inlineBuilder.SetForeground(section.Offset - startOffset, section.Length, section.Color.Foreground.GetBrush(null)); } } } // now highlight the match in bold if (column >= 1) { var endPosition = result.GetEndPosition(document); if (endPosition.Line == startPosition.Line && endPosition.Column > startPosition.Column) { // subtract one from the column to get the offset inside the line's text int startOffset = column - 1; int endOffset = Math.Min(inlineBuilder.Text.Length, endPosition.Column - 1); inlineBuilder.SetFontWeight(startOffset, endOffset - startOffset, FontWeights.Bold); } } } }
public Task <HighlightedLine> GetHighlightedLineAsync(IDocumentLine line, CancellationToken cancellationToken) { ITextSnapshotLine snapshotLine = (line as Mono.TextEditor.TextDocument.DocumentLineFromTextSnapshotLine)?.Line; if ((this.classifier == null) || (snapshotLine == null)) { return(Task.FromResult(new HighlightedLine(line, new[] { new ColoredSegment(0, line.Length, ScopeStack.Empty) }))); } List <ColoredSegment> coloredSegments = new List <ColoredSegment>(); SnapshotSpan snapshotSpan = snapshotLine.Extent; int lastClassifiedOffsetEnd = snapshotSpan.Start; ScopeStack scopeStack; IList <ClassificationSpan> classifications = this.classifier.GetClassificationSpans(snapshotSpan); foreach (ClassificationSpan curSpan in classifications) { if (curSpan.Span.Start > lastClassifiedOffsetEnd) { scopeStack = new ScopeStack(EditorThemeColors.Foreground); ColoredSegment whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd - snapshotLine.Start, curSpan.Span.Start - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } string styleName = GetStyleNameFromClassificationType(curSpan.ClassificationType); scopeStack = new ScopeStack(styleName); ColoredSegment curColoredSegment = new ColoredSegment(curSpan.Span.Start - snapshotLine.Start, curSpan.Span.Length, scopeStack); coloredSegments.Add(curColoredSegment); lastClassifiedOffsetEnd = curSpan.Span.End; } if (snapshotLine.End.Position > lastClassifiedOffsetEnd) { scopeStack = new ScopeStack(EditorThemeColors.Foreground); ColoredSegment whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd - snapshotLine.Start, snapshotLine.End.Position - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } HighlightedLine result = new HighlightedLine(line, coloredSegments); return(Task.FromResult(result)); }
public static bool IsInHighlightSection(this TextArea textArea, string highlightName, int caretOffset = -1) { IHighlighter highlighter = textArea.GetService(typeof(IHighlighter)) as IHighlighter; if (highlighter == null) { return(false); } if (caretOffset == -1) { caretOffset = textArea.Caret.Offset; } HighlightedLine result = highlighter.HighlightLine(textArea.Document.GetLineByOffset(caretOffset).LineNumber); return(result.Sections.Any(s => s.Offset <= caretOffset && s.Offset + s.Length >= caretOffset && s.Color.Name == highlightName)); }
/// <inheritdoc/> protected override void ColorizeLine(DocumentLine line) { string lineString = _document.GetText(line); if (CurrentContext.TextView.Services.GetService(typeof(IHighlighter)) is IHighlighter highlighter) { if (lineString.Length < 3 || lineString.Substring(0, 3) == ">>>" || lineString.Substring(0, 3) == "...") { HighlightedLine hl = highlighter.HighlightLine(line.LineNumber); foreach (HighlightedSection section in hl.Sections) { ChangeLinePart(section.Offset, section.Offset + section.Length, visualLineElement => ApplyColorToElement(visualLineElement, section.Color)); } } else { // Could add foreground colour functionality here. } } }
public HighlightedLine HighlightLine(int lineNumber) { var documentLine = Document.GetLineByNumber(lineNumber); var lineText = Document.GetText(documentLine); var highlightedLine = new HighlightedLine(Document, documentLine); var parser = new LyricsParser(); foreach (var node in parser.ParseLine(lineText)) { foreach (var token in node.Tokens) { highlightedLine.Sections.Add(new HighlightedSection { Offset = token.Span.Start.Index + documentLine.Offset, Length = token.Span.Length, Color = GetNamedColor(token.Label) }); } } return(highlightedLine); }
/// <summary> /// Creates a HTML fragment from a part of a document. /// </summary> /// <param name="document">The document to create HTML from.</param> /// <param name="highlighter">The highlighter used to highlight the document.</param> /// <param name="segment">The part of the document to create HTML for. You can pass null to create HTML for the whole document.</param> /// <param name="options">The options for the HTML creation.</param> /// <returns>HTML code for the document part.</returns> public static string CreateHtmlFragment(TextDocument document, DocumentHighlighter highlighter, ISegment segment, HtmlOptions options) { if (document == null) { throw new ArgumentNullException("document"); } if (options == null) { throw new ArgumentNullException("options"); } if (segment == null) { segment = new SimpleSegment(0, document.TextLength); } StringBuilder html = new StringBuilder(); int segmentEndOffset = segment.EndOffset; DocumentLine line = document.GetLineByOffset(segment.Offset); while (line != null && line.Offset < segmentEndOffset) { HighlightedLine highlightedLine; if (highlighter != null) { highlightedLine = highlighter.HighlightLine(line); } else { highlightedLine = new HighlightedLine(line); } SimpleSegment s = segment.GetOverlap(line); if (html.Length > 0) { html.AppendLine("<br>"); } html.Append(highlightedLine.ToHtml(s.Offset, s.EndOffset, options)); line = line.NextLine; } return(html.ToString()); }
private HighlightedLine DoHighlightLine(IDocumentLine documentLine) { _line = new HighlightedLine(_document, documentLine); IEnumerable <ClassifiedSpan> spans; try { // TODO: check offset in Roslyn's doc spans = Classifier.GetClassifiedSpansAsync(_roslynHost.CurrentDocument, new TextSpan(documentLine.Offset, documentLine.TotalLength), CancellationToken.None).GetAwaiter().GetResult(); } catch (OperationCanceledException) { return(_line); } foreach (var classifiedSpan in spans) { if (classifiedSpan.TextSpan.Start > documentLine.EndOffset || classifiedSpan.TextSpan.End > documentLine.EndOffset) { // TODO: this shouldn't happen, but the Roslyn document and AvalonEdit's somehow get out of sync continue; } _line.Sections.Add(new HighlightedSection { Color = ClassificationHighlightColors.GetColor(classifiedSpan.ClassificationType), Offset = classifiedSpan.TextSpan.Start, Length = classifiedSpan.TextSpan.Length }); } if (_cachedLines != null && _document.Version != null) { _cachedLines.Add(new CachedLine(_line, _document.Version)); } return(_line); }
private HighlightedLine DoHighlightLine(IDocumentLine documentLine, CachedLine previousCachedLine) { var line = new HighlightedLine(_document, documentLine); // If we have previous cached data, use it in the meantime since our request is asynchronous var previousHighlight = previousCachedLine?.HighlightedLine; if (previousHighlight != null && previousHighlight.Sections.Count > 0) { var offsetShift = documentLine.Offset - previousCachedLine.Offset; foreach (var section in previousHighlight.Sections) { var offset = section.Offset + offsetShift; // stop if section starts after end of line if (offset >= documentLine.EndOffset) { break; } // clamp section to not be longer than line line.Sections.Add(new HighlightedSection { Color = section.Color, Offset = offset, Length = Math.Min(section.Length, documentLine.EndOffset - offset), }); } } // since we don't want to block the UI thread // we'll enqueue the request and process it asynchornously EnqueueLine(line); CacheLine(line); return(line); }
public HighlightedInlineBuilder BuildInlines(int lineNumber) { HighlightedInlineBuilder builder = new HighlightedInlineBuilder(document.GetLine(lineNumber).Text); if (highlighter != null) { HighlightedLine highlightedLine = highlighter.HighlightLine(lineNumber); int startOffset = highlightedLine.DocumentLine.Offset; // copy only the foreground and background colors foreach (HighlightedSection section in highlightedLine.Sections) { if (section.Color.Foreground != null) { builder.SetForeground(section.Offset - startOffset, section.Length, section.Color.Foreground.GetBrush(null)); } if (section.Color.Background != null) { builder.SetBackground(section.Offset - startOffset, section.Length, section.Color.Background.GetBrush(null)); } } } return(builder); }
/// Gets the first offset >= startOffset where the generator wants to construct /// an element. /// Return -1 to signal no interest. public override int GetFirstInterestedOffset(int startOffset) { Match m = FindMatch(startOffset, regex); if (m.Success) { int res = startOffset + m.Index; int line = CurrentContext.Document.GetLocation(res).Line; var textArea = CurrentContext.TextView.GetService(typeof(TextArea)) as TextArea; var highlighter = textArea.GetService(typeof(IHighlighter)) as IHighlighter; HighlightedLine highlighted = highlighter.HighlightLine(line); foreach (var section in highlighted.Sections) { if (section.Color.Name == "Number" && section.Offset == res) { return(res); } } } return(-1); }
public static Block ConvertTextDocumentToBlock(TextDocument document, IHighlighter highlighter) { if (document == null) { throw new ArgumentNullException("document"); } // Table table = new Table(); // table.Columns.Add(new TableColumn { Width = GridLength.Auto }); // table.Columns.Add(new TableColumn { Width = new GridLength(1, GridUnitType.Star) }); // TableRowGroup trg = new TableRowGroup(); // table.RowGroups.Add(trg); Paragraph p = new Paragraph(); foreach (DocumentLine line in document.Lines) { int lineNumber = line.LineNumber; // TableRow row = new TableRow(); // trg.Rows.Add(row); // row.Cells.Add(new TableCell(new Paragraph(new Run(lineNumber.ToString()))) { TextAlignment = TextAlignment.Right }); HighlightedInlineBuilder inlineBuilder = new HighlightedInlineBuilder(document.GetText(line)); if (highlighter != null) { HighlightedLine highlightedLine = highlighter.HighlightLine(lineNumber); int lineStartOffset = line.Offset; foreach (HighlightedSection section in highlightedLine.Sections) { inlineBuilder.SetHighlighting(section.Offset - lineStartOffset, section.Length, section.Color); } } // Paragraph p = new Paragraph(); // row.Cells.Add(new TableCell(p)); p.Inlines.AddRange(inlineBuilder.CreateRuns()); p.Inlines.Add(new LineBreak()); } return(p); }
/// <inheritdoc/> public HighlightedLine HighlightLine(int lineNumber) { ThrowUtil.CheckInRangeInclusive(lineNumber, "lineNumber", 1, document.LineCount); CheckIsHighlighting(); isHighlighting = true; try { HighlightUpTo(lineNumber); DocumentLine line = document.GetLineByNumber(lineNumber); highlightedLine = new HighlightedLine(document, line); HighlightLineAndUpdateTreeList(line, lineNumber); return highlightedLine; } finally { highlightedLine = null; isHighlighting = false; } }
public HighlightedLine HighlightLine(int lineNumber) { var line = document.GetLineByNumber(lineNumber); int offs = line.Offset; int endOffs = line.EndOffset; var hl = new HighlightedLine(document, line); while (offs < endOffs) { int defaultTextLength, tokenLength; TextTokenKind tokenKind; if (!textEditor.LanguageTokens.Find(offs, out defaultTextLength, out tokenKind, out tokenLength)) { Debug.Fail("Could not find token info"); break; } HighlightingColor color; if (tokenLength != 0 && CanAddColor(color = GetColor(tokenKind))) { hl.Sections.Add(new HighlightedSection { Offset = offs + defaultTextLength, Length = tokenLength, Color = color, }); } offs += defaultTextLength + tokenLength; } return hl; }
public HighlightedLine HighlightLine(int lineNumber) { IDocumentLine documentLine = document.GetLineByNumber(lineNumber); if (hasCrashed) { // don't highlight anymore after we've crashed return new HighlightedLine(document, documentLine); } ITextSourceVersion newVersion = document.Version; CachedLine cachedLine = null; if (cachedLines != null) { for (int i = 0; i < cachedLines.Count; i++) { if (cachedLines[i].DocumentLine == documentLine) { if (newVersion == null || !newVersion.BelongsToSameDocumentAs(cachedLines[i].OldVersion)) { // cannot list changes from old to new: we can't update the cache, so we'll remove it cachedLines.RemoveAt(i); } else { cachedLine = cachedLines[i]; } break; } } if (cachedLine != null && cachedLine.IsValid && newVersion.CompareAge(cachedLine.OldVersion) == 0) { // the file hasn't changed since the cache was created, so just reuse the old highlighted line #if DEBUG cachedLine.HighlightedLine.ValidateInvariants(); #endif return cachedLine.HighlightedLine; } } bool wasInHighlightingGroup = inHighlightingGroup; if (!inHighlightingGroup) { BeginHighlighting(); } try { return DoHighlightLine(lineNumber, documentLine, cachedLine, newVersion); } finally { line = null; if (!wasInHighlightingGroup) EndHighlighting(); } }
public CachedLine(HighlightedLine highlightedLine, ITextSourceVersion fileVersion) { if (highlightedLine == null) throw new ArgumentNullException(nameof(highlightedLine)); if (fileVersion == null) throw new ArgumentNullException(nameof(fileVersion)); HighlightedLine = highlightedLine; OldVersion = fileVersion; IsValid = true; }
void PrintWords(TextWriter writer, HighlightedLine line) { writer.Write(line.ToHtml(new MyHtmlOptions(this))); }
private void EnqueueLine(HighlightedLine line) { _queue.Enqueue(line); _semaphore.Release(); }
private void CacheLine(HighlightedLine line) { if (_cachedLines != null && _document.Version != null) { _cachedLines.Add(new CachedLine(line, _document.Version)); } }
public string GenerateHtml(TextDocument document, IHighlighter highlighter) { string myMainStyle = MainStyle; string LineNumberStyle = "color: #606060;"; DocumentLine docline = null; string textLine = null; if (highlighter == null) { docline = document.GetLineByNumber(1); } StringWriter output = new StringWriter(); if (ShowLineNumbers || AlternateLineBackground) { output.Write("<div"); WriteStyle(output, myMainStyle); output.WriteLine(">"); int longestNumberLength = 1 + (int)Math.Log10(document.LineCount); for (int lineNumber = 1; lineNumber <= document.LineCount; lineNumber++) { HighlightedLine line = null; if (highlighter != null) { line = highlighter.HighlightLine(lineNumber); } else { textLine = document.GetText(docline); docline = docline.NextLine; } output.Write("<pre"); if (AlternateLineBackground && (lineNumber % 2) == 0) { WriteStyle(output, AlternateLineStyle); } else { WriteStyle(output, LineStyle); } output.Write(">"); if (ShowLineNumbers) { output.Write("<span"); WriteStyle(output, LineNumberStyle); output.Write('>'); output.Write(lineNumber.ToString().PadLeft(longestNumberLength)); output.Write(": "); output.Write("</span>"); } PrintWords(output, line, textLine); output.WriteLine("</pre>"); } output.WriteLine("</div>"); } else { output.Write("<pre"); WriteStyle(output, myMainStyle + LineStyle); output.WriteLine(">"); for (int lineNumber = 1; lineNumber <= document.LineCount; lineNumber++) { HighlightedLine line = highlighter.HighlightLine(lineNumber); PrintWords(output, line, textLine); output.WriteLine(); } output.WriteLine("</pre>"); } if (CreateStylesheet && stylesheet.Length > 0) { string result = "<style type=\"text/css\">" + stylesheet.ToString() + "</style>" + output.ToString(); stylesheet = new StringBuilder(); return(result); } else { return(output.ToString()); } }
private HighlightedLine DoHighlightLine(IDocumentLine documentLine) { var line = new HighlightedLine(_document, documentLine); // since we don't want to block the UI thread // we'll enqueue the request and process it asynchornously EnqueueLine(line); CacheLine(line); return line; }
HighlightedLine DoHighlightLine(int lineNumber, IDocumentLine documentLine, CachedLine cachedLine, ITextSourceVersion newVersion) { if (parseInfo == null) { if (forceParseOnNextRefresh) { forceParseOnNextRefresh = false; parseInfo = SD.ParserService.Parse(FileName.Create(document.FileName), document) as CSharpFullParseInformation; } else { parseInfo = SD.ParserService.GetCachedParseInformation(FileName.Create(document.FileName), newVersion) as CSharpFullParseInformation; } } if (parseInfo == null) { if (invalidLines != null && !invalidLines.Contains(documentLine)) { invalidLines.Add(documentLine); //Debug.WriteLine("Semantic highlighting for line {0} - marking as invalid", lineNumber); } if (cachedLine != null) { // If there's a cached version, adjust it to the latest document changes and return it. // This avoids flickering when changing a line that contains semantic highlighting. cachedLine.Update(newVersion); #if DEBUG cachedLine.HighlightedLine.ValidateInvariants(); #endif return cachedLine.HighlightedLine; } else { return null; } } if (visitor.Resolver == null) { var compilation = SD.ParserService.GetCompilationForFile(parseInfo.FileName); visitor.Resolver = parseInfo.GetResolver(compilation); } line = new HighlightedLine(document, documentLine); this.lineNumber = lineNumber; visitor.UpdateLineInformation(lineNumber); if (Debugger.IsAttached) { parseInfo.SyntaxTree.AcceptVisitor(visitor); #if DEBUG line.ValidateInvariants(); #endif } else { try { parseInfo.SyntaxTree.AcceptVisitor(visitor); #if DEBUG line.ValidateInvariants(); #endif } catch (Exception ex) { hasCrashed = true; throw new ApplicationException("Error highlighting line " + lineNumber, ex); } } //Debug.WriteLine("Semantic highlighting for line {0} - added {1} sections", lineNumber, line.Sections.Count); if (cachedLines != null && document.Version != null) { cachedLines.Add(new CachedLine(line, document.Version)); } return line; }
public CachedLine(HighlightedLine highlightedLine, ITextSourceVersion fileVersion) { HighlightedLine = highlightedLine ?? throw new ArgumentNullException(nameof(highlightedLine)); OldVersion = fileVersion ?? throw new ArgumentNullException(nameof(fileVersion)); }
private void EnqueueLine(HighlightedLine line) { _queue.Enqueue(line); _semaphore.Release(); }
void PrintWords(TextWriter writer, HighlightedLine line) { writer.Write(line.ToHtml(new MyHtmlOptions(this))); }
HighlightedLine DoHighlightLine(int lineNumber, IDocumentLine documentLine, CachedLine cachedLine, ITextSourceVersion newVersion) { if (parseInfo == null) { if (forceParseOnNextRefresh) { forceParseOnNextRefresh = false; parseInfo = SD.ParserService.Parse(FileName.Create(document.FileName), document) as CSharpFullParseInformation; } else { parseInfo = SD.ParserService.GetCachedParseInformation(FileName.Create(document.FileName), newVersion) as CSharpFullParseInformation; } } if (parseInfo == null) { if (invalidLines != null && !invalidLines.Contains(documentLine)) { invalidLines.Add(documentLine); //Debug.WriteLine("Semantic highlighting for line {0} - marking as invalid", lineNumber); } if (cachedLine != null) { // If there's a cached version, adjust it to the latest document changes and return it. // This avoids flickering when changing a line that contains semantic highlighting. cachedLine.Update(newVersion); #if DEBUG cachedLine.HighlightedLine.ValidateInvariants(); #endif return(cachedLine.HighlightedLine); } else { return(null); } } if (visitor.Resolver == null) { var compilation = SD.ParserService.GetCompilationForFile(parseInfo.FileName); visitor.Resolver = parseInfo.GetResolver(compilation); } line = new HighlightedLine(document, documentLine); this.lineNumber = lineNumber; visitor.UpdateLineInformation(lineNumber); if (Debugger.IsAttached) { parseInfo.SyntaxTree.AcceptVisitor(visitor); #if DEBUG line.ValidateInvariants(); #endif } else { try { parseInfo.SyntaxTree.AcceptVisitor(visitor); #if DEBUG line.ValidateInvariants(); #endif } catch (Exception ex) { hasCrashed = true; throw new ApplicationException("Error highlighting line " + lineNumber, ex); } } //Debug.WriteLine("Semantic highlighting for line {0} - added {1} sections", lineNumber, line.Sections.Count); if (cachedLines != null && document.Version != null) { cachedLines.Add(new CachedLine(line, document.Version)); } return(line); }
private void PrintWords(TextWriter writer, HighlightedLine line, string text) { writer.Write(line != null ? line.ToHtml(new MyHtmlOptions(this)) : text); }
public HighlightedLine HighlightLine(int lineNumber) { HighlightedLine line = new HighlightedLine(document, document.GetLineByNumber(lineNumber)); foreach (IHighlighter h in nestedHighlighters) { line.MergeWith(h.HighlightLine(lineNumber)); } return line; }
/// <summary> /// Highlights the specified document line. /// </summary> /// <param name="line">The line to highlight.</param> /// <returns>A <see cref="HighlightedLine"/> line object that represents the highlighted sections.</returns> public HighlightedLine HighlightLine(DocumentLine line) { if (!document.Lines.Contains(line)) throw new ArgumentException("The specified line does not belong to the document."); CheckIsHighlighting(); isHighlighting = true; try { int targetLineNumber = line.LineNumber; HighlightUpTo(targetLineNumber); highlightedLine = new HighlightedLine(document, line); HighlightLineAndUpdateTreeList(line, targetLineNumber); return highlightedLine; } finally { highlightedLine = null; isHighlighting = false; } }
public CachedLine(HighlightedLine highlightedLine, ITextSourceVersion fileVersion) { if (highlightedLine == null) throw new ArgumentNullException("highlightedLine"); if (fileVersion == null) throw new ArgumentNullException("fileVersion"); this.HighlightedLine = highlightedLine; this.OldVersion = fileVersion; this.IsValid = true; }