Scintilla.NET

repository·master·Indexed 41 days ago

https://github.com/desjarlais/scintilla.net

A Windows Forms control and managed wrapper for the Scintilla source code editing component. It provides advanced text editing features including syntax highlighting, code completion, and error indicators, with a specific focus on correct Unicode character handling using character-based offsets and ranges. It can be integrated into WPF applications via WindowsFormsHost and is available as the Scintilla5.NET NuGet package.

Tokens
1.9K
Snippets
4
Records
9
Agent score
2%

What's inside Scintilla.NET

  1. Understand Scintilla.NET Unicode and Character Offsets

    master

    Unlike the native Scintilla control which operates on bytes, Scintilla.NET has been rewritten to treat Unicode as a first-class citizen.

    All APIs consistently use character-based offsets and ranges rather than byte offsets. The library internally manages the mapping between characters and byte offsets, preventing OutOfRangeException errors that typically occur when dealing with multi-byte Unicode characters in the native API.

  2. Iterate through Indicator ranges

    master

    To find all text ranges tagged with a specific indicator, use Indicator.Start(position) and Indicator.End(position).

    Important Logic Note: These methods can be counter-intuitive. Depending on whether the starting position is currently tagged with the indicator, they might return the start/end of a filled range or the start/end of an empty range.

    To reliably iterate only through filled ranges, combine these methods with Scintilla.IndicatorAllOnFor(position). This method returns a bitmap where each bit corresponds to an indicator index. You can check if a specific indicator is present by performing a bitwise AND with a flag created via (1 << indicator.Index).

    var textLength = scintilla.TextLength;
    var indicator = scintilla.Indicators[8];
    var bitmapFlag = (1 << indicator.Index);
    
    var startPos = 0;
    var endPos = 0;
    
    do
    {
        startPos = indicator.Start(endPos);
        endPos = indicator.End(startPos);
    
        // Check if the range is actually filled with our specific indicator
        var bitmap = scintilla.IndicatorAllOnFor(startPos);
        var filled = ((bitmapFlag & bitmap) == bitmapFlag);
        
        if (filled)
        {
            // Process the range
            Debug.WriteLine(scintilla.GetTextRange(startPos, (endPos - startPos)));
        }
    
    } while (endPos != 0 && endPos < textLength);
  3. How Scintilla.NET API mapping works

    master

    Scintilla.NET aims to remain consistent with the native Scintilla API to ensure native documentation remains relevant. It follows these mapping conventions:

    • Properties: Calls with both a 'get' and 'set' (e.g., SCI_GETTEXT and SCI_SETTEXT) are mapped to .NET properties (e.g., Text).
    • Indexers: Calls requiring a numeric argument to access an item (e.g., SCI_INDICSETFORE(indicatorNumber, ...)) are accessed via indexers (e.g., Indicators[0].ForeColor).
    • Line Management: Lines are not treated as a standard .NET collection. There are no Add, Insert, or Remove methods for lines specifically. Instead, line modifications are handled as text changes.
    • Value Clamping: Following native Scintilla behavior, many methods clamp input values to valid ranges instead of throwing exceptions. For example, GotoPosition(position) will clamp position to 0 or TextLength if the provided value is out of bounds.
  4. Use Scintilla.NET in WPF

    master

    While Scintilla.NET is a Windows Forms control, it can be integrated into WPF applications using the WindowsFormsHost component.

    <!-- Example of how you might host it in XAML -->
    <WindowsFormsHost>
        <scintilla:Scintilla />
    </WindowsFormsHost>
  5. Configure and apply Indicators

    master

    Indicators are used to overlay information (like syntax errors or warnings) on top of text styling using underlines or boxes.

    Configuration

    Indicators are managed via the Scintilla.Indicators collection, which supports up to 32 definitions (indexes 0-31). Warning: Indexes 0-7 are often reserved for lexers. It is best to use indexes 8-31 unless you are certain your lexer does not require the lower range.

    Common Indicator properties:

    • Style: Defines the appearance (e.g., IndicatorStyle.Squiggle).
    • ForeColor: The color of the indicator.
    • Alpha / OutlineAlpha: Transparency for box-style indicators.
    • Under: Determines if the indicator is drawn over or under the text.
    • HoverForeColor: Color used when the caret is in range or the mouse is over the text. (Note: Cannot be used simultaneously with HoverStyle).
    • HoverStyle: A style definition index from Scintilla.Styles used during hover. (Note: Cannot be used simultaneously with HoverForeColor).

    Application Workflow

    1. Define the indicator properties in Scintilla.Indicators[index].
    2. Set Scintilla.IndicatorCurrent to that index.
    3. Call Scintilla.IndicatorFillRange(start, length) to apply it to specific text ranges.
    4. Use Scintilla.IndicatorClearRange(start, length) to remove it.
    // Define an indicator
    scintilla.Indicators[8].Style = IndicatorStyle.Squiggle;
    scintilla.Indicators[8].ForeColor = Color.Red;
    
    // Get ready for fill
    scintilla.IndicatorCurrent = 8;
    
    // Fill ranges
    scintilla.IndicatorFillRange(2, 5);
    scintilla.IndicatorFillRange(25, 33);
  6. Install Scintilla.NET via NuGet

    master

    Scintilla.NET is a Windows Forms control and wrapper for the Scintilla source code editing component. To use it in your project, install the Scintilla5.NET package from NuGet.

    Note: For WPF applications, you can use this control by wrapping it in a WindowsFormsHost.

    # Search for 'Scintilla5.NET' in the NuGet Package Manager
  7. Handle Indicator events

    master

    You can respond to user interaction with indicated text using the following events:

    • IndicatorClick: Fired when a user clicks on text tagged with an indicator. Useful for showing context menus or spell-check suggestions.
    • IndicatorRelease: Fired when the user releases the mouse button over indicated text.
    • ChangeIndicator: Fired when an indicator is filled or cleared (though this is typically triggered by your own calls to IndicatorFillRange or IndicatorClearRange).
  8. Store arbitrary values with Indicators

    master

    Scintilla allows you to associate an arbitrary integer value with a range of text tagged with an indicator.

    1. Set the desired value using Scintilla.IndicatorValue (similar to how IndicatorCurrent sets the active index).
    2. Apply the range using Scintilla.IndicatorFillRange.
    3. Retrieve the stored integer for a specific position using Scintilla.IndicatorValueAt(position).
  9. Explore Scintilla.NET Utility Assemblies

    master

    Several specialized libraries are available to extend Scintilla.NET functionality:

    LibraryPurpose
    ScintillaLexersLexer definitions for Scintilla.NET
    VPKSoft.ScintillaUrlDetectURL detection within the control
    VPKSoft.ScintillaSpellCheckSpell checking functionality
    ScintillaDiffComparing two text files using the control
    ScintillaTabbedTextControlA tabbed interface for multiple documents
    ScintillaNetPrintingAdds printing capabilities
    AutoCompleteMenu-ScintillaNETFlexible autocomplete menus
    ScintillaNET-FindReplaceDialogFind/Replace dialog implementation