However, there is a single method that is thread-safe: CreateSnapshot() (and its overloads).
internal DocumentLine(TextDocument document) { #if DEBUG Debug.Assert(document != null); this.document = document; #endif }
/// <summary> /// Creates a new TextDocumentAccessor that indents only a part of the document. /// </summary> public TextDocumentAccessor(TextDocument document, int minLine, int maxLine) { if (document == null) throw new ArgumentNullException("document"); doc = document; this.minLine = minLine; this.maxLine = maxLine; }
/// <summary> /// Creates a new TextDocumentAccessor. /// </summary> public TextDocumentAccessor(TextDocument document) { if (document == null) throw new ArgumentNullException("document"); doc = document; minLine = 1; maxLine = doc.LineCount; }
/// <summary> /// Registers the <paramref name="targetTracker" /> as line tracker for the <paramref name="textDocument" />. /// A weak reference to the target tracker will be used, and the WeakLineTracker will deregister itself /// when the target tracker is garbage collected. /// </summary> public static WeakLineTracker Register(TextDocument textDocument, ILineTracker targetTracker) { if (textDocument == null) throw new ArgumentNullException("textDocument"); if (targetTracker == null) throw new ArgumentNullException("targetTracker"); var wlt = new WeakLineTracker(textDocument, targetTracker); textDocument.LineTrackers.Add(wlt); return wlt; }
public TextColoringTransformer(TextDocument document) { this.document = document; TextTransformations = new TextSegmentCollection<TextTransformation>(document); CommentBrush = Brush.Parse("#559A3F"); CallExpressionBrush = Brush.Parse("Pink"); IdentifierBrush = Brush.Parse("#D4D4D4"); KeywordBrush = Brush.Parse("#569CD6"); LiteralBrush = Brush.Parse("#D69D85"); PunctuationBrush = Brush.Parse("#D4D4D4"); UserTypeBrush = Brush.Parse("#4BB289"); }
/// <inheritdoc cref="IIndentationStrategy.IndentLine" /> public override int IndentLine(TextDocument document, DocumentLine line, int caretOffset) { var lineNr = line.LineNumber; var acc = new TextDocumentAccessor(document, lineNr, lineNr); var result = Indent(acc, false, caretOffset); var t = acc.Text; if (t.Length == 0) { // use AutoIndentation for new lines in comments / verbatim strings. return base.IndentLine(document, line, caretOffset); } return result; }
public EditorModel() { shell = IoC.Get<IShell>(); codeAnalysisRunner = new JobRunner(); TextDocument = new TextDocument(); AnalysisTriggerEvents.Select(_ => Observable.Timer(TimeSpan.FromMilliseconds(500)) .SelectMany(o => DoCodeAnalysisAsync())).Switch().Subscribe(_ => { }); //AnalysisTriggerEvents.Throttle(TimeSpan.FromMilliseconds(500)).Subscribe(async _ => //{ // await DoCodeAnalysisAsync(); //}); }
public TextColoringTransformer(TextDocument document) { this.document = document; TextTransformations = new TextSegmentCollection<TextTransformation>(document); CommentBrush = Brush.Parse("#559A3F"); CallExpressionBrush = Brush.Parse("#DCDCAA"); IdentifierBrush = Brush.Parse("#C8C8C8"); KeywordBrush = Brush.Parse("#569CD6"); LiteralBrush = Brush.Parse("#D69D85"); NumericLiteralBrush = Brush.Parse("#B5CEA8"); EnumConstantBrush = Brush.Parse("#B5CEA8"); EnumTypeNameBrush = Brush.Parse("#B5CEA8"); InterfaceBrush = Brush.Parse("#B5CEA8"); PunctuationBrush = Brush.Parse("#C8C8C8"); UserTypeBrush = Brush.Parse("#4EC9B0"); }
/// <inheritdoc /> public virtual int IndentLine(TextDocument document, DocumentLine line, int caretOffset) { if (document == null) throw new ArgumentNullException("document"); if (line == null) throw new ArgumentNullException("line"); var previousLine = line.PreviousLine; if (previousLine != null) { var indentationSegment = TextUtilities.GetWhitespaceAfter(document, previousLine.Offset); var indentation = document.GetText(indentationSegment); // copy indentation to line indentationSegment = TextUtilities.GetWhitespaceAfter(document, line.Offset); document.Replace(indentationSegment, indentation); } return caretOffset; }
/// <inheritdoc cref="IIndentationStrategy.IndentLine" /> public override int IndentLine(TextDocument document, DocumentLine line, int caretIndex) { if (line == null) { return caretIndex; } var lineNr = line.LineNumber; var acc = new TextDocumentAccessor(document, lineNr, lineNr); var leadingWhiteSpaceBefore = TextUtilities.GetLeadingWhitespace(document, line).Length; var result = Indent(acc, false, caretIndex); var t = acc.Text; result = caretIndex + TextUtilities.GetLeadingWhitespace(document, line).Length - leadingWhiteSpaceBefore; if (t.Length == 0) { // use AutoIndentation for new lines in comments / verbatim strings. return base.IndentLine(document, line, caretIndex); } return result; }
public int Format(TextDocument textDocument, uint offset, uint length, int cursor) { bool replaceCursor = cursor >= 0 ? true : false; if (!replaceCursor) { cursor = 0; } var replacements = ClangFormat.FormatXml(textDocument.Text, offset, length, (uint)cursor, ClangFormatSettings.Default); return ApplyReplacements(textDocument, cursor, replacements, replaceCursor); }
public void RegisterSourceFile(IIntellisenseControl intellisense, ICompletionAssistant completionAssistant, TextEditor.TextEditor editor, ISourceFile file, TextDocument doc) { CPlusPlusDataAssociation association = null; if (dataAssociations.TryGetValue(file, out association)) { throw new Exception("Source file already registered with language service."); } association = new CPlusPlusDataAssociation(doc); dataAssociations.Add(file, association); association.KeyUpHandler = (sender, e) => { if (editor.TextDocument == doc) { switch (e.Key) { case Key.Return: { if (editor.CaretIndex >= 0 && editor.CaretIndex < editor.TextDocument.TextLength) { if (editor.TextDocument.GetCharAt(editor.CaretIndex) == '}') { editor.TextDocument.Insert(editor.CaretIndex, Environment.NewLine); editor.CaretIndex--; var currentLine = editor.TextDocument.GetLineByOffset(editor.CaretIndex); editor.CaretIndex = IndentationStrategy.IndentLine(editor.TextDocument, currentLine, editor.CaretIndex); editor.CaretIndex = IndentationStrategy.IndentLine(editor.TextDocument, currentLine.NextLine.NextLine, editor.CaretIndex); editor.CaretIndex = IndentationStrategy.IndentLine(editor.TextDocument, currentLine.NextLine, editor.CaretIndex); } var newCaret = IndentationStrategy.IndentLine(editor.TextDocument, editor.TextDocument.GetLineByOffset(editor.CaretIndex), editor.CaretIndex); editor.CaretIndex = newCaret; } } break; } } }; association.TextInputHandler = (sender, e) => { if (editor.TextDocument == doc) { OpenBracket(editor, editor.TextDocument, e.Text); CloseBracket(editor, editor.TextDocument, e.Text); switch (e.Text) { case "}": case ";": editor.CaretIndex = Format(editor.TextDocument, 0, (uint)editor.TextDocument.TextLength, editor.CaretIndex); break; case "{": var lineCount = editor.TextDocument.LineCount; var offset = Format(editor.TextDocument, 0, (uint)editor.TextDocument.TextLength, editor.CaretIndex); // suggests clang format didnt do anything, so we can assume not moving to new line. if (lineCount != editor.TextDocument.LineCount) { if (offset <= editor.TextDocument.TextLength) { var newLine = editor.TextDocument.GetLineByOffset(offset); editor.CaretIndex = newLine.PreviousLine.EndOffset; } } else { editor.CaretIndex = offset; } break; } } }; editor.AddHandler(InputElement.KeyUpEvent, association.KeyUpHandler, RoutingStrategies.Tunnel); editor.TextInput += association.TextInputHandler; }
public CPlusPlusDataAssociation(TextDocument textDocument) { BackgroundRenderers = new List<IBackgroundRenderer>(); DocumentLineTransformers = new List<IDocumentLineTransformer>(); TextColorizer = new TextColoringTransformer(textDocument); TextMarkerService = new TextMarkerService(textDocument); BackgroundRenderers.Add(new BracketMatchingBackgroundRenderer()); BackgroundRenderers.Add(TextMarkerService); DocumentLineTransformers.Add(TextColorizer); DocumentLineTransformers.Add(new DefineTextLineTransformer()); DocumentLineTransformers.Add(new PragmaMarkTextLineTransformer()); DocumentLineTransformers.Add(new IncludeTextLineTransformer()); }
internal void Push(TextDocument document, DocumentChangeEventArgs e) { if (state == StatePlayback) throw new InvalidOperationException("Document changes during undo/redo operations are not allowed."); if (state == StatePlaybackModifyDocument) state = StatePlayback; // allow only 1 change per expected modification else Push(new DocumentChangeOperation(document, e)); }
public static ISegment GetTrailingWhitespace(TextDocument document, DocumentLine documentLine) { if (documentLine == null) throw new ArgumentNullException("documentLine"); var segment = GetWhitespaceBefore(document, documentLine.EndOffset); // If the whole line consists of whitespace, we consider all of it as leading whitespace, // so return an empty segment as trailing whitespace. if (segment.Offset == documentLine.Offset) return new SimpleSegment(documentLine.EndOffset, 0); return segment; }
public static int ApplyReplacements(TextDocument document, int cursor, XDocument replacements, bool replaceCursor = true) { var elements = replacements.Elements().First().Elements(); document.BeginUpdate(); var offsetChange = 0; foreach (var element in elements) { switch (element.Name.LocalName) { case "cursor": cursor = Convert.ToInt32(element.Value); break; case "replacement": var offset = -1; var replacementLength = -1; var attributes = element.Attributes(); foreach (var attribute in attributes) { switch (attribute.Name.LocalName) { case "offset": offset = Convert.ToInt32(attribute.Value); break; case "length": replacementLength = Convert.ToInt32(attribute.Value); break; } } document.Replace(offsetChange + offset, replacementLength, element.Value); offsetChange += element.Value.Length - replacementLength; break; } } document.EndUpdate(); return replaceCursor ? cursor : -1; }
private void OpenBracket(TextEditor.TextEditor editor, TextDocument document, string text) { if (text[0].IsOpenBracketChar() && editor.CaretIndex <= document.TextLength && editor.CaretIndex > 0) { var nextChar = ' '; if (editor.CaretIndex != document.TextLength) { document.GetCharAt(editor.CaretIndex); } if (char.IsWhiteSpace(nextChar) || nextChar.IsCloseBracketChar()) { document.Insert(editor.CaretIndex, text[0].GetCloseBracketChar().ToString()); } } }
public TextAnchorTree(TextDocument document) { this.document = document; }
public DocumentChangeOperation(TextDocument document, DocumentChangeEventArgs change) { this.document = document; this.change = change; }
public void OpenFile(ISourceFile file, IIntellisenseControl intellisense, ICompletionAssistant completionAssistant) { if (ProjectFile != file) { if (System.IO.File.Exists(file.Location)) { using (var fs = System.IO.File.OpenText(file.Location)) { TextDocument = new TextDocument(fs.ReadToEnd()); TextDocument.FileName = file.Location; } ProjectFile = file; RegisterLanguageService(intellisense, completionAssistant); DocumentLoaded?.Invoke(this, new EventArgs()); } } }
/// <summary> /// Does nothing: indenting multiple lines is useless without a smart indentation strategy. /// </summary> public virtual int IndentLines(TextDocument document, int beginLine, int endLine, int caretOffset) { return caretOffset; }
public int Comment(TextDocument textDocument, ISegment segment, int caret = -1, bool format = true) { var result = caret; var lines = VisualLineGeometryBuilder.GetLinesForSegmentInDocument(textDocument, segment); textDocument.BeginUpdate(); foreach (var line in lines) { textDocument.Insert(line.Offset, "//"); } if (format) { result = Format(textDocument, (uint)segment.Offset, (uint)segment.Length, caret); } textDocument.EndUpdate(); return result; }
public int UnComment(TextDocument textDocument, ISegment segment, int caret = -1, bool format = true) { var result = caret; var lines = VisualLineGeometryBuilder.GetLinesForSegmentInDocument(textDocument, segment); textDocument.BeginUpdate(); foreach (var line in lines) { var index = textDocument.GetText(line).IndexOf("//"); if (index >= 0) { textDocument.Replace(line.Offset + index, 2, string.Empty); } } if (format) { result = Format(textDocument, (uint)segment.Offset, (uint)segment.Length, caret); } textDocument.EndUpdate(); return result; }
internal TextAnchor(TextDocument document) { Document = document; }
private void CloseBracket(TextEditor.TextEditor editor, TextDocument document, string text) { if (text[0].IsCloseBracketChar() && editor.CaretIndex < document.TextLength && editor.CaretIndex > 0) { if (document.GetCharAt(editor.CaretIndex) == text[0]) { document.Replace(editor.CaretIndex - 1, 1, string.Empty); } } }
/// <summary> /// Deregisters the weak line tracker. /// </summary> public void Deregister() { if (textDocument != null) { textDocument.LineTrackers.Remove(this); textDocument = null; } }
public static ISegment GetLeadingWhitespace(TextDocument document, DocumentLine documentLine) { if (documentLine == null) throw new ArgumentNullException("documentLine"); return GetWhitespaceAfter(document, documentLine.Offset); }
/// <inheritdoc cref="IIndentationStrategy.IndentLines" /> public override int IndentLines(TextDocument document, int beginLine, int endLine, int caretOffset) { return Indent(new TextDocumentAccessor(document, beginLine, endLine), true, caretOffset); }
private WeakLineTracker(TextDocument textDocument, ILineTracker targetTracker) { this.textDocument = textDocument; targetObject = new WeakReference(targetTracker); }
internal void RegisterAffectedDocument(TextDocument document) { if (affectedDocuments == null) affectedDocuments = new List<TextDocument>(); if (!affectedDocuments.Contains(document)) { affectedDocuments.Add(document); document.BeginUpdate(); } }