void ScanAndAddComment(List <ColoredSegment> coloredSegments, int startOffset, ScopeStack commentScopeStack, ClassificationSpan classificationSpan) { int lastClassifiedOffset = classificationSpan.Span.Start; try { // Scan comments for tag highlighting var text = textView.TextSnapshot.GetText(classificationSpan.Span); int idx = 0, oldIdx = 0; while ((idx = FindNextCommentTagIndex(text, idx, out string commentTag)) >= 0) { var headSpanLength = idx - oldIdx; if (headSpanLength > 0) { var headSegment = new ColoredSegment(lastClassifiedOffset - startOffset, headSpanLength, commentScopeStack); lastClassifiedOffset += headSpanLength; coloredSegments.Add(headSegment); } var highlightSegment = new ColoredSegment(lastClassifiedOffset - startOffset, commentTag.Length, commentScopeStack.Push("markup.other")); coloredSegments.Add(highlightSegment); idx += commentTag.Length; lastClassifiedOffset += commentTag.Length; oldIdx = idx; } } catch (Exception e) { LoggingService.LogError("Error while scanning comment tags.", e); } int tailSpanLength = classificationSpan.Span.End - lastClassifiedOffset; if (tailSpanLength > 0) { var tailSpan = new ColoredSegment(lastClassifiedOffset - startOffset, tailSpanLength, commentScopeStack); coloredSegments.Add(tailSpan); } }
void CopyData(TextEditorData data, Selection selection) { if (!selection.IsEmpty && data != null && data.Document != null) { this.docStyle = data.ColorStyle; this.options = data.Options; copyData = null; switch (selection.SelectionMode) { case SelectionMode.Normal: isBlockMode = false; var segment = selection.GetSelectionRange(data); copiedColoredChunks = ColoredSegment.GetChunks(data, segment); var pasteHandler = data.TextPasteHandler; if (pasteHandler != null) { try { copyData = pasteHandler.GetCopyData(segment); } catch (Exception e) { Console.WriteLine("Exception while getting copy data:" + e); } } break; case SelectionMode.Block: isBlockMode = true; DocumentLocation visStart = data.LogicalToVisualLocation(selection.Anchor); DocumentLocation visEnd = data.LogicalToVisualLocation(selection.Lead); int startCol = System.Math.Min(visStart.Column, visEnd.Column); int endCol = System.Math.Max(visStart.Column, visEnd.Column); copiedColoredChunks = new List <List <ColoredSegment> >(); for (int lineNr = selection.MinLine; lineNr <= selection.MaxLine; lineNr++) { DocumentLine curLine = data.Document.GetLine(lineNr); int col1 = curLine.GetLogicalColumn(data, startCol) - 1; int col2 = System.Math.Min(curLine.GetLogicalColumn(data, endCol) - 1, curLine.Length); if (col1 < col2) { copiedColoredChunks.Add(ColoredSegment.GetChunks(data, new TextSegment(curLine.Offset + col1, col2 - col1)).First()); } else { copiedColoredChunks.Add(new List <ColoredSegment>()); } } break; } } else { copiedColoredChunks = null; } }
async Task <HighlightedLine> ISyntaxHighlighting.GetHighlightedLineAsync(IDocumentLine line, CancellationToken cancellationToken) { if (line == null) { throw new ArgumentNullException(nameof(line)); } if (!DefaultSourceEditorOptions.Instance.EnableSemanticHighlighting) { return(await syntaxMode.GetHighlightedLineAsync(line, cancellationToken)); } var syntaxLine = await syntaxMode.GetHighlightedLineAsync(line, cancellationToken).ConfigureAwait(false); if (syntaxLine.Segments.Count == 0) { return(syntaxLine); } lock (lineSegments) { var segments = new List <ColoredSegment> (syntaxLine.Segments); int endOffset = segments [segments.Count - 1].EndOffset; try { var tree = lineSegments.FirstOrDefault(t => t.Item1 == line); int lineOffset = line.Offset; if (tree == null) { tree = Tuple.Create(line, new HighlightingSegmentTree()); tree.Item2.InstallListener(editor.Document); foreach (var seg2 in semanticHighlighting.GetColoredSegments(new TextSegment(lineOffset, line.Length))) { tree.Item2.AddStyle(seg2, seg2.ColorStyleKey); } while (lineSegments.Count > MaximumCachedLineSegments) { var removed = lineSegments.Dequeue(); try { removed.Item2.RemoveListener(); } catch (Exception) { } } lineSegments.Enqueue(tree); } foreach (var treeseg in tree.Item2.GetSegmentsOverlapping(line)) { var inLineStartOffset = Math.Max(0, treeseg.Offset - lineOffset); var inLineEndOffset = Math.Min(line.Length, treeseg.EndOffset - lineOffset); if (inLineEndOffset <= inLineStartOffset) { continue; } var semanticSegment = new ColoredSegment(inLineStartOffset, inLineEndOffset - inLineStartOffset, syntaxLine.Segments [0].ScopeStack.Push(treeseg.Style)); SyntaxHighlighting.ReplaceSegment(segments, semanticSegment); } } catch (Exception e) { LoggingService.LogError("Error in semantic highlighting: " + e); return(syntaxLine); } return(new HighlightedLine(line, segments)); } }
public Task <HighlightedLine> GetHighlightedLineAsync(IDocumentLine line, CancellationToken cancellationToken) { var 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) }))); } try { var coloredSegments = new List <ColoredSegment>(); var snapshotSpan = new SnapshotSpan(snapshotLine.Snapshot, snapshotLine.Extent.Span); int start = snapshotSpan.Start.Position; int end = snapshotSpan.End.Position; var classifications = classifier.GetClassificationSpans(snapshotSpan); int lastClassifiedOffsetEnd = start; ScopeStack scopeStack; foreach (var curSpan in classifications) { if (curSpan.Span.Start > lastClassifiedOffsetEnd) { scopeStack = defaultScopeStack; var whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd - start, curSpan.Span.Start - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } scopeStack = GetScopeStackFromClassificationType(curSpan.ClassificationType); if (scopeStack.Peek().StartsWith("comment", StringComparison.Ordinal)) { ScanAndAddComment(coloredSegments, start, scopeStack, curSpan); } else { var curColoredSegment = new ColoredSegment(curSpan.Span.Start - start, curSpan.Span.Length, scopeStack); coloredSegments.Add(curColoredSegment); } lastClassifiedOffsetEnd = curSpan.Span.End; } if (end > lastClassifiedOffsetEnd) { scopeStack = defaultScopeStack; var whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd - start, end - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } return(Task.FromResult(new HighlightedLine(line, coloredSegments))); } catch (Exception e) { LoggingService.LogInternalError("Error while getting highlighted line " + line, e); return(Task.FromResult(new HighlightedLine(line, new [] { new ColoredSegment(0, line.Length, ScopeStack.Empty) }))); } }
void IChunkMarker.TransformChunks(List <MonoDevelop.Ide.Editor.Highlighting.ColoredSegment> chunks) { int markerStart = Segment.Offset; int markerEnd = Segment.EndOffset; for (int i = 0; i < chunks.Count; i++) { var chunk = chunks [i]; if (chunk.EndOffset < markerStart || markerEnd <= chunk.Offset) { continue; } if (chunk.Offset == markerStart && chunk.EndOffset == markerEnd) { return; } if (chunk.Contains(markerStart) && chunk.Contains(markerEnd)) { var chunkBefore = new ColoredSegment(chunk.Offset, markerStart - chunk.Offset, chunk.ScopeStack); var chunkAfter = new ColoredSegment(markerEnd, chunk.EndOffset - markerEnd, chunk.ScopeStack); chunks [i] = new ColoredSegment(markerStart, markerEnd - markerStart, chunk.ScopeStack); if (chunkAfter.Length > 0) { chunks.Insert(i + 1, chunkAfter); } if (chunkBefore.Length > 0) { chunks.Insert(i, chunkBefore); i++; } if (chunkAfter.Length > 0) { i++; } continue; } if (chunk.Contains(markerStart)) { var chunkBefore = new ColoredSegment(chunk.Offset, markerStart - chunk.Offset, chunk.ScopeStack); chunks [i] = new ColoredSegment(markerStart, chunk.EndOffset - markerStart, chunk.ScopeStack); chunks.Insert(i, chunkBefore); i++; continue; } if (chunk.Contains(markerEnd)) { var chunkAfter = new ColoredSegment(markerEnd, chunk.EndOffset - markerEnd, chunk.ScopeStack); chunks [i] = new ColoredSegment(chunk.Offset, markerEnd - chunk.Offset, chunk.ScopeStack); chunks.Insert(i + 1, chunkAfter); i++; continue; } } }
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 = new SnapshotSpan(textView.TextBuffer.CurrentSnapshot, snapshotLine.Extent.Span); int start = snapshotSpan.Start.Position; int end = snapshotSpan.End.Position; IList <ClassificationSpan> classifications = this.classifier.GetAllClassificationSpans(snapshotSpan, cancellationToken); int lastClassifiedOffsetEnd = start; ScopeStack scopeStack; foreach (ClassificationSpan curSpan in classifications) { if (curSpan.Span.Start > lastClassifiedOffsetEnd) { scopeStack = defaultScopeStack; ColoredSegment whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd - start, curSpan.Span.Start - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } scopeStack = GetScopeStackFromClassificationType(curSpan.ClassificationType); if (scopeStack.Peek().StartsWith("comment", StringComparison.Ordinal)) { ScanAndAddComment(coloredSegments, start, scopeStack, curSpan); } else { var curColoredSegment = new ColoredSegment(curSpan.Span.Start - start, curSpan.Span.Length, scopeStack); coloredSegments.Add(curColoredSegment); } lastClassifiedOffsetEnd = curSpan.Span.End; } if (end > lastClassifiedOffsetEnd) { scopeStack = defaultScopeStack; ColoredSegment whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd - start, end - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } return(Task.FromResult(new HighlightedLine(line, coloredSegments))); }
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 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)); }
async Task <HighlightedLine> ISyntaxHighlighting.GetHighlightedLineAsync(IDocumentLine line, CancellationToken cancellationToken) { if (line == null) { throw new ArgumentNullException(nameof(line)); } if (!DefaultSourceEditorOptions.Instance.EnableSemanticHighlighting) { return(await syntaxMode.GetHighlightedLineAsync(line, cancellationToken)); } var syntaxLine = await syntaxMode.GetHighlightedLineAsync(line, cancellationToken).ConfigureAwait(false); if (syntaxLine.Segments.Count == 0) { return(syntaxLine); } var segments = new List <ColoredSegment> (syntaxLine.Segments); int endOffset = segments [segments.Count - 1].EndOffset; try { // This code should not have any lambda capture linq, as it is a hot loop. int lineOffset = line.Offset; foreach (var treeseg in semanticHighlighting.GetColoredSegments(new TextSegment(lineOffset, line.Length))) { var inLineStartOffset = Math.Max(0, treeseg.Offset - lineOffset); var inLineEndOffset = Math.Min(line.Length, treeseg.EndOffset - lineOffset); if (inLineEndOffset <= inLineStartOffset) { continue; } var semanticSegment = new ColoredSegment(inLineStartOffset, inLineEndOffset - inLineStartOffset, treeseg.ScopeStack); SyntaxHighlighting.ReplaceSegment(segments, semanticSegment); } } catch (Exception e) { LoggingService.LogError("Error in semantic highlighting: ", e); return(syntaxLine); } return(new HighlightedLine(line, segments)); }
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 = vbScope.Push(EditorThemeColors.UserTypes); ColoredSegment whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd, curSpan.TextSpan.Start - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } string styleName = GetStyleNameFromClassificationType(curSpan.ClassificationType); scopeStack = vbScope.Push(styleName); ColoredSegment curColoredSegment = new ColoredSegment(curSpan.TextSpan.Start, curSpan.TextSpan.Length, scopeStack); coloredSegments.Add(curColoredSegment); lastClassifiedOffsetEnd = curSpan.TextSpan.End; } if (offset + length > lastClassifiedOffsetEnd) { scopeStack = vbScope.Push(EditorThemeColors.UserTypes); ColoredSegment whitespaceSegment = new ColoredSegment(lastClassifiedOffsetEnd, offset + length - lastClassifiedOffsetEnd, scopeStack); coloredSegments.Add(whitespaceSegment); } return(new HighlightedLine(coloredSegments)); }
void CopyData(TextEditorData data, Selection selection) { copiedDocument = null; monoDocument = null; if (!selection.IsEmpty && data != null && data.Document != null) { copiedDocument = new TextDocument(); monoDocument = new TextDocument(); this.docStyle = data.ColorStyle; this.options = data.Options; copyData = null; copiedColoredChunks = ColoredSegment.GetChunks(data, data.SelectionRange); switch (selection.SelectionMode) { case SelectionMode.Normal: isBlockMode = false; var segment = selection.GetSelectionRange(data); var pasteHandler = data.TextPasteHandler; if (pasteHandler != null) { copyData = pasteHandler.GetCopyData(segment); } var text = data.GetTextAt(segment); copiedDocument.Text = text; monoDocument.Text = text; var line = data.Document.GetLineByOffset(segment.Offset); var spanStack = line.StartSpan.Clone(); this.copiedDocument.GetLine(DocumentLocation.MinLine).StartSpan = spanStack; break; case SelectionMode.Block: isBlockMode = true; DocumentLocation visStart = data.LogicalToVisualLocation(selection.Anchor); DocumentLocation visEnd = data.LogicalToVisualLocation(selection.Lead); int startCol = System.Math.Min(visStart.Column, visEnd.Column); int endCol = System.Math.Max(visStart.Column, visEnd.Column); for (int lineNr = selection.MinLine; lineNr <= selection.MaxLine; lineNr++) { DocumentLine curLine = data.Document.GetLine(lineNr); int col1 = curLine.GetLogicalColumn(data, startCol) - 1; int col2 = System.Math.Min(curLine.GetLogicalColumn(data, endCol) - 1, curLine.Length); if (col1 < col2) { copiedDocument.Insert(copiedDocument.TextLength, data.Document.GetTextAt(curLine.Offset + col1, col2 - col1)); monoDocument.Insert(monoDocument.TextLength, data.Document.GetTextAt(curLine.Offset + col1, col2 - col1)); } if (lineNr < selection.MaxLine) { // Clipboard line end needs to be system dependend and not the document one. copiedDocument.Insert(copiedDocument.TextLength, Environment.NewLine); // \r in mono document stands for block selection line end. monoDocument.Insert(monoDocument.TextLength, "\r"); } } line = data.Document.GetLine(selection.MinLine); spanStack = line.StartSpan.Clone(); this.copiedDocument.GetLine(DocumentLocation.MinLine).StartSpan = spanStack; break; } } else { copiedDocument = null; } }