How can I highlight text in Scintilla?
Asked Answered
H

4

7

I am writing an editor using Scintilla.

I am already using a lexer to do automatic syntax highlighting but now I would like to mark search results. If I want to mark only one hit I can set the selection there, however, I would like to mark (e.g. with yellow background) all the hits.

I writing this in Perl but if you have suggestions in other languages that would be cool as well.

Hallucinate answered 18/9, 2008 at 13:34 Comment(0)
T
9

Have you read the Markers reference in Scintilla doc? This reference can be a bit obscure, so I advise to take a look at the source code of SciTE as well. This text editor was originally a testbed for Scintilla. It grown to a full fledged editor, but it is still a good implementation reference for all things Scintilla.

In our particular case, there is a Mark All button in the Find dialog. You can find its implementation in SciTEBase::MarkAll() method. This method only loops on search results (until it loops on the first search result, if any) and puts a bookmark on the found lines (and optionally set an indicator on the found items). The found line is gotten using SCI_LINEFROMPOSITION(posFound), the bookmark is just a call to SCI_MARKERADD(lineno, markerBookmark). Note that the mark can be symbol in a margin, or if not associated to a margin, it will highlight the whole line.

HTH.

Tartarus answered 18/9, 2008 at 13:59 Comment(0)
E
2

The "sample" editor scite uses the bookmark feature to bookmark all the lines that match the search result.

Eskill answered 18/9, 2008 at 13:48 Comment(0)
M
1

I used Indicators to highlight search results.

Marrufo answered 31/1, 2011 at 18:5 Comment(0)
F
1

This solution works in c#:

   private void HighlightWord(Scintilla scintilla, string text)
    {
        if (string.IsNullOrEmpty(text))
            return;

        // Indicators 0-7 could be in use by a lexer
        // so we'll use indicator 8 to highlight words.
        const int NUM = 8;

        // Remove all uses of our indicator
        scintilla.IndicatorCurrent = NUM;
        scintilla.IndicatorClearRange(0, scintilla.TextLength);

        // Update indicator appearance
        scintilla.Indicators[NUM].Style = IndicatorStyle.StraightBox;
        scintilla.Indicators[NUM].Under = true;
        scintilla.Indicators[NUM].ForeColor = Color.Green;
        scintilla.Indicators[NUM].OutlineAlpha = 50;
        scintilla.Indicators[NUM].Alpha = 30;

        // Search the document
        scintilla.TargetStart = 0;
        scintilla.TargetEnd = scintilla.TextLength;
        scintilla.SearchFlags = SearchFlags.None;
        while (scintilla.SearchInTarget(text) != -1)
        {
            // Mark the search results with the current indicator
            scintilla.IndicatorFillRange(scintilla.TargetStart, scintilla.TargetEnd - scintilla.TargetStart);

            // Search the remainder of the document
            scintilla.TargetStart = scintilla.TargetEnd;
            scintilla.TargetEnd = scintilla.TextLength;
        }
    }

Call is simple, in this example the words beginning with @ will be highlighted:

        Regex regex = new Regex(@"@\w+");
        string[] operands = regex.Split(txtScriptText.Text);
        Match match = regex.Match(txtScriptText.Text);

        if (match.Value.Length > 0)
            HighlightWord(txtScriptText, match.Value);
Flavoring answered 3/1, 2023 at 10:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.