Community
    • Login

    Find and Display *All* Duplicate Lines

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    54 Posts 9 Posters 28.6k 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 @PeterJones
      last edited by

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

      When typing names of files with two-letter extensions, some extensions map to known TopLevelDomains, which makes NodeBB linkify those filenames as URLs.

      I always wondered why it did that – go to know.
      In the past I’ve sometimes red-texted the name of scripts, but not always; didn’t realize there was possibly some harm to come from not doing it.
      I’ll attempt to remember to do filenames in red-text from now on.

      1 Reply Last reply Reply Quote 2
      • 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