• Login
Community
  • Login

Automatic selection of ALL instances of a searched string, in one go

Scheduled Pinned Locked Moved General Discussion
37 Posts 7 Posters 5.2k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M
    mkupper
    last edited by mkupper Jun 17, 2023, 4:49 PM Jun 17, 2023, 4:41 PM

    I have always thought of selections as being temporary and fragile things and don’t think I would be comfortable with constructing selections using a search expression. I like to be able to look things over before I perform some action… One click of a mouse or keyboard can wipe out a carefully constructed selection.

    An alternative is to use marking and to add a Select Marked Text button. This button likely could replace the Copy Marked Text button on the Mark dialog box.

    Once the marked text is selected then people could then copy it, replace it, delete it, convert to upper/lower case, etc.

    At present, unmarking is moderately awkward but is possible. Ideally, the Mark dialog box was a little more consistent. The Mark All button marks using a combination of the search pattern plus the In selection checkbox. The Clear all marks button though ignores the search pattern field but does honor In selection.

    That leads me to thinking about adding a Mark selected text button so that I can drag-select some text, mark it, drag-select something else and mark it without needing to use the search pattern field.

    A potential downside to the idea is that because selecting and marking do not make changes to the text that the activity related to setting up the marked area(s) or selection(s) never show up in the undo/redo history. Someone could loose chunk of time.

    A 1 Reply Last reply Jun 18, 2023, 10:47 AM Reply Quote 4
    • L
      Lycan Thrope @Alan Kilborn
      last edited by Jun 17, 2023, 10:16 PM

      @Alan-Kilborn ,

      I’m glad you did this, because I was thinking the same thing. I don’t know why his Undo didn’t work, perhaps because it was a script that did other things in addition, but whenever I do a change or search/replace, I feel it’s on me, to make sure I really want that change, as @mkupper suggests.

      For that, the usefulness of the Mark comes into play and allows one to see what they’ll be changing ahead of time using the supplied regex. Using these things in bulk text changes is always a risk so again, these changes need to be tempered with good reason, as @Alan-Kilborn suggests, rather than willly-nilly giving users more complex operations than they truly need which just adds to more confusion, support problems and trying to explain to people how to properly use it which will benefit, what? Maybe 1% of the total users?

      That’s what the scripting option is supposed to be for, so that the 1% (which most likely will also be superusers with the skills, anyways) can craft custom capabilities that the other 99% don’t need to be able to use or heaven forbid, stumble into and send them straight here looking for people to unscrew their lack of understanding of what “Don’t push the red button” means. :-)

      1 Reply Last reply Reply Quote 3
      • A
        Alan Kilborn @mkupper
        last edited by Jun 18, 2023, 10:47 AM

        @mkupper said:

        An alternative is to use marking and to add a Select Marked Text button. This button likely could replace the Copy Marked Text button on the Mark dialog box.

        Or, it could be an additional action button, not replacing an existing one that users could be used to using.


        At present, unmarking is moderately awkward but is possible. Ideally, the Mark dialog box was a little more consistent. The Mark All button marks using a combination of the search pattern…

        So what I think you’re saying here is that it would be nice to be able to unmark text based on the Find what expression as well. That makes a good deal of sense. Maybe an additional action button could be added for this case.

        M 1 Reply Last reply Jun 18, 2023, 2:13 PM Reply Quote 4
        • M
          mkupper @Alan Kilborn
          last edited by Jun 18, 2023, 2:13 PM

          @Alan-Kilborn said in Automatic selection of ALL instances of a searched string, in one go:

          Or, it could be an additional action button, not replacing an existing one that users could be used to using.

          I had suggested replacing the button to declutter the user interface.

          The action would still be available but would take an extra step which is select-all-marked and then copy.

          1 Reply Last reply Reply Quote 2
          • E
            Ekopalypse @Alan Kilborn
            last edited by Jun 19, 2023, 7:18 AM

            @Alan-Kilborn said in Automatic selection of ALL instances of a searched string, in one go:

            And the big advantage to that is…?

            To be able to work with multiple cursors.

            On the rest of the arguments against such a feature.
            I don’t think it takes a genius to figure out what “select whatever” would mean in such a case,
            and if it’s documented, those unfamiliar with or accustomed to the concept of “multiple cursors/carets/editors/whatever” will understand its purpose.
            Does this mean that all potential users are using it correctly,
            no, but are all users also using regexes correctly? Backup? …
            Someone who wants to test beforehand whether the results of his search will give only the desired result can run mark beforehand …
            Whether such an extension is implemented in the find tab as a checkbox,
            or gets its own tab or dialog, is in my opinion irrelevant for this discussion,
            because it is ONLY about whether Don finds it good or not.
            No matter what comes out of this discussion in the end,
            if Don has a different opinion on it, and that should be respected because it’s his project,
            that and only that will be the deciding factor.
            So, I’ve given enough mustard on this subject now, wouldn’t know what more input I could provide.

            A 1 Reply Last reply Jun 19, 2023, 11:31 AM Reply Quote 3
            • A
              Alan Kilborn @Ekopalypse
              last edited by Jun 19, 2023, 11:31 AM

              @Ekopalypse

              And the big advantage to that is…?

              To be able to work with multiple cursors.

              Sure, one can just keep saying that over and over again, but I for one haven’t been convinced about any great usefulness gain coming from it.

              Of course, my opinion doesn’t matter, but if I feel that way, probably others do, too. No idea how the author of Notepad++ feels about it, but unless someone creates a PR for it, that doesn’t matter, either.

              1 Reply Last reply Reply Quote 2
              • M Mark Olson referenced this topic on Aug 5, 2023, 2:38 PM
              • A
                Alan Kilborn
                last edited by Alan Kilborn Oct 15, 2023, 3:21 PM Oct 15, 2023, 12:11 PM

                Here’s my entry for a script for this topic.

                NOTE: This is probably NOT of any use for dedicated keyboardists as there is really no way to make use of it without touching the mouse. (Of course, the same can be said of most (but not all) “mulit-edit” operations.

                What it does is a “scoped multiselect”. For myself, I find this very useful to quickly rename a poorly-named script variable in a localized section of code. Often when I’m coding I need a variable to do something, so maybe I’ll just call it zz until I get its code correct, and only then will I give it a good permanent name, one that suits its (perhaps evolved) function.

                Anyway, to use the script, you define two empty carets (to say “only act in the range between them”) and then a non-empty selection between the empties (to define the source text to be replaced), and then you run the script. The empty carets defining scope give me confidence that I won’t be changing text outside of my defined area.

                An example helps; take the original example in this thread, and set up the following two empty carets and selection, which is very quick and easy to do with the mouse (just click on line 6, ctrl+click on line 17, and ctrl+doubleclick on simple in line 13):

                f8d9f854-2964-4796-bf3b-e24da9e393bb-image.png

                Run the script to obtain:

                34852a6f-582c-42fb-a651-25b73e3e99d0-image.png

                I bind the running of this script to a keycombo, and find this is quicker than Notepad++'s replace function when I need to rename something: No prompts and no typing to get the text I need selected; all I have to do after running the script is type the desired replacement text.

                I named this script the somewhat lengthy MultiselectSelectedTextBetweenlEmptyCaretStoppers.py and here is its listing:

                # -*- coding: utf-8 -*-
                from __future__ import print_function
                
                #########################################
                #
                #  MultiselectSelectedTextBetweenlEmptyCaretStoppers (MSTBECS)
                #
                #########################################
                
                # references:
                #  https://community.notepad-plus-plus.org/topic/24549  <-- this script posted here
                #  inspiration:
                #   https://github.com/notepad-plus-plus/notepad-plus-plus/issues/8203#issuecomment-623136793
                #  for newbie info on PythonScripts, see https://community.notepad-plus-plus.org/topic/23039/faq-desk-how-to-install-and-run-a-script-in-pythonscript
                
                #-------------------------------------------------------------------------------
                
                from Npp import *
                import os
                import inspect
                
                #-------------------------------------------------------------------------------
                
                class MSTBECS(object):
                
                    def __init__(self):
                
                        self.this_script_name = inspect.getframeinfo(inspect.currentframe()).filename.split(os.sep)[-1].rsplit('.', 1)[0]
                
                        # user must make the 3 required selections in any order:
                        sel_tup_list = []
                        sel_tup_list.append( (editor.getSelectionNStart(0), editor.getSelectionNEnd(0)) )
                        if editor.getSelections() >= 2: sel_tup_list.append( (editor.getSelectionNStart(1), editor.getSelectionNEnd(1)) )
                        if editor.getSelections() >= 3: sel_tup_list.append( (editor.getSelectionNStart(2), editor.getSelectionNEnd(2)) )
                        sel_tup_list.sort()
                
                        # conditions-not-correct checking:
                        cnc = False
                        if not cnc and not editor.getMultipleSelection(): cnc = True  # must have "Multi-editing" enabled in Preferences
                        rect_sel_mode = editor.getSelectionMode() in [ SELECTIONMODE.RECTANGLE, SELECTIONMODE.THIN ]
                        if not cnc and rect_sel_mode: cnc = True  # can't be in column-block selection mode
                        if not cnc and len(sel_tup_list) != 3: cnc = True  # need 3 selections (actually 2 carets and one selection)
                        if not cnc and sel_tup_list[0][0] != sel_tup_list[0][1]: cnc = True  # no leading empty caret
                        if not cnc and sel_tup_list[1][0] == sel_tup_list[1][1]: cnc = True  # no text selected between carets
                        if not cnc and sel_tup_list[2][0] != sel_tup_list[2][1]: cnc = True  # no trailing empty caret
                        if cnc:
                            cnc_help = '''
                            Conditions are not correct for running the script.
                            You must have:
                            - "Multi-Editing" enabled in Preferences
                            - Two empty carets with a stream selection in between
                            '''
                            self.mb(cnc_help)
                            return
                
                        (start_search_pos, end_search_pos) = (sel_tup_list[0][0], sel_tup_list[2][0])
                        search_word = editor.getTextRange(*sel_tup_list[1])
                        match_span_tup_list = []
                        editor.search(search_word, lambda m: match_span_tup_list.append(m.span(0)), 0, start_search_pos, end_search_pos)
                
                        if len(match_span_tup_list) > 1:
                            editor.setSelection(*match_span_tup_list[0][::-1])  # args to setSelection are caret then anchor
                            for (start_match_pos, end_match_pos) in match_span_tup_list[1:]:
                                editor.addSelection(end_match_pos, start_match_pos)
                            self.sb_output('{} selections made'.format(len(match_span_tup_list)))
                
                    def mb(self, msg, flags=0, title=''):  # a message-box function
                        return notepad.messageBox(msg, title if title else self.this_script_name, flags)
                        
                    def sb_output(self, *args):  # output to N++'s status bar (will be overwritten by N++ e.g. when active tab is changed)
                        notepad.setStatusBar(STATUSBARSECTION.DOCTYPE, ' '.join(map(str, args)))
                
                #-------------------------------------------------------------------------------
                
                if __name__ == '__main__': MSTBECS()
                
                M 1 Reply Last reply Oct 15, 2023, 3:03 PM Reply Quote 3
                • A Alan Kilborn referenced this topic on Oct 15, 2023, 12:11 PM
                • M
                  Mark Olson @Alan Kilborn
                  last edited by Oct 15, 2023, 3:03 PM

                  @Alan-Kilborn
                  Getting this error:

                  Traceback (most recent call last):
                    File "%AppData%\Roaming\Notepad++\plugins\Config\PythonScript\scripts\multiSelectBetweenEmptyCaretSelections.py", line 65, in <module>
                      if __name__ == '__main__': MSTBECS()
                    File "%AppData%\Roaming\Notepad++\plugins\Config\PythonScript\scripts\multiSelectBetweenEmptyCaretSelections.py", line 61, in __init__
                      self.sb_output('{} selections made'.format(len(match_span_tup_list)))
                  AttributeError: 'MSTBECS' object has no attribute 'sb_output'
                  

                  Eyeballing the code, it looks like calling self.mb will probably cause the same problem. I guess you forgot to define those methods.

                  A 1 Reply Last reply Oct 15, 2023, 3:10 PM Reply Quote 2
                  • A
                    Alan Kilborn @Mark Olson
                    last edited by Alan Kilborn Oct 15, 2023, 3:21 PM Oct 15, 2023, 3:10 PM

                    @Mark-Olson

                    I didn’t exactly forget, I just streamlined out some of my usual debug code, before posting.
                    It appears I got too heavy with my edits. :-(

                    I still have time to edit the script; I’ll fix it. :-)
                    Thanks for pointing it out.

                    EDIT: I updated the above script listing to fix the problems @Mark-Olson pointed out.

                    1 Reply Last reply Reply Quote 3
                    • G
                      guy038
                      last edited by guy038 Oct 18, 2023, 4:20 PM Oct 18, 2023, 1:16 PM

                      Hello, @alan-kilborn and All,

                      Ah… yes, your proposed script is quite clever and very intuitive ;-)) I didn’t think about invisible caret boundaries for the defined scope

                      Remark that, at first glance, I thought that the carets did represent the true | character ( with code \x7C ). But, thanks to the error message, I quickly understood the problem !

                      I personally think that the logical method is :

                      • Do the stream selection of the text first, without holding down the Ctrl key

                      • Then, do the two caret zero-length selections, with the Ctrl key pressed


                      Notes :

                      • If you prefer an insensitive search, simply add the import re command, below the import inspect one and change the line :
                      editor.search(search_word, lambda m: match_span_tup_list.append(m.span(0)), 0, start_search_pos, end_search_pos)  #  SENSITIVE search
                      

                      As :

                      editor.search(search_word, lambda m: match_span_tup_list.append(m.span(0)), re.I, start_search_pos, end_search_pos)  #  INSENSITIVE search
                      

                      • Now, I also found out a trick to simulate a whole-word search :

                        • Do a stream selection of the word, including its surrounding space chars

                        • Do the two caret selections

                        • Run the script

                        • Click on the Right arrow key

                        • Click on the Left arrow key

                        • Click on the Ctrl + Left arrow shortcut


                      Playing around with your script, after a while, I asked myself :

                      Could it be possible to just do the text selection and that the scope of the search would be, automatically, the complete file contents ?

                      After some tries, I ended up with this modified part of the script which, indeed, does the job !

                              sel_tup_list = []
                              sel_tup_list.append( (editor.getSelectionNStart(0), editor.getSelectionNEnd(0)) )
                              if editor.getSelections() >= 2: sel_tup_list.append( (editor.getSelectionNStart(1), editor.getSelectionNEnd(1)) )
                              if editor.getSelections() >= 3: sel_tup_list.append( (editor.getSelectionNStart(2), editor.getSelectionNEnd(2)) )
                              if editor.getSelections() == 1:                                          # If an unique stream selection:
                                  sel_tup_list.append ( (0, 0) )                                       #     Leading caret is supposed to be at the very begining of current filec
                                  sel_tup_list.append ( (editor.getLength(), editor.getLength()) )     #     Trailing caret is supposed to be at the very end of current file
                              sel_tup_list.sort()
                      

                      instead of :

                              sel_tup_list = []
                              sel_tup_list.append( (editor.getSelectionNStart(0), editor.getSelectionNEnd(0)) )
                              if editor.getSelections() >= 2: sel_tup_list.append( (editor.getSelectionNStart(1), editor.getSelectionNEnd(1)) )
                              if editor.getSelections() >= 3: sel_tup_list.append( (editor.getSelectionNStart(2), editor.getSelectionNEnd(2)) )
                              sel_tup_list.sort()
                      

                      Now, although this modification seems quite functional, I would like to know, Alan, if this is the best formulation !

                      Best Regards,

                      guy038

                      A last observation :

                      If you do the three needed selections, in any order and that you decide to add additional selections ( either non-null text or null caret selections ), no error message is displayed : these additional selections are simply ignored. To my mind, it’s the best way to proceed !

                      A 1 Reply Last reply Oct 18, 2023, 2:01 PM Reply Quote 1
                      • A
                        Alan Kilborn @guy038
                        last edited by Oct 18, 2023, 2:01 PM

                        @guy038 said in Automatic selection of ALL instances of a searched string, in one go:

                        I personally think that the logical method is :

                        Do the stream selection of the text first, without holding down the Ctrl key

                        Then, do the two caret zero-length selections, with the Ctrl key pressed

                        The “beauty” of the design is that you can do these 3 things in ANY order that you like.


                        @guy038 said in Automatic selection of ALL instances of a searched string, in one go:

                        If you prefer an insensitive search

                        Yes, but for the utmost in safety, I prefer a sensitive, i.e, match case, design. I don’t want to have to consider it, I just want to know I am getting exactly and only what I’ve asked for.


                        @guy038 said in Automatic selection of ALL instances of a searched string, in one go:

                        …and that the scope of the search would be, automatically, the complete file contents ?

                        Again, the empty carets for scoping are there for safety in this “quick” replacement method. If you’re looking for something with wider scope, just use Notepad++ 's own Replace All functionality.


                        @guy038 said in Automatic selection of ALL instances of a searched string, in one go:

                        if this is the best formulation

                        It seems reasonable to me! :-)
                        There’s rarely one and only one best way with a block of code…

                        1 Reply Last reply Reply Quote 0
                        • G
                          guy038
                          last edited by guy038 Oct 19, 2023, 9:20 AM Oct 18, 2023, 6:19 PM

                          @alan-kilborn and All,

                          In you previous post, you said :

                          Again, the empty carets for scoping are there for safety in this “quick” replacement method. If you’re looking for something with wider scope, just use Notepad++ 's own Replace All functionality.

                          At the time, I felt rather silly for not having thought of it ! But, on reflection, I think we should consider these scripts as, either :

                          • An interactive replacement in selection feature ( for our two scripts )

                          • An interactive global replacement feature ( for my derived script )


                          • For example, let’s imagine this scenario :

                            • I first decide to change any simple word with the word difficult

                            • Then, I changed my mind and prefer to change the word difficult with the expression very difficult

                            • Again , I changed my mind and finally decide to replace from the word very to the end of current line with the expression good old method


                          • With the Replace dialog, we would do 3 successive regex S/R :

                            • SEARCH (?-i)simple

                            • REPLACE difficult

                            • SEARCH (?-i)difficult

                            • REPLACE very $0

                            • SEARCH (?-si)very difficult.+

                            • REPLACE good old method


                          • with our scripts, we would :

                            • Select the word simple and, possibly, the scope of search

                            • Run the script

                            • Type in the word difficult

                            • Use the Ctrl + Left Arrow shortcut

                            • Type in the word very, followed with a space char

                            • Use, again, the Ctrl + Left Arrow shortcut

                            • Use the Shift + End shortcut

                            • Finally type in the good old method expression


                          As you can see, for most of the replacements, the script way seems more intuitive than using successive replacements !

                          Best Regards,

                          guy038

                          A 1 Reply Last reply Oct 18, 2023, 6:58 PM Reply Quote 1
                          • A
                            Alan Kilborn @guy038
                            last edited by Alan Kilborn Oct 18, 2023, 8:37 PM Oct 18, 2023, 6:58 PM

                            @guy038

                            I think it is about “different ways of working”.
                            Each way has its advantages/disadvantages – isn’t everything like that, pretty much?
                            Pros and cons…pros and cons…

                            1 Reply Last reply Reply Quote 1
                            • G
                              guy038
                              last edited by guy038 Oct 19, 2023, 1:31 PM Oct 19, 2023, 1:21 PM

                              Hi, @alan-kilborn and All,

                              In my modified script of my previous post, I added the possibility to choose a single stream selection and select, by default, all the file contents as the scope of the search

                              I slightly improved it : IF NO selection at all is done, it will select the current word under the caret and will search for this word, throughout the file contents !

                              The concerned part is :

                                      if editor.getSelections() == 1:                                       # If an UNIQUE stream selection:
                              
                                          if editor.getSelectionEmpty():                                    # Case : UNIQUE selection EMPTY => We get the START and END of current word
                                              sel_tup_list = []
                                              sel_tup_list.append( (editor.wordStartPosition(editor.getCurrentPos(), True), editor.wordEndPosition(editor.getCurrentPos(), True)) )
                              
                                          sel_tup_list.append ( (0, 0) )                                    #     LEADING caret is supposed at the VERY BEGINING of current filec
                                          sel_tup_list.append ( (editor.getLength(), editor.getLength()) )  #     TRAILING caret is supposed at the VERY END of current file
                              

                              instead of :

                                      if editor.getSelections() == 1:                                       # If an UNIQUE stream selection:
                              
                                          sel_tup_list.append ( (0, 0) )                                    #     LEADING caret is supposed at the VERY BEGINING of current filec
                                          sel_tup_list.append ( (editor.getLength(), editor.getLength()) )  #     TRAILING caret is supposed at the VERY END of current file
                              

                              So, here is my updated script, that I called Automatic_Selections_AK.py, as all credits should be given to you, Alan :

                              # -*- coding: utf-8 -*-
                              
                              from __future__ import print_function
                              
                              '''
                              MultiselectSelectedTextBetweenlEmptyCaretStoppers (MSTBECS)
                              
                              An @Alan-kilborn's Python script with a @guy038 adaptation !
                              
                                Refer to :  https://community.notepad-plus-plus.org/topic/24549/automatic-selection-of-all-instances-of-a-searched-string-in-one-go/29
                                
                                         :  https://community.notepad-plus-plus.org/topic/24549/automatic-selection-of-all-instances-of-a-searched-string-in-one-go/36
                              
                                         :  https://github.com/notepad-plus-plus/notepad-plus-plus/issues/8203#issuecomment-623136793
                              
                                         :  https://github.com/notepad-plus-plus/notepad-plus-plus/issues/8203#issuecomment-624124396 ( from @sasumner )
                              
                              
                              NEWBIES, refer to : https://community.notepad-plus-plus.org/topic/23039/faq-desk-how-to-install-and-run-a-script-in-pythonscript
                              
                              
                              Example :
                              
                              This is a simple test
                              This is a simple test
                              This is a simple test
                              This is a simple test
                              This is a simple test
                              
                              This is a simple test
                                This is a simple test
                                  This is a simple test
                                    This is a simple test
                                      This is a simple test
                                        This is a simple test
                                          This is a simple test
                                            This is a simple test
                                              This is a simple test
                                                This is a simple test
                              
                              This is a simple test
                              This is a simple test
                              This is a simple test
                              This is a simple test
                              This is a simple test
                              
                              
                              THREE usages are possible :
                              
                              1) Do THREE distint STREAM selections :
                              
                                  - The FIRST one, WITHOUT any hit on the 'CTRL' key, of ALL the text to search for
                              
                                  - An additional ZERO-LENGTH one, while holding DOWN the 'CTRL' key, to define the BEGINNING of the scope where the search process will START
                              
                                  - An additional ZERO-LENGTH one, while holding DOWN the 'CTRL' key, to define the END       of the scope where the search proces  will STOP
                              
                              
                              2) Do a SINGLE stream selection ONLY, WITHOUT any hit on the 'CTRL' key, of ALL the text to search for, throughout the ENTIRE file contents
                              
                              
                              3) Do a NULL stream selection ONLY, WITHOUT any hit on the 'CTRL' key, => AUTOMATIC selection of the word under the CARET, throughout the ENTIRE file contents
                              
                              
                              Finally, run this script
                              
                              '''
                              
                              from Npp import *
                              import os
                              import inspect
                              
                              #-----------------------------------------------------------------------------------------------------------------------------------------------------
                              
                              class MSTBECS(object):
                              
                                  def __init__(self):
                              
                                      self.this_script_name = inspect.getframeinfo(inspect.currentframe()).filename.split(os.sep)[-1].rsplit('.', 1)[0]
                              
                                      # user must make the 3 required selections in any order:
                              
                                      sel_tup_list = []
                                      sel_tup_list.append( (editor.getSelectionNStart(0), editor.getSelectionNEnd(0)) )
                              
                                      if editor.getSelections() >= 2: sel_tup_list.append( (editor.getSelectionNStart(1), editor.getSelectionNEnd(1)) )
                                      if editor.getSelections() >= 3: sel_tup_list.append( (editor.getSelectionNStart(2), editor.getSelectionNEnd(2)) )
                              
                                      if editor.getSelections() == 1:                                       # If an UNIQUE stream selection:
                              
                                          if editor.getSelectionEmpty():                                    # Case : UNIQUE selection EMPTY => We get the START and END of current word
                                              sel_tup_list = []
                                              sel_tup_list.append( (editor.wordStartPosition(editor.getCurrentPos(), True), editor.wordEndPosition(editor.getCurrentPos(), True)) )
                              
                                          sel_tup_list.append ( (0, 0) )                                    #     LEADING caret is supposed at the VERY BEGINING of current filec
                                          sel_tup_list.append ( (editor.getLength(), editor.getLength()) )  #     TRAILING caret is supposed at the VERY END of current file
                              
                                      sel_tup_list.sort()
                              
                                      # conditions-not-correct checking:
                              
                                      cnc = False
                                      if not cnc and not editor.getMultipleSelection(): cnc = True         # 'Multi-editing' option ENABLED in Preferences
                              
                                      rect_sel_mode = editor.getSelectionMode() in [ SELECTIONMODE.RECTANGLE, SELECTIONMODE.THIN ]
                                      if not cnc and rect_sel_mode: cnc = True  # can't be in column-block selection mode
                              
                                      if not cnc and len(sel_tup_list) != 3: cnc = True  # need THREE selections ( Actually, 2 carets and 1 selection )
                              
                                      if not cnc and sel_tup_list[0][0] != sel_tup_list[0][1]: cnc = True  #  NO LEADING empty caret
                                      if not cnc and sel_tup_list[1][0] == sel_tup_list[1][1]: cnc = True  #  NO SELECTED text between carets
                                      if not cnc and sel_tup_list[2][0] != sel_tup_list[2][1]: cnc = True  #  NO TRAILING empty caret
                              
                                      if cnc:
                              
                                          cnc_help =\
                              '''
                                The CONDITIONS are NOT met to run this script!
                                      
                                You must have the "Multi-Editing Settings" option ENABLED in 'Settings > Preferences > Editing'
                                      
                                And, either:
                              
                                - 1 NON-NULL stream selection ( Text ), between 2 EMPTY selections ( Carets ), which define the SCOPE of the search
                              
                                - 1 NON-NULL stream selection ( Text ), with an IMPLICITE scope of ALL the file contents
                              
                                - 1 NULL stream selection (Text ) with IMPLICIT selection of word under CARET and IMPLICITE scope of ALL the file contents
                              
                              '''
                                          self.mb(cnc_help)
                                          return
                              
                                      (start_search_pos, end_search_pos) = (sel_tup_list[0][0], sel_tup_list[2][0])
                                      search_word = editor.getTextRange(*sel_tup_list[1])
                                      match_span_tup_list = []
                              
                                      editor.search(search_word, lambda m: match_span_tup_list.append(m.span(0)), 0, start_search_pos, end_search_pos)     #  SENSITIVE search
                                      #editor.search(search_word, lambda m: match_span_tup_list.append(m.span(0)), re.I, start_search_pos, end_search_pos)  #  INSENSITIVE search
                              
                                      if len(match_span_tup_list) > 1:
                                          editor.setSelection(*match_span_tup_list[0][::-1])  #  Args to 'setSelection' are CARET then ANCHOR
                              
                                          for (start_match_pos, end_match_pos) in match_span_tup_list[1:]:
                                              editor.addSelection(end_match_pos, start_match_pos)
                                          self.sb_output('{} selections made'.format(len(match_span_tup_list)))
                              
                                  def mb(self, msg, flags=0, title=''):  #  A MESSAGE-BOX function
                                      return notepad.messageBox(msg, title if title else self.this_script_name, flags)
                                      
                                  def sb_output(self, *args):  # output to N++'s STATUS bar ( will be overwritten by N++, e.g. when ACTIVE tab is changed )
                                      notepad.setStatusBar(STATUSBARSECTION.DOCTYPE, ' '.join(map(str, args)))        
                              
                              #-----------------------------------------------------------------------------------------------------------------------------------------------------
                              
                              if __name__ == '__main__': MSTBECS()
                              

                              Best Regards,

                              guy038

                              A 1 Reply Last reply Oct 19, 2023, 1:47 PM Reply Quote 1
                              • G guy038 referenced this topic on Oct 19, 2023, 1:21 PM
                              • A
                                Alan Kilborn @guy038
                                last edited by Oct 19, 2023, 1:47 PM

                                @guy038 said in Automatic selection of ALL instances of a searched string, in one go:

                                So, here is my updated script, that I called Automatic_Selections_AK.py

                                Oh no, the script should fully be called Automatic_Selections_GT.py ! :-)

                                1 Reply Last reply Reply Quote 1
                                32 out of 37
                                • First post
                                  32/37
                                  Last post
                                The Community of users of the Notepad++ text editor.
                                Powered by NodeBB | Contributors