### Install Folding Manager Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Installs the FoldingManager for text editor folding. Ensure the FoldingManager is installed before proceeding. ```csharp foldingManager = FoldingManager.Install(textEditor.TextArea); foldingStrategy = new XmlFoldingStrategy(); foldingStrategy.UpdateFoldings(foldingManager, textEditor.Document); ``` -------------------------------- ### Install and Configure Search Panel Source: https://context7.com/icsharpcode/avalonedit/llms.txt Installs the search panel, configures search options like pattern, case sensitivity, whole words, and regex, and customizes highlighting. Use this to add find and replace functionality to a TextEditor. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Search; var textEditor = new TextEditor(); textEditor.Text = "Hello World! Hello Universe! Hello Everyone!"; // Install search panel (adds Ctrl+F functionality) SearchPanel searchPanel = SearchPanel.Install(textEditor); // Configure search options searchPanel.SearchPattern = "Hello"; searchPanel.MatchCase = false; searchPanel.WholeWords = false; searchPanel.UseRegex = false; // Customize search result highlighting searchPanel.MarkerBrush = System.Windows.Media.Brushes.Yellow; searchPanel.MarkerCornerRadius = 2.0; // Open the search panel programmatically searchPanel.Open(); // Navigate through results searchPanel.FindNext(); searchPanel.FindPrevious(); // Close the panel searchPanel.Close(); // Register global keyboard shortcuts searchPanel.RegisterCommands(this.CommandBindings); // Subscribe to search options changes searchPanel.SearchOptionsChanged += (sender, e) => { Console.WriteLine($"Search pattern: {e.SearchPattern}"); Console.WriteLine($"Match case: {e.MatchCase}"); Console.WriteLine($"Use regex: {e.UseRegex}"); Console.WriteLine($"Whole words: {e.WholeWords}"); }; // Uninstall when done searchPanel.Uninstall(); ``` -------------------------------- ### FoldingManager Installation Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Installs and registers the necessary components for code folding functionality. This is a convenience method to set up folding automatically. ```csharp FoldingManager.Install(textView); ``` -------------------------------- ### Install and Use FoldingManager for Code Folding Source: https://context7.com/icsharpcode/avalonedit/llms.txt Install the FoldingManager on a TextEditor's TextArea to enable code folding. Use built-in strategies like XmlFoldingStrategy or create custom ones for brace-based languages. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Folding; using ICSharpCode.AvalonEdit.Document; using System.Collections.Generic; using System.Windows.Threading; var textEditor = new TextEditor(); textEditor.Text = " public class Example { public void Method1() { // Code here } public void Method2() { // More code } }"; // Install folding manager on the text area FoldingManager foldingManager = FoldingManager.Install(textEditor.TextArea); // Use built-in XML folding strategy var xmlFoldingStrategy = new XmlFoldingStrategy(); xmlFoldingStrategy.UpdateFoldings(foldingManager, textEditor.Document); // Create custom folding strategy for brace-based languages public class BraceFoldingStrategy { public char OpeningBrace { get; set; } = '{'; public char ClosingBrace { get; set; } = '}'; public void UpdateFoldings(FoldingManager manager, TextDocument document) { var newFoldings = CreateNewFoldings(document); manager.UpdateFoldings(newFoldings, firstErrorOffset: -1); } public IEnumerable CreateNewFoldings(TextDocument document) { var foldings = new List(); var startOffsets = new Stack(); int lastNewLineOffset = 0; for (int i = 0; i < document.TextLength; i++) { char c = document.GetCharAt(i); if (c == OpeningBrace) { startOffsets.Push(i); } else if (c == ClosingBrace && startOffsets.Count > 0) { int startOffset = startOffsets.Pop(); if (startOffset < lastNewLineOffset) { foldings.Add(new NewFolding(startOffset, i + 1)); } } else if (c == '\n' || c == '\r') { lastNewLineOffset = i + 1; } } foldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); return foldings; } } // Use the custom strategy var braceFoldingStrategy = new BraceFoldingStrategy(); braceFoldingStrategy.UpdateFoldings(foldingManager, textEditor.Document); // Set up automatic folding updates var foldingUpdateTimer = new DispatcherTimer(); foldingUpdateTimer.Interval = TimeSpan.FromSeconds(2); foldingUpdateTimer.Tick += (s, e) => braceFoldingStrategy.UpdateFoldings(foldingManager, textEditor.Document); foldingUpdateTimer.Start(); // Access individual foldings foreach (FoldingSection folding in foldingManager.AllFoldings) { Console.WriteLine($"Folding: {folding.StartOffset} - {folding.EndOffset}, Collapsed: {folding.IsFolded}"); // Collapse or expand folding.IsFolded = true; // Set custom title for collapsed display folding.Title = "{ ... }"; } // Uninstall when done FoldingManager.Uninstall(foldingManager); ``` -------------------------------- ### Get Description Property Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Retrieves a description string based on the Text property. This is a simple getter for a descriptive string. ```csharp public object Description { get { return "Description for " + this.Text; } } ``` -------------------------------- ### Initialize and Configure TextEditor Control Source: https://context7.com/icsharpcode/avalonedit/llms.txt Demonstrates how to create, configure, and manipulate a TextEditor instance in C#. Includes setting text content, line numbers, word wrap, read-only mode, and applying syntax highlighting. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Highlighting; // Create and configure a text editor in XAML or code var textEditor = new TextEditor(); // Set the text content textEditor.Text = "public class HelloWorld\n{\n static void Main()\n {\n Console.WriteLine(\"Hello, World!\");\n }\n}"; // Configure editor properties textEditor.ShowLineNumbers = true; textEditor.WordWrap = false; textEditor.IsReadOnly = false; // Apply syntax highlighting by name textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("C#"); // Or apply highlighting by file extension textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(".cs"); // Get or set caret position int caretOffset = textEditor.CaretOffset; textEditor.CaretOffset = 50; // Select text programmatically textEditor.Select(0, 10); // Select first 10 characters string selectedText = textEditor.SelectedText; // Scroll to a specific line textEditor.ScrollToLine(5); // Clear the document textEditor.Clear(); ``` -------------------------------- ### Show Simple Insight Window with Custom Content in C# Source: https://context7.com/icsharpcode/avalonedit/llms.txt Illustrates how to display a simple `InsightWindow` with custom content, such as a `TextBlock` containing parameter details. This is useful for displaying brief, static information to the user. ```csharp // Show simple insight window with custom content InsightWindow simpleInsight = new InsightWindow(textEditor.TextArea); simpleInsight.Content = new TextBlock { Text = "Parameter: int value - The value to process", TextWrapping = TextWrapping.Wrap }; simpleInsight.Show(); ``` -------------------------------- ### Create and Manipulate TextDocument Source: https://context7.com/icsharpcode/avalonedit/llms.txt Demonstrates creating a TextDocument, setting its text, and performing basic text manipulations like insertion, removal, and replacement. Also shows how to retrieve text properties and specific ranges. ```csharp using ICSharpCode.AvalonEdit.Document; // Create a new text document var document = new TextDocument(); document.Text = "Hello World"; // Or create with initial text var document2 = new TextDocument("Initial text content"); // Get text properties int length = document.TextLength; int lineCount = document.LineCount; string allText = document.Text; // Get specific text range string portion = document.GetText(0, 5); // "Hello" // Get character at offset char c = document.GetCharAt(0); // 'H' // Insert text at position document.Insert(5, " Beautiful"); // "Hello Beautiful World" // Remove text document.Remove(5, 10); // "Hello World" // Replace text document.Replace(6, 5, "Universe"); // "Hello Universe" ``` ```csharp using ICSharpCode.AvalonEdit.Document; // Get line information DocumentLine line = document.GetLineByNumber(1); // First line int lineOffset = line.Offset; int lineLength = line.Length; int totalLineLength = line.TotalLength; // Including line delimiter // Convert between offset and location TextLocation location = document.GetLocation(offset); // (line, column) int offset = document.GetOffset(line: 1, column: 1); int offset2 = document.GetOffset(new TextLocation(1, 1)); ``` ```csharp using ICSharpCode.AvalonEdit.Document; // Group multiple changes into a single undo operation using (document.RunUpdate()) { document.Insert(0, "// Header\n"); document.Insert(document.TextLength, "\n// Footer"); } // Or using BeginUpdate/EndUpdate document.BeginUpdate(); try { document.Insert(0, "Line 1\n"); document.Insert(document.TextLength, "Line 2\n"); } finally { document.EndUpdate(); } ``` ```csharp using ICSharpCode.AvalonEdit.Document; // Create immutable snapshot (thread-safe) ITextSource snapshot = document.CreateSnapshot(); string snapshotText = snapshot.Text; ``` ```csharp using ICSharpCode.AvalonEdit.Document; // Subscribe to change events document.Changed += (sender, e) => { Console.WriteLine($"Changed at offset {e.Offset}: removed '{e.RemovedText.Text}', inserted '{e.InsertedText.Text}'"); }; document.TextChanged += (sender, e) => { Console.WriteLine("Document text changed (after update group)"); }; ``` -------------------------------- ### Show Overload Insight Window in C# Source: https://context7.com/icsharpcode/avalonedit/llms.txt Demonstrates how to display an `OverloadInsightWindow` with a custom `MyOverloadProvider`. This window shows parameter information for method calls, similar to Visual Studio's parameter info. ```csharp // Show overload insight window OverloadInsightWindow insightWindow = new OverloadInsightWindow(textEditor.TextArea); insightWindow.Provider = new MyOverloadProvider(); insightWindow.Show(); ``` -------------------------------- ### Implement Custom Overload Provider for Insight Window in C# Source: https://context7.com/icsharpcode/avalonedit/llms.txt Defines a custom class `MyOverloadProvider` that implements `IOverloadProvider` to provide method signature information for the `OverloadInsightWindow`. It manages a list of signatures and exposes properties for the current selection, count, header, and content. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.CodeCompletion; using System.Windows.Controls; var textEditor = new TextEditor(); // Implement overload provider for method signatures public class MyOverloadProvider : IOverloadProvider { private readonly string[] signatures = new[] { "void Method(int value)", "void Method(int value, string text)", "void Method(int value, string text, bool flag)" }; private int selectedIndex; public int SelectedIndex { get => selectedIndex; set { selectedIndex = value; OnPropertyChanged(nameof(SelectedIndex)); OnPropertyChanged(nameof(CurrentHeader)); OnPropertyChanged(nameof(CurrentContent)); } } public int Count => signatures.Length; public string CurrentIndexText => $"{SelectedIndex + 1} of {Count}"; public object CurrentHeader => signatures[SelectedIndex]; public object CurrentContent => $"Parameter info for overload {SelectedIndex + 1}"; public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string name) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } } ``` -------------------------------- ### Configure TextEditor Options Source: https://context7.com/icsharpcode/avalonedit/llms.txt Customize indentation, display settings, word wrap, editing behavior, virtual space, and IME support. Subscribe to option changes to react to modifications. ```csharp using ICSharpCode.AvalonEdit; var textEditor = new TextEditor(); TextEditorOptions options = textEditor.Options; // Indentation settings options.IndentationSize = 4; options.ConvertTabsToSpaces = true; // Display settings options.ShowTabs = false; options.ShowSpaces = false; options.ShowEndOfLine = false; options.ShowBoxForControlCharacters = true; options.ShowColumnRuler = true; options.ColumnRulerPosition = 80; // Word wrap options.WordWrapIndentation = 0; options.InheritWordWrapIndentation = true; // Editing behavior options.CutCopyWholeLine = true; // Cut/copy entire line when nothing selected options.AllowScrollBelowDocument = true; options.EnableHyperlinks = true; options.EnableEmailHyperlinks = true; options.RequireControlModifierForHyperlinkClick = true; // Virtual space options.EnableVirtualSpace = false; options.EnableRectangularSelection = true; // IME and typing options.HideCursorWhileTyping = true; options.EnableImeSupport = true; // Subscribe to option changes textEditor.OptionChanged += (sender, e) => { Console.WriteLine($"Option changed: {e.PropertyName}"); }; ``` -------------------------------- ### Create and Use TextAnchor Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/document.html Demonstrates creating a TextAnchor at a specific offset, modifying the document, and then retrieving the anchor's new offset. Anchors adjust automatically to document changes. ```csharp TextAnchor anchor = document.CreateAnchor(offset); ChangeMyDocument(); int newOffset = anchor.Offset; ``` -------------------------------- ### Load and Register Custom Syntax Highlighting Source: https://context7.com/icsharpcode/avalonedit/llms.txt Load custom highlighting definitions from an XSHD file and register them with the HighlightingManager. This allows for custom language support. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting.Xshd; using System.Xml; using System.IO; var textEditor = new TextEditor(); // Get the global highlighting manager HighlightingManager manager = HighlightingManager.Instance; // List all available highlighting definitions foreach (var definition in manager.HighlightingDefinitions) { Console.WriteLine(definition.Name); } // Output: C#, VB, JavaScript, HTML, XML, CSS, PHP, Java, etc. // Get highlighting by name IHighlightingDefinition csharpHighlighting = manager.GetDefinition("C#"); textEditor.SyntaxHighlighting = csharpHighlighting; // Get highlighting by file extension IHighlightingDefinition jsHighlighting = manager.GetDefinitionByExtension(".js"); // Load custom highlighting from XSHD file IHighlightingDefinition customHighlighting; using (Stream stream = File.OpenRead("CustomLanguage.xshd")) using (XmlTextReader reader = new XmlTextReader(stream)) { customHighlighting = HighlightingLoader.Load(reader, manager); } // Register custom highlighting manager.RegisterHighlighting("CustomLanguage", new[] { ".custom", ".cst" }, customHighlighting); // Load highlighting from embedded resource using (Stream s = typeof(MyApp).Assembly.GetManifestResourceStream("MyApp.CustomHighlighting.xshd")) using (XmlReader reader = new XmlTextReader(s)) { var highlighting = HighlightingLoader.Load(reader, HighlightingManager.Instance); HighlightingManager.Instance.RegisterHighlighting("Custom", new[] { ".cool" }, highlighting); } // Access named colors from highlighting definition HighlightingColor commentColor = csharpHighlighting.GetNamedColor("Comment"); HighlightingColor stringColor = csharpHighlighting.GetNamedColor("String"); ``` -------------------------------- ### Initialize Code Completion Event Handlers Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Set up event handlers for text entering and text entered events in the AvalonEdit text area constructor to enable code completion functionality. ```csharp // in the constructor: textEditor.TextArea.TextEntering += textEditor_TextArea_TextEntering; textEditor.TextArea.TextEntered += textEditor_TextArea_TextEntered; ``` -------------------------------- ### Implement Custom Completion Data in C# Source: https://context7.com/icsharpcode/avalonedit/llms.txt Defines a custom class `MyCompletionData` that implements `ICompletionData` for code completion items. It allows setting text, description, and an optional image for each completion suggestion. The `Complete` method handles replacing the text in the editor when a suggestion is chosen. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.CodeCompletion; using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Editing; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; var textEditor = new TextEditor(); CompletionWindow completionWindow = null; // Implement custom completion data public class MyCompletionData : ICompletionData { public MyCompletionData(string text, string description = null, ImageSource image = null) { Text = text; Description = description ?? $"Description for {text}"; Image = image; } public ImageSource Image { get; } public string Text { get; } public object Content => Text; // Can be a UIElement for rich display public object Description { get; } // Shown in tooltip public double Priority => 0; // Higher priority items appear first public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) { // Replace the typed text with the completion textArea.Document.Replace(completionSegment, Text); } } ``` -------------------------------- ### Configure Completion Window Behavior in C# Source: https://context7.com/icsharpcode/avalonedit/llms.txt Configures the behavior of the `CompletionWindow`, setting `CloseAutomatically` to true and `CloseWhenCaretAtBeginning` to true for enhanced user experience. ```csharp // Configure completion window behavior completionWindow = new CompletionWindow(textEditor.TextArea); completionWindow.CloseAutomatically = true; completionWindow.CloseWhenCaretAtBeginning = true; ``` -------------------------------- ### Load and Save Files with TextEditor Source: https://context7.com/icsharpcode/avalonedit/llms.txt Shows how to load and save text content to and from files or streams using the TextEditor control. Covers automatic encoding detection and managing the modified state of the document. ```csharp using ICSharpCode.AvalonEdit; using System.IO; using System.Text; var textEditor = new TextEditor(); // Load a file (auto-detects encoding) textEditor.Load("C:\\path\\to\\file.cs"); // Save to a file using detected or specified encoding textEditor.Save("C:\\path\\to\\output.cs"); // Load from a stream using (FileStream fs = new FileStream("file.txt", FileMode.Open)) { textEditor.Load(fs); } // Save to a stream using (FileStream fs = new FileStream("output.txt", FileMode.Create)) { textEditor.Save(fs); } // Get or set the encoding used for saving textEditor.Encoding = Encoding.UTF8; // Check if the document has been modified bool isModified = textEditor.IsModified; // Clear the modified flag after saving textEditor.IsModified = false; ``` -------------------------------- ### Implement Current Line Highlighting Renderer in AvalonEdit Source: https://context7.com/icsharpcode/avalonedit/llms.txt Add a custom background renderer to highlight the current line where the caret is positioned. This requires implementing the IBackgroundRenderer interface and drawing a semi-transparent rectangle over the current line. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Rendering; using System.Windows; using System.Windows.Media; var textEditor = new TextEditor(); // Create renderer for current line highlighting public class CurrentLineHighlighter : IBackgroundRenderer { private TextEditor editor; public CurrentLineHighlighter(TextEditor editor) { this.editor = editor; } public KnownLayer Layer => KnownLayer.Background; public void Draw(TextView textView, DrawingContext drawingContext) { if (editor.Document == null) return; textView.EnsureVisualLines(); var currentLine = editor.Document.GetLineByOffset(editor.CaretOffset); foreach (var rect in BackgroundGeometryBuilder.GetRectsForSegment(textView, currentLine)) { drawingContext.DrawRectangle( new SolidColorBrush(Color.FromArgb(40, 0, 0, 255)), null, new Rect(rect.Location, new Size(textView.ActualWidth, rect.Height))); } } } // Add the renderer var highlighter = new CurrentLineHighlighter(textEditor); textEditor.TextArea.TextView.BackgroundRenderers.Add(highlighter); ``` -------------------------------- ### Create and Insert Code Snippets Source: https://context7.com/icsharpcode/avalonedit/llms.txt Demonstrates how to create and insert code snippets into a TextEditor. Snippets allow users to insert predefined code templates with editable placeholders and tab navigation. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Snippets; using ICSharpCode.AvalonEdit.Document; var textEditor = new TextEditor(); // Create a simple snippet var snippet = new Snippet { Elements = { new SnippetTextElement { Text = "for (int " }, new SnippetReplaceableTextElement { Text = "i" }, // Editable placeholder new SnippetTextElement { Text = " = 0; " }, new SnippetBoundElement { TargetElement = /* reference to "i" element */ }, new SnippetTextElement { Text = " < " }, new SnippetReplaceableTextElement { Text = "length" }, new SnippetTextElement { Text = "; " }, new SnippetBoundElement { TargetElement = /* reference to "i" element */ }, new SnippetTextElement { Text = "++)\n{\n\t" }, new SnippetCaretElement(), // Final caret position new SnippetTextElement { Text = "\n}" } } }; // Create a for-loop snippet with proper element references var iElement = new SnippetReplaceableTextElement { Text = "i" }; var lengthElement = new SnippetReplaceableTextElement { Text = "length" }; var forSnippet = new Snippet(); forSnippet.Elements.Add(new SnippetTextElement { Text = "for (int " }); forSnippet.Elements.Add(iElement); forSnippet.Elements.Add(new SnippetTextElement { Text = " = 0; " }); forSnippet.Elements.Add(new SnippetBoundElement { TargetElement = iElement }); forSnippet.Elements.Add(new SnippetTextElement { Text = " < " }); forSnippet.Elements.Add(lengthElement); forSnippet.Elements.Add(new SnippetTextElement { Text = "; " }); forSnippet.Elements.Add(new SnippetBoundElement { TargetElement = iElement }); forSnippet.Elements.Add(new SnippetTextElement { Text = "++)\n{\n\t" }); forSnippet.Elements.Add(new SnippetCaretElement()); forSnippet.Elements.Add(new SnippetTextElement { Text = "\n}" }); // Insert the snippet at the current caret position forSnippet.Insert(textEditor.TextArea); // User can now press Tab to move between "i" and "length" placeholders ``` -------------------------------- ### Implement Error Highlighting Renderer in AvalonEdit Source: https://context7.com/icsharpcode/avalonedit/llms.txt Create a custom background renderer to highlight specific lines with error markers. This involves maintaining a list of error line numbers and drawing a red rectangle with a border for each error line. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Rendering; using System.Windows; using System.Windows.Media; var textEditor = new TextEditor(); // Create renderer for error highlighting public class ErrorHighlighter : IBackgroundRenderer { public List ErrorLines { get; } public ErrorHighlighter() { ErrorLines = new List(); } public KnownLayer Layer => KnownLayer.Background; public void Draw(TextView textView, DrawingContext drawingContext) { foreach (int lineNumber in ErrorLines) { var line = textView.Document.GetLineByNumber(lineNumber); foreach (var rect in BackgroundGeometryBuilder.GetRectsForSegment(textView, line)) { drawingContext.DrawRectangle( new SolidColorBrush(Color.FromArgb(50, 255, 0, 0)), new Pen(Brushes.Red, 1), rect); } } } } // Add error highlighting var errorHighlighter = new ErrorHighlighter(); errorHighlighter.ErrorLines.Add(5); errorHighlighter.ErrorLines.Add(12); textEditor.TextArea.TextView.BackgroundRenderers.Add(errorHighlighter); // Refresh the view to show changes textEditor.TextArea.TextView.InvalidateLayer(KnownLayer.Background); ``` -------------------------------- ### Implement Undo/Redo Operations Source: https://context7.com/icsharpcode/avalonedit/llms.txt Details how to utilize the UndoStack for undo and redo functionality in AvalonEdit. Covers checking availability, performing actions, accessing the stack directly, and grouping changes. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Document; var textEditor = new TextEditor(); textEditor.Text = "Original text"; // Perform edits textEditor.TextArea.Document.Replace(0, 8, "Modified"); // Check if undo/redo is available bool canUndo = textEditor.CanUndo; bool canRedo = textEditor.CanRedo; // Perform undo if (textEditor.CanUndo) { textEditor.Undo(); // Returns true if successful } // Perform redo if (textEditor.CanRedo) { textEditor.Redo(); // Returns true if successful } ``` ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Document; var textEditor = new TextEditor(); // ... edits ... // Access the undo stack directly UndoStack undoStack = textEditor.Document.UndoStack; // Clear all undo/redo history undoStack.ClearAll(); // Mark current state as "original" (for IsModified tracking) undoStack.MarkAsOriginalFile(); // Check if document is at original state bool isOriginal = undoStack.IsOriginalFile; // Set undo limit undoStack.SizeLimit = 100; // Maximum number of undo steps ``` ```csharp using ICSharpCode.AvalonEdit; // Group operations into a single undo step using (textEditor.DeclareChangeBlock()) { textEditor.Document.Insert(0, "Line 1\n"); textEditor.Document.Insert(textEditor.Document.TextLength, "\nLine 2"); } // Both insertions are now undone with a single Ctrl+Z ``` -------------------------------- ### Basic Text Editor Usage in WPF Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Instantiate the AvalonEdit TextEditor control in XAML. Set properties like FontFamily and FontSize as needed. ```XAML ``` -------------------------------- ### Implement TextEntered for Code Completion Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Handle the TextEntered event to trigger the display of the code completion window when a specific character, like '.', is typed. This involves creating a CompletionWindow and populating its data. ```csharp CompletionWindow completionWindow; void textEditor_TextArea_TextEntered(object sender, TextCompositionEventArgs e) { if (e.Text == ".") { // Open code completion after the user has pressed dot: completionWindow = new CompletionWindow(textEditor.TextArea); IList data = completionWindow.CompletionList.CompletionData; data.Add(new MyCompletionData("Item1")); data.Add(new MyCompletionData("Item2")); data.Add(new MyCompletionData("Item3")); completionWindow.Show(); completionWindow.Closed += delegate { completionWindow = null; }; } } ``` -------------------------------- ### TextView Rendering Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html The TextView class is responsible for rendering the document's content to the screen. It utilizes VisualLines for efficient rendering of visible portions and offers extensibility through element generators, line transformers, and background renderers. ```APIDOC ## TextView Rendering ### Description Handles the rendering of the text document onto the screen using a pipeline of visual elements. ### Core Concepts - **VisualLine**: Represents a visible portion of the document, optimized for rendering. - **Rendering Pipeline**: A series of steps including element generation, line transformation, and background rendering before final WPF text rendering. ### Extensibility Points - **Element Generators**: Used to add custom elements to visual lines. - **Line Transformers**: Allow modification of visual lines before rendering. - **Background Renderers**: Enable custom drawing in the background of the text view. ``` -------------------------------- ### C# Syntax Highlighting Definition Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Defines syntax highlighting rules for a subset of C# using an XSHD file. This includes colors for comments, strings, keywords, and numbers. ```xml " " if else \b0\[xX\]\[0-9a-fA-F\]+ # hex number | \b ( \d+(\. \[0-9\]+)? #number with optional floating point | \. \[0-9\]+ #or just starting with floating point ) (\[eE\]\[+-\]?\[0-9\]+)? # optional exponent ``` -------------------------------- ### MyCompletionData Class Implementation Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Provides a basic implementation of the ICompletionData interface for custom items displayed in the AvalonEdit code completion dropdown. It sets the text and content for each completion item. ```csharp /// Implements AvalonEdit ICompletionData interface to provide the entries in the /// completion drop down. public class MyCompletionData : ICompletionData { public MyCompletionData(string text) { this.Text = text; } public System.Windows.Media.ImageSource Image { get { return null; } } public string Text { get; private set; } // Use this property if you want to show a fancy UIElement in the list. public object Content { get { return this.Text; } } } ``` -------------------------------- ### Implement TextEntering for Completion Window Interaction Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Handle the TextEntering event to manage interactions with the code completion window. This allows inserting the selected item when a non-letter character is typed while the window is open. ```csharp void textEditor_TextArea_TextEntering(object sender, TextCompositionEventArgs e) { if (e.Text.Length > 0 && completionWindow != null) { if (!char.IsLetterOrDigit(e.Text[0])) { // Whenever a non-letter is typed while the completion window is open, // insert the currently selected element. completionWindow.CompletionList.RequestInsertion(e); } } // Do not set e.Handled=true. // We still want to insert the character that was typed. } ``` -------------------------------- ### Handle Text Entering for Completion Insertion in C# Source: https://context7.com/icsharpcode/avalonedit/llms.txt Attaches an event handler to the `TextEntering` event to manage the insertion of selected completion items. If the input character is not alphanumeric and a `completionWindow` is active, it requests the insertion of the selected item. ```csharp // Handle text entering to insert selected completion on certain characters textEditor.TextArea.TextEntering += (sender, e) => { if (e.Text.Length > 0 && completionWindow != null) { if (!char.IsLetterOrDigit(e.Text[0])) { // Insert the currently selected element on non-alphanumeric input completionWindow.CompletionList.RequestInsertion(e); } } }; ``` -------------------------------- ### Manage TextArea Caret and Selection Source: https://context7.com/icsharpcode/avalonedit/llms.txt Control caret position, selection bounds, and handle text input events. Subscribe to caret and selection changes for real-time updates. Customize selection appearance. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Document; using System.Windows.Media; var textEditor = new TextEditor(); TextArea textArea = textEditor.TextArea; // Access the caret Caret caret = textArea.Caret; // Get/set caret position int offset = caret.Offset; caret.Offset = 100; // Get/set position as line/column TextLocation location = caret.Location; caret.Location = new TextLocation(5, 10); // Line 5, Column 10 // Individual line and column access int line = caret.Line; int column = caret.Column; caret.Line = 3; caret.Column = 1; // Make caret visible caret.BringCaretToView(); // Subscribe to caret movement caret.PositionChanged += (sender, e) => { Console.WriteLine($"Caret moved to line {caret.Line}, column {caret.Column}"); }; // Selection handling Selection selection = textArea.Selection; // Check if there's a selection bool hasSelection = !selection.IsEmpty; // Get selection bounds if (!selection.IsEmpty) { ISegment segment = selection.SurroundingSegment; int start = segment.Offset; int length = segment.Length; string selectedText = textArea.Document.GetText(segment); } // Create selection programmatically textArea.Selection = Selection.Create(textArea, startOffset: 10, endOffset: 50); // Clear selection textArea.ClearSelection(); // Subscribe to selection changes textArea.SelectionChanged += (sender, e) => { if (!textArea.Selection.IsEmpty) { Console.WriteLine($"Selected: {textArea.Selection.GetText()}"); } }; // Customize selection appearance textArea.SelectionBrush = new SolidColorBrush(Color.FromArgb(100, 51, 153, 255)); textArea.SelectionForeground = Brushes.White; textArea.SelectionCornerRadius = 3; // Handle text input extArea.TextEntering += (sender, e) => { // Called before text is inserted - can cancel with e.Handled = true if (e.Text == "\t") { // Custom tab handling e.Handled = true; textArea.Document.Insert(caret.Offset, " "); } }; textArea.TextEntered += (sender, e) => { // Called after text is inserted Console.WriteLine($"Entered: {e.Text}"); }; ``` -------------------------------- ### Enable Syntax Highlighting in AvalonEdit Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Assign a syntax highlighting definition to the SyntaxHighlighting property of the TextEditor. Highlighting definitions are managed by HighlightingManager. ```C# textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("C#"); ``` -------------------------------- ### Handle Text Entered for Code Completion in C# Source: https://context7.com/icsharpcode/avalonedit/llms.txt Attaches an event handler to the `TextEntered` event of the `TextArea` to trigger code completion. When a '.' is entered, it creates and shows a `CompletionWindow` populated with custom completion data. It also sets up a handler for the `Closed` event to clean up the `completionWindow` reference. ```csharp // Handle text entered event to show completion textEditor.TextArea.TextEntered += (sender, e) => { if (e.Text == ".") { // Create completion window completionWindow = new CompletionWindow(textEditor.TextArea); completionWindow.Width = 300; completionWindow.MaxHeight = 400; // Add completion items IList data = completionWindow.CompletionList.CompletionData; data.Add(new MyCompletionData("ToString", "Converts the object to its string representation")); data.Add(new MyCompletionData("GetHashCode", "Returns a hash code for this instance")); data.Add(new MyCompletionData("Equals", "Determines whether the specified object is equal")); data.Add(new MyCompletionData("GetType", "Gets the Type of the current instance")); // Show the window completionWindow.Show(); // Clean up when closed completionWindow.Closed += (s, args) => completionWindow = null; } }; ``` -------------------------------- ### Complete Method for Text Insertion Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Inserts text into a TextArea at a specified segment. The `Complete` method can be customized with custom logic and uses event arguments to determine the insertion type. ```csharp public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) { textArea.Document.Replace(completionSegment, this.Text); } ``` -------------------------------- ### Implement Custom Breakpoint Margin in AvalonEdit Source: https://context7.com/icsharpcode/avalonedit/llms.txt Create a custom margin to display breakpoints in the left area of the text editor. This involves handling mouse clicks to toggle breakpoints and overriding the OnRender method to draw breakpoint indicators. ```csharp using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Rendering; using System.Windows; using System.Windows.Media; var textEditor = new TextEditor(); // Create custom margin for breakpoints public class BreakpointMargin : AbstractMargin { private HashSet breakpoints = new HashSet(); protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) { return new PointHitTestResult(this, hitTestParameters.HitPoint); } protected override void OnMouseDown(MouseButtonEventArgs e) { base.OnMouseDown(e); var pos = e.GetPosition(this); var textView = this.TextView; if (textView != null) { var line = textView.GetVisualLineFromVisualTop(pos.Y + textView.ScrollOffset.Y); if (line != null) { int lineNumber = line.FirstDocumentLine.LineNumber; if (breakpoints.Contains(lineNumber)) breakpoints.Remove(lineNumber); else breakpoints.Add(lineNumber); InvalidateVisual(); } } } protected override void OnRender(DrawingContext drawingContext) { var textView = this.TextView; if (textView == null || !textView.VisualLinesValid) return; foreach (var line in textView.VisualLines) { int lineNumber = line.FirstDocumentLine.LineNumber; if (breakpoints.Contains(lineNumber)) { double y = line.VisualTop - textView.ScrollOffset.Y; drawingContext.DrawEllipse(Brushes.Red, null, new Point(10, y + line.Height / 2), 6, 6); } } } protected override Size MeasureOverride(Size availableSize) { return new Size(20, 0); } } // Add the margin var breakpointMargin = new BreakpointMargin(); textEditor.TextArea.LeftMargins.Insert(0, breakpointMargin); // Remove margin when done textEditor.TextArea.LeftMargins.Remove(breakpointMargin); ``` -------------------------------- ### Manage Text Positions with Text Anchors Source: https://context7.com/icsharpcode/avalonedit/llms.txt Shows how to create and use TextAnchors to track positions within a TextDocument. Anchors automatically update their offset when text is inserted or removed, and can notify on deletion. ```csharp using ICSharpCode.AvalonEdit.Document; var document = new TextDocument("Hello World"); // Create an anchor at offset 6 (start of "World") TextAnchor anchor = document.CreateAnchor(6); // Configure movement behavior anchor.MovementType = AnchorMovementType.Default; // Moves after insertions at its position // Or: AnchorMovementType.BeforeInsertion - stays before insertions at its position // Get current position (updates automatically) int currentOffset = anchor.Offset; // 6 // Insert text before the anchor document.Insert(0, "Say "); // Document is now "Say Hello World" // Anchor position is automatically updated Console.WriteLine(anchor.Offset); // 10 (6 + 4 chars inserted) // Subscribe to deletion events anchor.Deleted += (sender, e) => { Console.WriteLine("Anchor position was deleted"); }; // Check if anchor is still valid bool isDeleted = anchor.IsDeleted; ``` -------------------------------- ### Implement Image Embedding in AvalonEdit Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/rendering.html This class extends `VisualLineElementGenerator` to embed images into the text document based on a regex pattern. It requires a base path for image resolution and handles loading and displaying images. ```csharp public class ImageElementGenerator : VisualLineElementGenerator { readonly static Regex imageRegex = new Regex(@"", RegexOptions.IgnoreCase); readonly string basePath; public ImageElementGenerator(string basePath) { if (basePath == null) throw new ArgumentNullException("basePath"); this.basePath = basePath; } Match FindMatch(int startOffset) { // fetch the end offset of the VisualLine being generated int endOffset = CurrentContext.VisualLine.LastDocumentLine.EndOffset; TextDocument document = CurrentContext.Document; string relevantText = document.GetText(startOffset, endOffset - startOffset); return imageRegex.Match(relevantText); } /// 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); return m.Success ? (startOffset + m.Index) : -1; } /// Constructs an element at the specified offset. /// May return null if no element should be constructed. public override VisualLineElement ConstructElement(int offset) { Match m = FindMatch(offset); // check whether there's a match exactly at offset if (m.Success && m.Index == 0) { BitmapImage bitmap = LoadBitmap(m.Groups[1].Value); if (bitmap != null) { Image image = new Image(); image.Source = bitmap; image.Width = bitmap.PixelWidth; image.Height = bitmap.PixelHeight; // Pass the length of the match to the 'documentLength' parameter // of InlineObjectElement. return new InlineObjectElement(m.Length, image); } } return null; } BitmapImage LoadBitmap(string fileName) { // TODO: add some kind of cache to avoid reloading the image whenever the // VisualLine is reconstructed try { string fullFileName = Path.Combine(basePath, fileName); if (File.Exists(fullFileName)) { BitmapImage bitmap = new BitmapImage(new Uri(fullFileName)); bitmap.Freeze(); return bitmap; } } catch (ArgumentException) { // invalid filename syntax } catch (IOException) { // other IO error } return null; } } ``` -------------------------------- ### Folding API Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Implements code folding (collapsing sections of text) as an extension to the editor. It involves VisualLineElementGenerator for collapsed sections and a custom margin for fold controls. ```APIDOC ## Folding API ### Description Provides functionality for code folding (collapsing and expanding text sections) within the editor. ### Key Components - **VisualLineElementGenerator**: Responsible for generating elements representing collapsed sections. - **Custom Margin**: Draws the fold controls (plus/minus buttons). ### Usage - **FoldingManager.Install**: A static method to automatically set up the necessary components for folding. - **FoldingManager.UpdateFoldings**: Call this method regularly with the desired foldings to update the folding state. - **Folding Strategies**: Can be used to automatically calculate the list of foldings. ``` -------------------------------- ### Update Foldings Regularly Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html To ensure folding markers update dynamically as text changes, the UpdateFoldings method must be called periodically. This is crucial for maintaining an accurate folding state. ```csharp foldingStrategy.UpdateFoldings(foldingManager, textEditor.Document); ``` -------------------------------- ### Highlight 'AvalonEdit' with Bold Font Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/rendering.html This DocumentColorizingTransformer highlights occurrences of 'AvalonEdit' in a document line by applying a bold italic typeface. Ensure the 'AvalonEdit' library is referenced. ```csharp public class ColorizeAvalonEdit : DocumentColorizingTransformer { protected override void ColorizeLine(DocumentLine line) { int lineStartOffset = line.Offset; string text = CurrentContext.Document.GetText(line); int start = 0; int index; while ((index = text.IndexOf("AvalonEdit", start)) >= 0) { base.ChangeLinePart( lineStartOffset + index, // startOffset lineStartOffset + index + 10, // endOffset (VisualLineElement element) => { // This lambda gets called once for every VisualLineElement // between the specified offsets. Typeface tf = element.TextRunProperties.Typeface; // Replace the typeface with a modified version of // the same typeface element.TextRunProperties.SetTypeface(new Typeface( tf.FontFamily, FontStyles.Italic, FontWeights.Bold, tf.Stretch )); }); start = index + 1; // search for next occurrence } } } ``` -------------------------------- ### TextArea Input Handling Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html The TextArea class manages user input and editing operations within the text editor. It controls the caret and selection, and allows customization of input handling and the addition of custom margins. ```APIDOC ## TextArea Input Handling ### Description Manages user input, caret, selection, and provides extensibility for custom input modes and UI elements. ### Customization - **DefaultInputHandler**: Modify or replace the default input handler to customize key bindings and input behavior. - **ActiveInputHandler**: Set to switch the text area into different input modes (e.g., incremental search, VI emulation). - **LeftMargins**: Add custom UI elements (margins) to the left of the text view. ### Margin Implementation - **AbstractMargin**: A base class providing utility code for creating custom margins. - Any `UIElement` can be used as a margin. ``` -------------------------------- ### FoldingManager Update Source: https://github.com/icsharpcode/avalonedit/blob/master/ICSharpCode.AvalonEdit.Sample/article.html Updates the foldings in the document based on a provided list of foldings. This method should be called regularly to reflect desired folding states. ```csharp FoldingManager.UpdateFoldings(foldings); ```