Community
    • Login

    Python Script plugin: script to tell the cursor to highlight the result and everything before it up to ">"

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    15 Posts 5 Posters 1.0k 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.
    • .jean luc borla.
      .jean luc borla
      last edited by .jean luc borla

      Hi,
      Python Script plugin is standard Notepad++ plugin which allows the user to develop and run Python programs which can interact directly with their Notepad++ session.

      The editor.documentStart() script allows to Move the cursor to the start of the document.

      what would be the script to tell the cursor to highlight the result and everything before it up to “>”

      Exemple :

      search for “585543”
      highlight “585543” and everything before “585543” up to and including “>”

      1> toto|entry1|name entry 1
      <5545530925043245043647831425433855454444254454443854954458554352443344530514554384755584535325242
      2> toto|entry2|name entry 2
      <5052111312475888808008337300450218742703373135855433133731130394883472454243543738810345331428373511418323890414683233322831303141448503314323173333332301183187278483374123574635428388480388131343333333328343545131430202150411403646343534333338333833523308138353313131145313331434117340114110404331621361303318123203538825
      3>toto|code3|…

      PeterJonesP Alan KilbornA 2 Replies Last reply Reply Quote 1
      • PeterJonesP
        PeterJones @.jean luc borla
        last edited by PeterJones

        @jean-luc-borla said in Python Script plugin: script to tell the cursor to highlight the result and everything before it up to ">":

        what would be the script to tell the cursor to highlight the result and everything before it up to “>”

        I’m not sure what you mean by that. “Everything before 585543” seems to contractict “up to >”. Unless you mean you want to select from the > on one line to the 585543 that comes next, something like this:
        86eb7bf8-2242-47e7-b3a7-62a197ade31e-image.png
        (I used the Mark > Mark All to set the color on the 585543, and then manually selected the text from the > to the 585543 to show what I think you want. That wouldn’t necessarily be the sequence used in the PythonScript equivalent, depending on your definition of “highlight”, as I request clarification below.)

        But I could also interpret that as if you didn’t mean “before” but actually meant “after”, in which case it would be highlighting more like:
        66f8eac3-2f36-487d-8256-494a939bde8f-image.png

        If one of my screenshots matches the text you are expecting, please let us know which. If neither of my screenshots matches the text you are expecting, please do the manual selection for us, so that we can see which text you actually want highlighted.

        Also, when you say “highlight”, do you mean “select the text”? Or do you mean “mark the text with the Search > Mark color”? Or do you mean “mark the text using **Search > Style One Token > Using #th Style”? Or do you mean, “apply some arbitrary text-styling color, like a language lexer does”? Because all three of those are ways to “highlight”, but they would each require different syntax in PythonScript.

        But from what I do understand:

        • editor.documentStart() is not a necessary part of the answer to this script; you don’t need to move the caret in order to highlight something (you could, but you don’t need to)
        • editor.setSel(start,end) is the easiest way to set the start and end locations for the active selection (assuming “highlight” means “select the text”)
        • editor.setStyling(...) could be part of a lexer-like solution. But Notepad++ changes styling based on the active lexer every time it refreshes the view, so you’d probably find it pretty annoying
        • editor.setIndicatorCurrent(...); editor.setIndicatorValue(...); indicatorFillRange(...) could be used to set the “indicator” rather than the “style”, which would have a similar result, from your perspective, but Notepad++ doesn’t mess with indicators as much as it does with styles, so there would be less conflict.
        • editor.setSel(start,end); notepad.menuCommand(MENUCOMMAN.SEARCH_MARKALLEXT2) would be the same as selecting the text then using Search > Style All Occurrences of Token > Using 2nd Style. Unfortunately, PythonScript 2.0.0.0 does not have the constants for Style One Token instead of Style All Occurrences of Token. Fortunately, you can figure out those constants from menuCmdId.h: Mark One Token using styles 1-5 would be values 43062 - 43066, so notepad.menuCommand(43062) would use the 1st Style for doing the marking of the active selection as the “Token”.
        • editor.research() would be an easy way to find the text you want, and then run a function to actually do the marking.
        .jean luc borla. 1 Reply Last reply Reply Quote 0
        • Alan KilbornA
          Alan Kilborn @.jean luc borla
          last edited by Alan Kilborn

          @jean-luc-borla said in Python Script plugin: script to tell the cursor to highlight the result and everything before it up to ">":

          highlight “585543” and everything before “585543” up to and including “>”

          6e3eec4c-074f-43b6-8ab7-a88895a64457-image.png

          PeterJonesP .jean luc borla. 2 Replies Last reply Reply Quote 2
          • PeterJonesP
            PeterJones @Alan Kilborn
            last edited by

            @Alan-Kilborn ,

            Oh, right, editor.findText probably has an easier interface than editor.research()… I tend to forget that there’s the non-callback version.

            .jean luc borla. 1 Reply Last reply Reply Quote 0
            • .jean luc borla.
              .jean luc borla @PeterJones
              last edited by .jean luc borla

              @PeterJones said
              "Unless you mean you want to select from the > on one line to the 585543 that comes next, something like this:
              491c8c52-53be-43ab-ba75-bcdbf28651ac-image.png

              Yes it’s that
              culd you provide the complete code to do that ?

              1 Reply Last reply Reply Quote 0
              • .jean luc borla.
                .jean luc borla @PeterJones
                last edited by

                @PeterJones

                Thanks,

                I have tried but there is an error

                File “<console>”, line 1
                z = editor.findText(FINDOPTION.REGEXP, 0, editor.getLength(), r’ (?s)>.*585543’) if Z is not None: editor.setSel(*z)
                ^
                SyntaxError: invalid syntax

                1 Reply Last reply Reply Quote 0
                • .jean luc borla.
                  .jean luc borla @Alan Kilborn
                  last edited by

                  @Alan-Kilborn

                  I tried but there is an error:

                  File “<console>”, line 1
                  z = editor.findText(FINDOPTION.REGEXP, 0, editor.getLength(), r’ (?s)>.*585543’) if Z is not None: editor.setSel(*z)
                  ^
                  SyntaxError: invalid syntax

                  PeterJonesP 1 Reply Last reply Reply Quote 0
                  • PeterJonesP
                    PeterJones @.jean luc borla
                    last edited by

                    @jean-luc-borla said,

                    SyntaxError: invalid syntax

                    You put both commands on the same line. Python (and thus the PythonScript plugin) doesn’t work that way.

                    z = editor.findText(FINDOPTION.REGEXP, 0, editor.getLength(), r'(?s)>.*585543')
                    if z is not None: editor.setSel(*z)
                    

                    This works. Well, mostly. The regex is too greedy.
                    470b3d1d-a338-4ac3-9221-a2998a412f88-image.png

                    Change it to be less greedy:

                    z = editor.findText(FINDOPTION.REGEXP, 0, editor.getLength(), r'(?s)>.*?585543')
                    if z is not None: editor.setSel(*z)
                    

                    1eb0be69-4525-4842-931b-7901cd3bcb30-image.png

                    Alan KilbornA 4SHAKEN4 2 Replies Last reply Reply Quote 0
                    • Alan KilbornA
                      Alan Kilborn @PeterJones
                      last edited by

                      My response was going to be: “We can’t teach basic Python here”

                      1 Reply Last reply Reply Quote 2
                      • 4SHAKEN4
                        4SHAKEN @PeterJones
                        last edited by PeterJones

                        @PeterJones

                        Hello!
                        This thread has been very helpful and got me out of a rut I was in, so thank you very much!

                        How would you determine how many “matches” are in z? I like to output it to console as shown below…

                        console.write('Searching for matches...\n')
                        z = editor.findText(FINDOPTION.REGEXP, 0, editor.getLength(), my_search_variable)
                        if z is not None:
                            editor.gotoLine(editor.lineFromPosition(z[0])+20)    
                            editor.setSel(*z)
                            console.write('Search Completed - found XXX matches which are highlighted\n')
                        else:
                            console.write('Search Completed.  No matches found.\n')
                        

                        —

                        moderator added code markdown around text; please don’t forget to use the </> button to mark example text as “code” so that characters don’t get changed by the forum

                        Alan KilbornA 1 Reply Last reply Reply Quote 0
                        • Alan KilbornA
                          Alan Kilborn @4SHAKEN
                          last edited by Alan Kilborn

                          @4SHAKEN said :

                          z = editor.findText(FINDOPTION.REGEXP, 0, editor.getLength(), my_search_variable)

                          How would you determine how many “matches” are in z?

                          Um…well, one, at most. The documentation for editor.findText() in PythonScript is lacking, unfortunately; here’s what I’ve discovered about it over time:

                          Here’s how to interpret the return value from z = editor.findText(...):

                          Result Meaning
                          z is None no match was found
                          z is a 2-tuple where z[0] == -2 regular expression in my_search_variable is either invalid or the regex engine had a failure in conducting the search
                          z is a 2-tuple where z[0] != -2 one match, at the position range indicated by the tuple, i.e., at positions z[0] through z[1] in the document

                          Bonus (because it came to mind based on what you’re asking about, and what I’ve said above):

                          If you need to validate the regex in my_search_variable, here’s a (Python3) function that will do that for you:

                          def regex_is_valid(test_regex):
                              return (tup2 := editor.findText(FINDOPTION.REGEXP, 0, 0, test_regex)) is None or tup2[0] != -2
                          
                          

                          It really seems like you need to use editor.research() rather than editor.findText(), if you want to find multiple matches with a single call to a searching function, e.g.:

                          matches = []
                          editor.research(search_variable, lambda m: matches.append(m.span(0)))
                          num_matches = len(matches)
                          
                          4SHAKEN4 1 Reply Last reply Reply Quote 1
                          • 4SHAKEN4
                            4SHAKEN @Alan Kilborn
                            last edited by PeterJones

                            @Alan-Kilborn thanks for the suggestion on editor.research! I’m now able to get num of matches. I haven’t found a replacement for editor.setSel (using match) so I’m having to do the search twice. I’m sure its a rookie mistake on my part.

                            console.write('Searching for matches...\n')
                            matches = []
                            editor.research(my_search_variable, lambda m: matches.append(m.span(0)))
                            num_matches = len(matches)
                            z = editor.findText(FINDOPTION.REGEXP, 0, editor.getLength(), mrn_acc_search)
                            if matches:
                                editor.gotoLine(editor.lineFromPosition(matches[0][0])+20)
                                editor.setSel(*z)
                                console.write('Search Completed - found ' + str(num_matches) + ' which are highlighted.\n')
                            if not matches:
                                console.write('Search Completed.  No matches found.\n')
                            

                            —

                            moderator added code markdown around text; please don’t forget to use the </> button to mark example text as “code” so that characters don’t get changed by the forum

                            Alan KilbornA 1 Reply Last reply Reply Quote 0
                            • Alan KilbornA
                              Alan Kilborn @4SHAKEN
                              last edited by

                              @4SHAKEN said:

                              I haven’t found a replacement for editor.setSel (using match)

                              Note, the following is untested, but it or something very similar, should work, if I’m understanding what you want:

                              editor.setSel(*matches[0])

                              4SHAKEN4 1 Reply Last reply Reply Quote 0
                              • 4SHAKEN4
                                4SHAKEN @Alan Kilborn
                                last edited by PeterJones

                                @Alan-Kilborn Confirmed it works, thanks so much! My updated code is below in case it helps others.

                                console.write('Searching for matches...\n')
                                matches = []
                                editor.research(my_search_variable, lambda m: matches.append(m.span(0)))
                                num_matches = len(matches)
                                if matches:
                                    editor.gotoLine(editor.lineFromPosition(matches[0][0])+20)
                                    editor.setSel(*matches[0])
                                    console.write('Search completed at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + '. ' + str(num_matches) + ' matches found.\n')
                                if not matches:
                                    console.write('Search completed at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + '.  No matches found.\n')
                                

                                —

                                moderator added code markdown around text; please don’t forget to use the </> button to mark example text as “code” so that characters don’t get changed by the forum

                                Mark OlsonM 1 Reply Last reply Reply Quote 2
                                • Mark OlsonM
                                  Mark Olson @4SHAKEN
                                  last edited by

                                  @4SHAKEN
                                  In the future you should wrap your code snippets in ``` blocks.

                                  if foo:
                                      blah = -3
                                      return bar() # notice syntax highlighting, indentation preserved
                                  else:
                                      return zut()
                                  
                                  1 Reply Last reply Reply Quote 0
                                  • First post
                                    Last post
                                  The Community of users of the Notepad++ text editor.
                                  Powered by NodeBB | Contributors