Community
    • Login

    Find and Display *All* Duplicate Lines

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    54 Posts 9 Posters 28.7k 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.
    • Alan KilbornA
      Alan Kilborn @Michael Vincent
      last edited by

      @Michael-Vincent said in Find and Display *All* Duplicate Lines:

      this lexer name seems to be defined and used within N++, I wonder why PythonScript cannot activate it?

      I agree with the sentiment, and a while ago I actually tried go get this going – but not to the level it seems you did. I was also unsuccessful. I had some offline chats with @Ekopalypse about it; I don’t think we got to a working solution. :-(

      EkopalypseE 1 Reply Last reply Reply Quote 2
      • EkopalypseE
        Ekopalypse @Alan Kilborn
        last edited by

        @Alan-Kilborn @Michael-Vincent

        Afaik the problem is that the “search result” lexer uses an internal structure MarkingsStruct that contains the results to which it refers.

        EkopalypseE 1 Reply Last reply Reply Quote 1
        • EkopalypseE
          Ekopalypse @Ekopalypse
          last edited by Ekopalypse

          I used my lunch break productively :-)
          Please note that this only works if the corresponding search has taken place, i.e.
          You cannot save the search result in a file and reapply the styling when loading.

          6376b31b-6cab-4096-a008-6a02e8fc979e-image.png

          from ctypes import (cdll, windll, create_string_buffer, create_unicode_buffer,
              addressof, pointer, WINFUNCTYPE)
          from ctypes.wintypes import BOOL, HWND, LPARAM, WPARAM, UINT
          
          from Npp import editor2, notepad
          
          SendMessage          = windll.user32.SendMessageW
          SendMessage.argtypes = [HWND, UINT, WPARAM, LPARAM]
          SendMessage.restype  = LPARAM
          
          NPPM_CREATELEXER = (1024 + 1000 + 110)
          
          WNDENUMPROC = WINFUNCTYPE(BOOL, HWND, LPARAM)
          
          FindWindowEx = windll.user32.FindWindowExW
          GetWindowText = windll.user32.GetWindowTextW
          GetWindowTextLength = windll.user32.GetWindowTextLengthW
          EnumChildWindows = windll.user32.EnumChildWindows
          GetClassName = windll.user32.GetClassNameW
          
          
          nppHandle = notepad.hwnd
          curr_class = create_unicode_buffer(256)
          WM_CLOSE = 0x010
          window_hwnds = {}
          
          SEARCH_WINDOW = 'Search results'
          
          def foreach_window(hwnd, lParam):
              if curr_class[:GetClassName(hwnd, curr_class, 256)] == '#32770':
                  length = GetWindowTextLength(hwnd)
                  if length > 0:
                      buff = create_unicode_buffer(length + 1)
                      GetWindowText(hwnd, buff, length + 1)
                      if buff.value == SEARCH_WINDOW:
                          window_hwnds[buff.value] = hwnd
                          return False
              return True
          
          EnumChildWindows(nppHandle, WNDENUMPROC(foreach_window), 0)
          
          if SEARCH_WINDOW in window_hwnds:
              SCI_GETPROPERTY = 4008
              sci_hwnd = FindWindowEx(window_hwnds[SEARCH_WINDOW], None, 'Scintilla', None)
          
              mark_struct = create_string_buffer(b'@MarkingsStruct')
              mark_struct_ptr = addressof(mark_struct)
          
              length = SendMessage(sci_hwnd, SCI_GETPROPERTY, mark_struct_ptr, 0)
              buffer = create_string_buffer(length+1)
              SendMessage(sci_hwnd, SCI_GETPROPERTY, mark_struct_ptr, addressof(buffer))
          
              _lexer = create_unicode_buffer('searchResult')
          
              ilexer_ptr = SendMessage(notepad.hwnd, NPPM_CREATELEXER, 0, addressof(_lexer))
              editor2.setILexer(ilexer_ptr)
              editor2.setProperty('@MarkingsStruct', buffer.value)
              editor2.styleSetFore(1, (224, 108, 117))
              editor2.styleSetFore(2, (229, 192, 123))
              editor2.styleSetFore(3, (209, 154, 102))
              editor2.styleSetFore(4, (97, 175, 239))
              editor2.colourise(0, -1)
          
          

          Note the use of editor2!

          1 Reply Last reply Reply Quote 2
          • Alan KilbornA
            Alan Kilborn @Alan Kilborn
            last edited by

            @Alan-Kilborn said earlier:

            Another reason is that I have a UDL that I made for .sr files which colorizes the output somewhat like N++'s Search results,

            Actually, I misspoke. When I first set it up, I was trying to do it with a UDL, but I later switched to using the EnhanceAnyLexer plugin. (I was confused because I didn’t delete my UDL when I went a different way)

            EnhanceAnyLexer seems easier than trying to force N++ to artificially use the internal Search-result lexer, but it is definitely interesting to play around with something like that, so I enjoyed considering the code from @Michael-Vincent and @Ekopalypse earlier in this thread.

            1 Reply Last reply Reply Quote 2
            • Alan KilbornA Alan Kilborn referenced this topic on
            • guy038G
              guy038
              last edited by

              Hello, @yaron, @coises, @mkupper, @alan-kilborn and All,

              From this post :

              https://community.notepad-plus-plus.org/topic/20370/how-to-jump-to-a-bookmark-and-show-the-bookmarked-line-at-the-top-of-the-screen-not-in-the-middle/14

              In order to always get the target line on top of the visible screen, @mkupper, simply add these 3 Python lines :

                                      curr_pos = editor.getCurrentPos()
                                      curr_line = editor.lineFromPosition(curr_pos)
                                      editor.setFirstVisibleLine(curr_line)
              

              right after the line

                                      editor.gotoLine(line_in_source_file)
              

              in the FindAndDisplayAllDuplicateLines (FADADL) Alan script

              Just be sure that the parameter Enable scrolling beyond last line is checked, in the Preferences > Editing panel


              Now, @mkupper and @alan-kilborn, to get rid of the random selection issue, I personally solve the problem by moving the DupeLineResults.sr file in the secondary view ! And , in that case, it does not bother anymore about a possible previous selection, in the DupeLineResults.sr file, right before double-clicking to get an other line ;-)

              WOW…, Alan, everything is perfect with your script, by now !!

              Best Regards,

              guy038

              Alan KilbornA 1 Reply Last reply Reply Quote 0
              • Alan KilbornA
                Alan Kilborn @guy038
                last edited by PeterJones

                @guy038 said in Find and Display *All* Duplicate Lines:

                In order to always get the target line on top of the visible screen, @mkupper, simply add these 3 Python lines :

                                    curr_pos = editor.getCurrentPos()
                                    curr_line = editor.lineFromPosition(curr_pos)
                                    editor.setFirstVisibleLine(curr_line)
                

                right after the line

                                    editor.gotoLine(line_in_source_file)
                

                You shouldn’t have to calculate new values (your curr_pos and curr_line).

                editor.setFirstVisibleLine(line_in_source_file) should suffice.


                to get rid of the random selection issue, I personally solve the problem by moving the DupeLineResults.sr file in the secondary view ! And , in that case, it does not bother anymore about a possible previous selection, in the DupeLineResults.sr file, right before double-clicking to get an other line

                I can’t comment, as I can’t reproduce random selections happening.


                Alan, everything is perfect with your script, by now

                Well, I doubt this, given mkupper’s continuing strange issues with it.

                EDIT: Ah…wait… I may have just had an inspiration on what could be happening for mkupper, even though I can’t repro it. I’ll do some more thinking on it, and if its logic is sound, I’ll post about it…

                1 Reply Last reply Reply Quote 2
                • guy038G
                  guy038
                  last edited by guy038

                  Hi, @yaron, @coises, @mkupper, @alan-kilborn and All,

                  So, as @alan-kilborn mentioned, to always get the target line on top of the visible screen, @mkupper, simply add this line :

                                      editor.setFirstVisibleLine(line_in_source_file) 
                  

                  Right after the line

                                          editor.gotoLine(line_in_source_file)
                  

                  But I forgot to specify that your must cancel, as well, the Word wrap feature. That is IMPORTANT !!

                  BR

                  guy038

                  Alan KilbornA 1 Reply Last reply Reply Quote 0
                  • guy038G
                    guy038
                    last edited by

                    Hi, @alan-kilborn and All,

                    An other minor bug :

                    If you do get a DupeLineresults.sr file in a tab and that the corresponding source file is presently closed, any double-click on a line of the DupeLineResults.sr file will not open the source file, contrary to a double-click in the Search results panel !

                    BR

                    guy038

                    Alan KilbornA mkupperM datatraveller1D 3 Replies Last reply Reply Quote 0
                    • Alan KilbornA
                      Alan Kilborn @guy038
                      last edited by PeterJones

                      @guy038 said in Find and Display *All* Duplicate Lines:

                      If you do get a DupeLineresults.sr file in a tab and that the corresponding source file is presently closed, any double-click on a line of the DupeLineResults.sr file will not open the source file, contrary to a double-click in the Search results panel !

                      Yes, well a compromise here, because this is only a single source file situation – not multi-file like a potential find-in-files – is that you already have the source file open in another tab. :-)

                      We can fix it with…more code… The original intent, like most of my scripts, is just a demo of possible functionality, not all-encompassing behavior. To try to do that…scripts get too long and the main point is lost, with all the error-checking needed, and the full-featuredness ratcheting up the line count…

                      1 Reply Last reply Reply Quote 3
                      • Alan KilbornA
                        Alan Kilborn @guy038
                        last edited by

                        @guy038 said in Find and Display *All* Duplicate Lines:

                        But I forgot to specify that your must cancel, as well, the Word wrap feature. That is IMPORTANT !!


                        Do we call this YOUR bug, since you introduced the “setFirstVisibleLine” code? :-)


                        I didn’t try it, but probably changing:

                        editor.setFirstVisibleLine(line_in_source_file)

                        to

                        editor.setFirstVisibleLine(editor.visibleFromDocLine(line_in_source_file))

                        will cure that.

                        1 Reply Last reply Reply Quote 3
                        • mkupperM
                          mkupper @guy038
                          last edited by

                          Thank you @guy038 on the editor.setFirstVisibleLine(line_in_source_file) thing. That works perfectly and now I’m consistently taken a view with the desired line at the top.

                          @Alan-Kilborn, as the results are now more consistent I spotted a clue related to the random selection. The end of the random selection is at or very near the mouse which is there because I was double clicking on the line in the DupeLineResults.sr file. The typing cursor is also at that spot.

                          When we double click on a word in npp that word becomes selected. When working with DupeLineResults.sr I double click on a line and am usually double clicking on the number part of Line 1234 though I could double click on the word Line. I’m now wondering if npp or Scintilla is still in the middle of painting that double-clicked word in the DupeLineResults.sr tab while the FindAndDisplayAllDuplicateLines.py script is running notepad.activateIndex(view, index)

                          I tried an experiment with starting a bunch of CPU bound processes to tie up the machine but was unable to hit the sweet spot of getting random selections to happen every time. I did discover that if I use start /high when starting a CPU bound thread that having all of my CPU cores running high priority threads results badly performing windows. I killed one of those threads to free up a CPU core and both Windows and Notepad++ work very well.

                          1 Reply Last reply Reply Quote 1
                          • datatraveller1D
                            datatraveller1 @guy038
                            last edited by

                            Hi @guy038 a bit off topic but…
                            Congratulations on being the top 3 poster now!!!
                            Thanks for your great contributions to the Notepad++ community.

                            1 Reply Last reply Reply Quote 2
                            • mkupperM mkupper referenced this topic on
                            • Alan KilbornA
                              Alan Kilborn
                              last edited by

                              If you’ve used a script in this thread, you might want to double check your copy of it for a bug I’ve discovered.
                              Look to previous postings in this topic thread where the script has been changed – find the text moderator edit (2024-Jan-14).
                              There’s a link there that describes the bug in more detail, and shows what needs to be changed in an old copy (or you can simply grab a copy of the current version).

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