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.
    • 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