Reputation: 6302
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.
Upvotes: 7
Views: 8807
Reputation: 11
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);
Upvotes: 1
Reputation: 41152
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.
Upvotes: 9
Reputation: 36702
The "sample" editor scite uses the bookmark feature to bookmark all the lines that match the search result.
Upvotes: 2