Author Topic: Highlight all occurrences of a variable  (Read 4390 times)

Offline sorinev

  • Multiple posting newcomer
  • *
  • Posts: 61
Highlight all occurrences of a variable
« on: February 01, 2016, 05:20:45 pm »
Sorry to post this here guys but I'm nearly at wits end here. I've asked this on the wxWidgets forums, I've looked through the wxWidgets documentation, Scintilla documentation, Notepad++ source code, Code::Blocks source code, and I've even posted a question on Stackoverflow, all to no avail. I figure you guys are more familiar with wxWidgets than anyone else outside of the wxWidgets team itself, especially when it comes to wxStyledTextCtrl (scintilla) so I'm hoping you can help here.

I'm making an in-house server log parsing tool using wxWidgets 3.0.2 (static+unicode on Win10). I am using wxStyledTextCtrl, which makes it similar to Notepad++ and, to a lesser extent, Code::Blocks (both use Scintilla, but my functionality will visually appear more similar to Notepad++ for those who will use it). Double-click to highlight all occurrences of a highlighted item is basic functionality these days, like NPP/CB have, but I'm having a hard time getting it working because I'm having a hard time figuring out what exactly I need to do when it comes to styling text in the wxStyleTextCtrl.

I've tried many different iterations of the below code, all to varying weird results. The version below clearly goes through the whole document (test file is 50MB), it just doesn't actually do any styling (previous versions of this code would do weird things - make whole document green, or put blue squiggly lines under the occurrences, etc).

Code
//textarea is a wxStyledTextCtrl*
textarea->StyleSetBackground(styleHightlightAllSelected, wxColor(80, 255, 80));

wxString selectedText = textarea->GetSelectedText();
int selSize  = selectedText.size();
int selStart = textarea->GetSelectionStart();

int pos    = 0;
int curr   = 0;
int maxPos = textarea->GetLastPosition();
while(pos != -1){
    pos = textarea->FindText(curr, maxPos, selectedText);
    if(pos == selStart){ //skip the actual highlighted item
        curr = pos + selSize;
    } else if(pos != -1){
        textarea->StartStyling(pos, 0x1F);
        textarea->SetStyling(selSize, styleHightlightAllSelected); //styleHighlightAllSelected is an enum starting at 100
        curr = pos + selSize;
    }
}

It find each occurrence just fine (stepping through debugger shows this), it's just not actually styling the way I want (highlight all occurrences in a specified color). To be more clear, it's not doing anything; the actual doubleclicked word is highlighted in green (SetSelBackground()), but nothing visually happens to any of the occurrences, meaning it just looks like a single word is highlighted and that's it. What I'm not clear on is:

  • What exactly do I use for a mask in StartStyling()? This parameter does not exist in the Scintilla version of StartStyling(), so this is something wxWidgets added. I've gathered that the value above seems to be the one to use, and in my attempts, it does seem to cause the least side effects (is this preserving the 5 styling bits? i.e. -> 00011111).
  • For the int used to refer to my style, I found that when I used 0, odd things happened, but when I used something higher, like the 100 mentioned above, weird things did not happen. I know styles 32-39 are pre-defined, but are styles 0-31 also built-in as well, such as for lexers and so forth?
  • Is it enough to just set the background color on my target style, or do I need to set everything related to the style?
  • The actual style setup aside, going through NPP and C::B source it seems that all I need to do is StartStyling() and then SetStyling() when I find something I want to style. Is this really it, or did I miss something somewhere?

I really appreciate any help you can offer.

Offline sorinev

  • Multiple posting newcomer
  • *
  • Posts: 61
Re: Highlight all occurrences of a variable
« Reply #1 on: February 03, 2016, 08:42:12 pm »
I asked about this on the Notepad++ github page, since that was the behavior I was after, and the answer was to use indicators, not styles. I had thought, obviously erroneously, that indicators were only for the margin, so I hadn't looked into them (and if we are going purely by name, 'style' seemed to make more sense).