public HeightTree(TextDocument document, double defaultLineHeight) { this.document = document; weakLineTracker = WeakLineTracker.Register(document, this); this.DefaultLineHeight = defaultLineHeight; RebuildDocument(); }
internal DocumentLine(TextDocument document) { #if DEBUG Debug.Assert(document != null); this.document = document; #endif }
/// <summary> /// Create <see cref="NewFolding"/>s for the specified document. /// </summary> public IEnumerable<NewFolding> CreateNewFoldings(TextDocument document, XmlReader reader, out int firstErrorOffset) { Stack<XmlFoldStart> stack = new Stack<XmlFoldStart>(); List<NewFolding> foldMarkers = new List<NewFolding>(); try { while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: if (!reader.IsEmptyElement) { XmlFoldStart newFoldStart = CreateElementFoldStart(document, reader); stack.Push(newFoldStart); } break; case XmlNodeType.EndElement: XmlFoldStart foldStart = stack.Pop(); CreateElementFold(document, foldMarkers, reader, foldStart); break; case XmlNodeType.Comment: CreateCommentFold(document, foldMarkers, reader); break; } } firstErrorOffset = -1; } catch (XmlException ex) { // ignore errors at invalid positions (prevent ArgumentOutOfRangeException) if (ex.LineNumber >= 1 && ex.LineNumber <= document.LineCount) firstErrorOffset = document.GetOffset(ex.LineNumber, ex.LinePosition); else firstErrorOffset = 0; } foldMarkers.Sort((a,b) => a.StartOffset.CompareTo(b.StartOffset)); return foldMarkers; }
/// <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> /// Deregisters the weak line tracker. /// </summary> public void Deregister() { if (textDocument != null) { textDocument.LineTrackers.Remove(this); textDocument = null; } }
/// <summary> /// Creates a new TextDocumentAccessor. /// </summary> public TextDocumentAccessor(TextDocument document) { if (document == null) throw new ArgumentNullException("document"); doc = document; this.minLine = 1; this.maxLine = doc.LineCount; }
/// <summary> /// Creates a new FoldingManager instance. /// </summary> public FoldingManager(TextDocument document) { if (document == null) throw new ArgumentNullException("document"); this.document = document; this.foldings = new TextSegmentCollection<FoldingSection>(); document.VerifyAccess(); TextDocumentWeakEventManager.Changed.AddListener(document, this); }
/// <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"); WeakLineTracker wlt = new WeakLineTracker(textDocument, targetTracker); textDocument.LineTrackers.Add(wlt); return wlt; }
/// <summary> /// Create <see cref="NewFolding"/>s for the specified document. /// </summary> public override IEnumerable<NewFolding> CreateNewFoldings(TextDocument document, out int firstErrorOffset) { try { XmlTextReader reader = new XmlTextReader(document.CreateReader()); reader.XmlResolver = null; // don't resolve DTDs return CreateNewFoldings(document, reader, out firstErrorOffset); } catch (XmlException) { firstErrorOffset = 0; return Enumerable.Empty<NewFolding>(); } }
/// <summary> /// Creates a new DocumentHighlighter instance. /// </summary> public DocumentHighlighter(TextDocument document, HighlightingRuleSet baseRuleSet) { if (document == null) throw new ArgumentNullException("document"); if (baseRuleSet == null) throw new ArgumentNullException("baseRuleSet"); this.document = document; this.baseRuleSet = baseRuleSet; WeakLineTracker.Register(document, this); InvalidateHighlighting(); }
/// <inheritdoc/> protected override void OnDocumentChanged(TextDocument oldDocument, TextDocument newDocument) { if (oldDocument != null) { PropertyChangedEventManager.RemoveListener(oldDocument, this, "LineCount"); } base.OnDocumentChanged(oldDocument, newDocument); if (newDocument != null) { PropertyChangedEventManager.AddListener(newDocument, this, "LineCount"); } OnDocumentLineCountChanged(); }
/// <inheritdoc cref="IIndentationStrategy.IndentLine"/> public override void IndentLine(TextDocument document, DocumentLine line) { int lineNr = line.LineNumber; TextDocumentAccessor acc = new TextDocumentAccessor(document, lineNr, lineNr); Indent(acc, false); string t = acc.Text; if (t.Length == 0) { // use AutoIndentation for new lines in comments / verbatim strings. base.IndentLine(document, line); } }
/// <inheritdoc/> public virtual void IndentLine(TextDocument document, DocumentLine line) { if (document == null) throw new ArgumentNullException("document"); if (line == null) throw new ArgumentNullException("line"); DocumentLine previousLine = line.PreviousLine; if (previousLine != null) { ISegment indentationSegment = TextUtilities.GetWhitespaceAfter(document, previousLine.Offset); string indentation = document.GetText(indentationSegment); // copy indentation to line indentationSegment = TextUtilities.GetWhitespaceAfter(document, line.Offset); document.Replace(indentationSegment, indentation); } }
/// <inheritdoc cref="IIndentationStrategy.IndentLines"/> public override void IndentLines(TextDocument document, int beginLine, int endLine) { Indent(new TextDocumentAccessor(document, beginLine, endLine), true); }
/// <summary> /// Gets the newline sequence used in the document at the specified line. /// </summary> public static string GetNewLineFromDocument(TextDocument document, int lineNumber) { DocumentLine line = document.GetLineByNumber(lineNumber); if (line.DelimiterLength == 0) { // at the end of the document, there's no line delimiter, so use the delimiter // from the previous line line = line.PreviousLine; if (line == null) return Environment.NewLine; } return document.GetText(line.Offset + line.Length, line.DelimiterLength); }
void OnDocumentChanged(TextDocument oldValue, TextDocument newValue) { if (oldValue != null) { TextDocumentWeakEventManager.Changing.RemoveListener(oldValue, this); TextDocumentWeakEventManager.Changed.RemoveListener(oldValue, this); TextDocumentWeakEventManager.UpdateStarted.RemoveListener(oldValue, this); TextDocumentWeakEventManager.UpdateFinished.RemoveListener(oldValue, this); } textView.Document = newValue; if (newValue != null) { TextDocumentWeakEventManager.Changing.AddListener(newValue, this); TextDocumentWeakEventManager.Changed.AddListener(newValue, this); TextDocumentWeakEventManager.UpdateStarted.AddListener(newValue, this); TextDocumentWeakEventManager.UpdateFinished.AddListener(newValue, this); } // Reset caret location and selection: this is necessary because the caret/selection might be invalid // in the new document (e.g. if new document is shorter than the old document). caret.Location = new TextLocation(1, 1); this.ClearSelection(); if (DocumentChanged != null) DocumentChanged(this, EventArgs.Empty); CommandManager.InvalidateRequerySuggested(); }
static int GetOffset(TextDocument document, XmlReader reader) { IXmlLineInfo info = reader as IXmlLineInfo; if (info != null && info.HasLineInfo()) { return document.GetOffset(info.LineNumber, info.LinePosition); } else { throw new ArgumentException("XmlReader does not have positioning information."); } }
void textArea_DocumentChanged(object sender, EventArgs e) { if (currentDocument != null) currentDocument.TextChanged -= textArea_Document_TextChanged; currentDocument = textArea.Document; if (currentDocument != null) { currentDocument.TextChanged += textArea_Document_TextChanged; DoSearch(false); } }
public DocumentChangeOperation(TextDocument document, DocumentChangeEventArgs change) { this.document = document; this.change = change; }
/// <summary> /// Creates the IHighlighter instance for the specified text document. /// </summary> protected virtual IHighlighter CreateHighlighter(TextView textView, TextDocument document) { return new TextViewDocumentHighlighter(this, textView, document, ruleSet); }
/// <summary> /// Creates an XmlFoldStart for the start tag of an element. /// </summary> XmlFoldStart CreateElementFoldStart(TextDocument document, XmlReader reader) { // Take off 1 from the offset returned // from the xml since it points to the start // of the element name and not the beginning // tag. //XmlFoldStart newFoldStart = new XmlFoldStart(reader.Prefix, reader.LocalName, reader.LineNumber - 1, reader.LinePosition - 2); XmlFoldStart newFoldStart = new XmlFoldStart(); IXmlLineInfo lineInfo = (IXmlLineInfo)reader; newFoldStart.StartLine = lineInfo.LineNumber; newFoldStart.StartOffset = document.GetOffset(newFoldStart.StartLine, lineInfo.LinePosition - 1); if (this.ShowAttributesWhenFolded && reader.HasAttributes) { newFoldStart.Name = String.Concat("<", reader.Name, " ", GetAttributeFoldText(reader), ">"); } else { newFoldStart.Name = String.Concat("<", reader.Name, ">"); } return newFoldStart; }
private WeakLineTracker(TextDocument textDocument, ILineTracker targetTracker) { this.textDocument = textDocument; this.targetObject = new WeakReference(targetTracker); }
/// <summary> /// Creates a comment fold if the comment spans more than one line. /// </summary> /// <remarks>The text displayed when the comment is folded is the first /// line of the comment.</remarks> static void CreateCommentFold(TextDocument document, List<NewFolding> foldMarkers, XmlReader reader) { string comment = reader.Value; if (comment != null) { int firstNewLine = comment.IndexOf('\n'); if (firstNewLine >= 0) { // Take off 4 chars to get the actual comment start (takes // into account the <!-- chars. int startOffset = GetOffset(document, reader) - 4; int endOffset = startOffset + comment.Length + 7; string foldText = String.Concat("<!--", comment.Substring(0, firstNewLine).TrimEnd('\r') , "-->"); foldMarkers.Add(new NewFolding(startOffset, endOffset) { Name = foldText } ); } } }
/// <summary> /// Does nothing: indenting multiple lines is useless without a smart indentation strategy. /// </summary> public virtual void IndentLines(TextDocument document, int beginLine, int endLine) { }
public TextViewDocumentHighlighter(HighlightingColorizer colorizer, TextView textView, TextDocument document, HighlightingRuleSet baseRuleSet) : base(document, baseRuleSet) { Debug.Assert(colorizer != null); Debug.Assert(textView != null); this.colorizer = colorizer; this.textView = textView; }
/// <summary> /// Called when the <see cref="Document"/> is changing. /// </summary> protected virtual void OnDocumentChanged(TextDocument oldDocument, TextDocument newDocument) { document = newDocument; }
/// <summary> /// Attaches this SearchPanel to a TextArea instance. /// </summary> public void Attach(TextArea textArea) { if (textArea == null) throw new ArgumentNullException("textArea"); this.textArea = textArea; adorner = new SearchPanelAdorner(textArea, this); DataContext = this; renderer = new SearchResultBackgroundRenderer(); currentDocument = textArea.Document; if (currentDocument != null) currentDocument.TextChanged += textArea_Document_TextChanged; textArea.DocumentChanged += textArea_DocumentChanged; KeyDown += SearchLayerKeyDown; this.CommandBindings.Add(new CommandBinding(SearchCommands.FindNext, (sender, e) => FindNext())); this.CommandBindings.Add(new CommandBinding(SearchCommands.FindPrevious, (sender, e) => FindPrevious())); this.CommandBindings.Add(new CommandBinding(SearchCommands.CloseSearchPanel, (sender, e) => Close())); IsClosed = true; }
public FoldingManager(TextView textView, TextDocument document) : this(document) { }
/// <summary> /// Creates a change tracking checkpoint for the specified document. /// This method is thread-safe. /// If you need a ChangeTrackingCheckpoint that's consistent with a snapshot of the document, /// use <see cref="TextDocument.CreateSnapshot(out ChangeTrackingCheckpoint)"/>. /// </summary> public static ChangeTrackingCheckpoint Create(TextDocument document) { if (document == null) throw new ArgumentNullException("document"); return document.CreateChangeTrackingCheckpoint(); }
/// <summary> /// Create an element fold if the start and end tag are on /// different lines. /// </summary> static void CreateElementFold(TextDocument document, List<NewFolding> foldMarkers, XmlReader reader, XmlFoldStart foldStart) { IXmlLineInfo lineInfo = (IXmlLineInfo)reader; int endLine = lineInfo.LineNumber; if (endLine > foldStart.StartLine) { int endCol = lineInfo.LinePosition + reader.Name.Length + 1; foldStart.EndOffset = document.GetOffset(endLine, endCol); foldMarkers.Add(foldStart); } }