The << Find button has returned...sort of...and has brought friends



  • The << Find button seemed to be a well-liked feature from Notepad++ 7.4.2…but sadly it was removed in Notepad++ 7.5. The removal was a good thing because there were some problems with the feature as implemented.

    Read about how the <<FInd button had some fans:

    Recently I made a 32-bit build (based upon N++ 7.5 sources) that adds the following buttons in the Find/Replace dialog:

    • << Find and Find >> (restored)
    • << Replace and Replace >> (new buttons)
    • << Repl All and Repl All >> (new buttons)

    Note: The Backward direction checkbox from 7.5 was removed from this build as it is no longer needed

    Here’s what this interface looks like:

    Some details:

    • One of the logistical “problems” with having two Repl All buttons is that direction is meaningless if the Wrap-around or In-selection checkboxes are ticked…in which case there really should be only ONE replace-all button – direction doesn’t matter. However, this (dynamically changing the UI to sometimes show one button) wasn’t done and pressing EITHER Repl All button is equivalent in these situations…

    • Note that the << buttons are disabled when regular-expression search-mode is enabled – this is intended behavior as searching backward in this mode has been disabled since around the time of version 6.3.

    • The way macros regarding Find and Replace/All work is that the direction of the search is remembered separately from the command. Breaking out Find, Replace, and ReplaceAll with 3 new “previous” buttons (the old buttons were just renamed as the “next” buttons) does not effect this scheme, i.e., no new commands are added to the command list–if a “previous” button is used during macro recording, the original command is recorded and the direction data is adjusted based upon the pressed button’s “direction”. An example might help here:
      * If the “<< Find” button is pressed during macro recording, it is recorded as an (existing) “Find Next” command (ID=1) with direction encoded as “up” (0 bit-weighting in the option mask)
      * If the “Find >>” button is pressed during macro recording, it is recorded as an (existing) “Find Next” command (ID=1) with direction encoded as “down” (512 bit-weighting in the option mask)

    • Note: Reference find-macro info here but definitely notice that the 1702 option-flags table is wrong in that it bit-weights “up” as 512, not “down”!

    • A bonus from keeping one command ID for two different commands is that find-related macros recorded with earlier versions of Notepad++ will work without any changes needed in this version.

    If you are valiant you can try out this build; the best way to do so might be to:

    • Grab a portable install of 7.5 from here … look for file “npp.7.5.bin.zip” or “npp.7.5.bin.7z”
    • Unzip the portable install somewhere
    • Get my build of notepad++ from here
    • Extract notepad++.exe from my build’s zip over the notepad++.exe in the folder where you unzipped the portable install
    • Run the new notepad++.exe
    • Do some finding and replacing!

    I would have also made a 64-bit build, but for some reason building Boost for 64-bit doesn’t want to work on my machine (MSVC 2015 Community Edition). :(

    I’d appreciate any feedback, even if you don’t actually try the build but just THINK about this new functionality…are these new button functions liked?

    If this gets some positive feedback, I’ll turn it into a real pull request…that could very well get ignored…but let’s be hopeful.



  • Hi, @scott-sumner,

    Bravo, Scott !! Nice implementation :-))

    I did some quick tests with the change.log file, searching for word Add and replacing with ABC, in both normal and Regular expression mode, with or without the wrap around option. Everything seems OK :-))

    Remark : I have not test any macro, yet, containing Search/Replace operations !

    I’ve just noticed one bug. Luckily, after checking on official versions, that’s NOT due to your version !

    Given, for instance, the string abcabcabcabcABCabcabc ( 7 times the string abc )

    • Place the cursor right after the part ABC, in upper case, of that string

    • Open the Find dialog

    • Type abc on the Find what: area

    • Leave all the “box” options UNchecked

    • Check the Normal search mode

    • Finally, click on the << Find button

    => It does not match the string ABC, as expected, but the previous string abc ! ( BUG )

    However, if the caret is located right after the string ABCa ( that is to say one more position to the right ! ), it does match the string ABC, in upper case !


    And luckily, in forward direction, this bug does not occur !

    • Place the cursor right before the part ABC, in upper case

    • Clicking on the Find >> button, N++ selects, as expected, the ABC string !

    Best Regards,

    guy038



  • @guy038 said:

    I’ve just noticed one bug. Luckily, after checking on official versions, that’s NOT due to your version !

    I agree with your findings. The trouble seems to come from this section of the source code:

    CharacterRange cr = (*_ppEditView)->getSelection();
    
    //The search "zone" is relative to the selection, so search happens 'outside'
    int startPosition = cr.cpMax;
    int endPosition = docLength;
    
    if (pOptions->_whichDirection == DIR_UP)
    {
        //When searching upwards, start is the lower part, end the upper, for backwards search
        startPosition = cr.cpMax - 1;
        endPosition = 0;
    }
    

    The line causing the trouble is startPosition = cr.cpMax - 1;

    When the caret is here (at the position marked by the vertical bar): abcabcabcabcABC|abcabc and the backwards search for “abc” (without regard to case) is invoked, the -1 in the line above is what causes the search to begin at this position: abcabcabcabcAB|Cabcabc instead of at the correct starting point. Thus, the first match that is found is the last “abc” just before “ABC” (as @guy038 indicated), instead of “ABC”. This supposes that Scintilla’s searchInTarget() function (called later than the above snippet of code) won’t find matches that begin inside the specified range and extend outside the range.

    Unfortunately, I don’t see an easy fix to this. If the line is changed to be startPosition = cr.cpMax; then “ABC” is correctly found as the first backward-search match, but repeated presses of the <<Find (my N++ build) or Find Next (real N++ 7.5) button will not move the caret, i.e., it will be stuck on “ABC” forever, instead of finding each preceding “abc” match in turn.


Log in to reply