• Login
Community
  • Login

Replace 1 + lines?

Scheduled Pinned Locked Moved General Discussion
43 Posts 7 Posters 34.1k 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.
  • H
    Herofiles.
    last edited by May 1, 2017, 7:27 AM

    Hello, is it possible to replace, lets say 1-50 lines with new code(same line amount)?

    S 1 Reply Last reply May 1, 2017, 11:53 AM Reply Quote 0
    • S
      Scott Sumner @Herofiles.
      last edited by May 1, 2017, 11:53 AM

      @Herofiles.

      It may be possible, with some amount of extra work. This thread may be of some interest to you: https://notepad-plus-plus.org/community/topic/12973/multiple-line-replacing-doesn-t-work

      Another thing to be aware of is that you may run into the length limit on the Find-what or Replace-with boxes.

      1 Reply Last reply Reply Quote 0
      • A
        AZJIO AZJIO
        last edited by AZJIO AZJIO Jun 19, 2017, 9:55 AM Jun 19, 2017, 9:52 AM

        Use the \r\n
        To replace in a multiline text line wrapping on \r\n
        The result is inserted in the field “Replace with”
        To search, check the “Expanded”

        Well, if the author added the button “Insert the selected text.”

        1 Reply Last reply Reply Quote 0
        • A
          AZJIO AZJIO
          last edited by Jun 25, 2017, 8:54 AM

          Necessary files

          \Notepad++\script\AutoIt3.exe
          \Notepad++\script\copy_multiline.au3

          shortcuts.xml (Alt+F1)

          <Command name=“copy_multiline” Ctrl=“no” Alt=“yes” Shift=“no” Key=“112”>“$(NPP_DIRECTORY)\script\AutoIt3.exe” “$(NPP_DIRECTORY)\script\copy_multiline.au3”</Command>


          copy_multiline.au3

          ; AutoIt
          #NoTrayIcon
          $label = ‘Extended’
          ; Send(‘^{INS}’)
          ControlSend(“[CLASS:Notepad++]”, “”, “”, ‘^{INS}’)
          $s=‘h’
          If @OSLang = 0419 Then $s=‘р’
          If Not WinExists(“[CLASS:#32770]”, $label) Then
          ControlSend(“[CLASS:Notepad++]”, “”, “[CLASS:SysTabControl32]”, ‘^’ & $s)
          EndIf
          $hWnd = WinWait(“[CLASS:#32770]”, $label, 2)
          If Not $hWnd Then Exit
          $hControl = ControlGetHandle($hWnd, $label, ‘SysTabControl321’)
          If Not $hControl Then Exit
          $iNumTab = ControlCommand($hWnd, $label, $hControl, “CurrentTab”)
          Switch $iNumTab
          Case 1
          ControlCommand($hWnd, “”, $hControl, “TabRight”)
          Case 2
          Sleep(10)
          Case 3
          Sleep(10)
          ; ControlCommand($hWnd, “”, $hControl, “TabLeft”)
          Case 4
          ControlCommand($hWnd, “”, $hControl, “TabLeft”)
          ControlCommand($hWnd, “”, $hControl, “TabLeft”)
          Case Else
          Exit
          EndSwitch

          ControlSetText($hWnd, $label, “Edit2”, ClipGet())

          S A 2 Replies Last reply Jun 26, 2017, 6:56 PM Reply Quote 1
          • S
            Scott Sumner @AZJIO AZJIO
            last edited by Jun 26, 2017, 6:56 PM

            This AutoIt3 solution seems to work to get multiple line data into the Replace-with box. The way to use it, which may not be obvious, is to highlight some multiline text in the Notepad++ editor window and then invoke it using the Alt+F1 binding that the author used, or whatever key combination you want to bind it to. The script also assumes that Ctrl+Insert (^{INS}) is mapped as a copy command, and that Ctrl+H ($s='h' or $s='p' if Russian is your language! :-D) is still mapped as the Replace binding. Overall, a nice job on this script; I will look at some of my own AutoIt3 scripts for dealing with the Find dialog to see if I can improve them based upon the ideas here.

            1 Reply Last reply Reply Quote 0
            • A
              Alan Kilborn @AZJIO AZJIO
              last edited by Jun 26, 2017, 7:25 PM

              @AZJIO-AZJIO

              You seem to be pretty good with AutoIt. Do you (or anyone?) know how to use it to get the red text at the bottom of the window?

              Example:

              1 Reply Last reply Reply Quote 0
              • A
                AZJIO AZJIO
                last edited by Jun 26, 2017, 8:44 PM

                I could not get


                Sleep(3000)
                $sText = ControlGetText(“[ACTIVE]”, ‘’, ‘msctls_statusbar32’)
                $hControl = ControlGetHandle(“[ACTIVE]”, ‘’, ‘msctls_statusbar32’)
                MsgBox(0, $sText, $hControl)


                http://azjio.ucoz.ru/load/vsjo_dlja_autoit3/skompilirovannye_skripty/capturetext/4-1-0-60
                If it does not capture the text, then I can not

                A 1 Reply Last reply Jun 27, 2017, 7:30 PM Reply Quote 0
                • A
                  Alan Kilborn @AZJIO AZJIO
                  last edited by Jun 27, 2017, 7:30 PM

                  @AZJIO-AZJIO

                  I couldn’t get your copy_multiline.au3 script to run reliably. The Find dialog box would be shown but the if Not $hWnd Then Exit line exits the program most of the time for me. :(

                  1 Reply Last reply Reply Quote 0
                  • A
                    AZJIO AZJIO
                    last edited by Jun 28, 2017, 4:02 AM

                    Simplified version


                    Send(‘^{INS}’)
                    ControlSetText(“[CLASS:#32770]”, “”, “Edit2”, ClipGet())


                    But the search dialog should be open

                    1 Reply Last reply Reply Quote 0
                    • A
                      Alan Kilborn
                      last edited by Jun 28, 2017, 1:10 PM

                      @AZJIO-AZJIO said:

                      But the search dialog should be open

                      I was most interested in the part that does the opening of the search dialog and switching its active tab. I had tried to do something like that in the past and didn’t have good luck. I can’t remember if it was for the same reason I am now having trouble with your original script, or not, but it very well could be. Do you know if there is an alternate way of doing it that might be more reliable?

                      A 1 Reply Last reply Jun 28, 2017, 10:53 PM Reply Quote 0
                      • A
                        AZJIO AZJIO
                        last edited by Jun 28, 2017, 9:58 PM

                        Add before each command Sleep (1000) to see which command has failed

                        1 Reply Last reply Reply Quote 0
                        • C
                          Claudia Frank
                          last edited by Jun 28, 2017, 10:31 PM

                          If it is still about the status message, then be aware that it is ownerdrawed text,
                          which means that you need to resolve the pointer returned by the statusbar message used.
                          Well, I assume ControlGetText returns the message from SB_GETTEXT (never really used autoit).

                          A python script to get the text would look like this

                          #!/usr/bin/python
                          # -*- coding: utf-8 -*-
                          
                          ################################################################################# 
                          ## automate find dialog
                          import ctypes
                          from ctypes.wintypes import BOOL, HWND, LPARAM
                          
                          WNDENUMPROC = ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM)                         
                          
                          FindWindow = ctypes.windll.user32.FindWindowW
                          FindWindowEx = ctypes.windll.user32.FindWindowExW
                          SendMessage = ctypes.windll.user32.SendMessageW
                          EnumChildWindows = ctypes.windll.user32.EnumChildWindows
                          GetClassName = ctypes.windll.user32.GetClassNameW
                          create_unicode_buffer = ctypes.create_unicode_buffer
                          
                          
                          BM_CLICK = 0x00F5
                          SBT_OWNERDRAW = 0x1000
                          WM_USER = 0x400
                          
                          SB_GETTEXTLENGTHW = WM_USER + 12
                          SB_GETTEXTW = WM_USER + 13
                          
                          STATUSBAR_HANDLE = None
                          
                          def on_press(window_handle, button_text):
                              button_handle = FindWindowEx(window_handle, 0, u"Button", button_text)
                              SendMessage(button_handle, BM_CLICK, 0, 0)
                          
                          def get_result_from_statusbar(statusbar_item):
                              retcode = SendMessage(STATUSBAR_HANDLE, SB_GETTEXTLENGTHW, statusbar_item, 0)
                              length = retcode & 0xFFFF
                              type = (retcode >> 16) & 0xFFFF
                              _text = ''
                              
                              if type == SBT_OWNERDRAW:
                                  retcode = SendMessage(STATUSBAR_HANDLE, SB_GETTEXTW, statusbar_item, 0)
                                  _text =  'SBT_OWNERDRAW:{}'.format(ctypes.wstring_at(retcode))
                              else: # not sure if this gets called at all
                                  text_buffer = create_unicode_buffer(length)        
                                  retcode = SendMessage(STATUSBAR_HANDLE, SB_GETTEXTW, statusbar_item, text_buffer)
                                  _text = 'text_buffer:{}'.format(text_buffer[:length]) 
                                      
                              return _text
                          
                              
                          def EnumCallback(hwnd, lparam):
                              global STATUSBAR_HANDLE
                              curr_class = create_unicode_buffer(256)
                              GetClassName(hwnd, curr_class, 256)
                              if curr_class.value.lower() == "msctls_statusbar32":
                                  STATUSBAR_HANDLE = hwnd
                                  return False
                              return True
                          
                          notepad.menuCommand(MENUCOMMAND.SEARCH_FIND)
                          
                          find_hwnd = FindWindow(None, u'Find')
                          EnumChildWindows(find_hwnd, WNDENUMPROC(EnumCallback), 0)
                          
                          if STATUSBAR_HANDLE:
                              on_press(find_hwnd, u'Coun&t')
                              console.write(get_result_from_statusbar(0) + '\n')
                          

                          The script opens the find dialog, then gets the window handle from that dialog,
                          enumerates all its child windows (aka controls) and if a statusbar control has been found,
                          simulates an button press on Count button and writes the statusbar message to the console.

                          Cheers
                          Claudia

                          A 2 Replies Last reply Jun 28, 2017, 11:58 PM Reply Quote 4
                          • A
                            AZJIO AZJIO @Alan Kilborn
                            last edited by Jun 28, 2017, 10:53 PM

                            @Alan-Kilborn said:

                            Do you know if there is an alternate way of doing it that might be more reliable?

                            Using Au3Info.exe, check CLASS: # 32770

                            1 Reply Last reply Reply Quote 0
                            • A
                              Alan Kilborn @Claudia Frank
                              last edited by Jun 28, 2017, 11:58 PM

                              @Claudia-Frank

                              Once again you are amazing! I haven’t tried what you propose yet but I have no doubt it will be awesome.

                              1 Reply Last reply Reply Quote 0
                              • A
                                Alan Kilborn @Claudia Frank
                                last edited by Jun 29, 2017, 10:00 PM

                                @Claudia-Frank

                                I started working with and extending your script to do some other things on the Find dialog. I can get and set the state of radio buttons and checkboxes–yay! Some final things that I need to do are to get and/or set the text of the Find-what and Replace-with edit boxes (or comboboxes?). Is there a best way to do this? It isn’t as easy as with the other controls because these don’t have a caption. Can you post a short example of how to get text and set text to these edit controls on the Find dialog?

                                C 1 Reply Last reply Jun 29, 2017, 10:53 PM Reply Quote 0
                                • C
                                  Claudia Frank @Alan Kilborn
                                  last edited by Jun 29, 2017, 10:53 PM

                                  @Alan-Kilborn

                                  Hi Alan,

                                  you right, edit box aren’t easy to identify but, as far as I remember, you can rely on the order (z-order) how the controls get identified/returned.

                                  So in this case you could check when the static box (aka label) returns with &Find what and set a
                                  flag and when the edit control appears, check if flag is set and treat it. To retrieve or set the text
                                  you can use the api functions GetWindowText and SetWindowText.

                                  A simple example like this (only the callback part and the definitions of the code)

                                  GetWindowText = ctypes.windll.user32.GetWindowTextW
                                  GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
                                  SetWindowText = ctypes.windll.user32.SetWindowTextW
                                  
                                  STATUSBAR_HANDLE = None
                                  FIND_WHAT = None
                                  REPLACE_WITH = None
                                  
                                  
                                  def EnumCallback(hwnd, lparam):
                                      global STATUSBAR_HANDLE
                                      global FIND_WHAT
                                      global REPLACE_WITH
                                      
                                      curr_class = ctypes.create_unicode_buffer(256)
                                      GetClassName(hwnd, curr_class, 256)
                                      
                                      length = GetWindowTextLength(hwnd)
                                      buff = ctypes.create_unicode_buffer(length + 1)
                                      GetWindowText(hwnd, buff, length + 1)
                                      
                                      if curr_class.value.lower() == 'msctls_statusbar32':
                                          STATUSBAR_HANDLE = hwnd
                                          # return False
                                      elif curr_class.value.lower() == 'static':
                                          if buff.value == '&Find what :':
                                              FIND_WHAT = True
                                          elif buff.value == 'Rep&lace with :':
                                              REPLACE_WITH = True
                                      elif curr_class.value.lower() == 'edit':
                                          if FIND_WHAT:
                                              SetWindowText(hwnd, u'xyz789')
                                              FIND_WHAT = False
                                          elif REPLACE_WITH:
                                              REPLACE_WITH = False
                                              SetWindowText(hwnd, u'123abc')
                                      else:
                                          console.write('{}({:^7}) : {}'.format(curr_class.value,hwnd, buff.value) + '\n' )
                                      return True
                                  

                                  Cheers
                                  Claudia

                                  S 1 Reply Last reply Jun 30, 2017, 6:37 PM Reply Quote 2
                                  • S
                                    Scott Sumner @Claudia Frank
                                    last edited by Jun 30, 2017, 6:37 PM

                                    So the ideas presented here by @Claudia-Frank I think will allow me to stop using AutoIt in favor of Pythonscript for controlling the Find dialog functions. It seems very nice. To bring this thread back to where it began, here’s a P.S. based upon Claudia’s work that puts the current selection (which can include multiple lines) into the Find dialog’s Replace-with box. The part of it I question for general usage is the .decode('utf-8') – it seems to work for me, but I’m not an encoding expert by any means.

                                    Here’s ReplaceWithBoxFromSelection.py :

                                    import ctypes
                                    from ctypes.wintypes import BOOL, HWND, LPARAM
                                    
                                    WNDENUMPROC = ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM)
                                    
                                    FindWindow = ctypes.windll.user32.FindWindowW
                                    FindWindowEx = ctypes.windll.user32.FindWindowExW
                                    SendMessage = ctypes.windll.user32.SendMessageW
                                    EnumChildWindows = ctypes.windll.user32.EnumChildWindows
                                    GetClassName = ctypes.windll.user32.GetClassNameW
                                    GetWindowText = ctypes.windll.user32.GetWindowTextW
                                    GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
                                    SetWindowText = ctypes.windll.user32.SetWindowTextW
                                    create_unicode_buffer = ctypes.create_unicode_buffer
                                    
                                    replace_tab_caption  = u'Replace'
                                    replacewith_caption = u'Rep&lace with :'
                                    replacewith_is_next_ctrl = False
                                    replacewith_handle = None
                                    
                                    def EnumCallback(hwnd, lparam):
                                        global replacewith_is_next_ctrl
                                        global replacewith_handle
                                        curr_class = create_unicode_buffer(256)
                                        GetClassName(hwnd, curr_class, 256)
                                        length = GetWindowTextLength(hwnd)
                                        buff = ctypes.create_unicode_buffer(length + 1)
                                        GetWindowText(hwnd, buff, length + 1)
                                        if curr_class.value.lower() == 'static':
                                            if buff.value == replacewith_caption:
                                                replacewith_is_next_ctrl = True
                                        elif curr_class.value.lower() == 'edit':
                                            if replacewith_is_next_ctrl:
                                                replacewith_handle = hwnd
                                                return False  # stop enumeration
                                        return True  # let enumeration continue
                                    
                                    def main():
                                        msg = ''
                                        if editor.getSelections() == 1 and not editor.getSelectionEmpty():
                                            sel = editor.getSelText()
                                            if len(sel) > 2046:
                                                sel = sel[:2046]
                                                msg += 'Warning:  Selected text too long for replace-with box; truncating to 2046 characters.  '
                                            notepad.menuCommand(MENUCOMMAND.SEARCH_REPLACE)
                                            find_dialog_hwnd = FindWindow(None, replace_tab_caption)
                                            if find_dialog_hwnd:
                                                EnumChildWindows(find_dialog_hwnd, WNDENUMPROC(EnumCallback), 0)
                                                if replacewith_handle:
                                                    if SetWindowText(replacewith_handle, sel.decode('utf-8')) == 0:
                                                        msg += 'Error:  Problem setting window text'
                                                else:
                                                    msg += 'Error:  Bad value for replacewith_handle'
                                            else:
                                                msg += 'Error:  Bad value for find_dialog_hwnd'
                                        else:
                                            msg += 'Warning:  Nothing to copy into replace-with field'
                                        if len(msg) > 0: notepad.messageBox(msg)
                                    
                                    main()
                                    
                                    C 1 Reply Last reply Jun 30, 2017, 9:43 PM Reply Quote 2
                                    • C
                                      Claudia Frank @Scott Sumner
                                      last edited by Jun 30, 2017, 9:43 PM

                                      @Scott-Sumner

                                      The part of it I question for general usage is the .decode(‘utf-8’)

                                      I assume your way should work, regardless of the encoding used by the user,
                                      if I understand scintilla and pythonscript plugin correctly.
                                      editor.getSelText() always returns a byte string (python str) but, because we defined
                                      unicode version of SetWindowText, this string needs to be converted as you did.
                                      Maybe I’m wrong.

                                      Cheers
                                      Claudia

                                      S 1 Reply Last reply Jun 30, 2017, 10:49 PM Reply Quote 0
                                      • S
                                        Scott Sumner @Claudia Frank
                                        last edited by Scott Sumner Jun 30, 2017, 10:49 PM Jun 30, 2017, 10:49 PM

                                        @Claudia-Frank

                                        I did notice something else that was a bit odd (and drove me a little nuts until I figured out what was going on) when I was working on that script. Let’s see if I can describe it. Usually I work with English_customizable.xml loaded, and everything is consistent and as-expected. When working on that script, I switched back to English.xml, thinking that if I share the script here, it should not use my specific and custom Find dialog captions, but rather the generic English ones.

                                        With English configured, I noticed that when Notepad++ starts up, it doesn’t exactly have English.xml set up, it has something close to it, but not exactly! I found that if I go back into the Preferences, and again select English from the dropdown (even though it is already selected), and have the Find dialog up at the same time, I can watch subtle changes occur in the Find dialog’s label/caption fields. For example, and I can watch a space be inserted (or removed) between “Find what” and the colon that follows (same for “Replace with”. I really have no idea why this is happening. Again, this only happens with English.xml, not English_customizable.xml.

                                        The reason it was making me crazy was that I’d work on the script, have it working fine, then later I would notice it was breaking because it couldn’t find the controls. I kept changing the text strings to make it work and then later it would break again.

                                        1 Reply Last reply Reply Quote 0
                                        • guy038G
                                          guy038
                                          last edited by Jul 1, 2017, 9:23 AM

                                          Hello, @scott-sumner and @claudia-frank,

                                          Claudia, your automatic counting of any normal selection, multi-lines or not, works fine !

                                          Scott, your ReplaceWithBoxFromSelection.py script is working nice, too !. I’ve just noticed that your script, automatically, copies the current normal and unique selection, BOTH, in the Find what : and in the Replace with: boxes. Is it the normal behaviour or am I wrong about it ?


                                          This topic makes me think about an other possibility ! Let’s suppose that the option Settings > Preferences…> Editing > Multi-Editing Settings is enabled

                                          Now, the goal would be :

                                          • To define TWO selected blocks of text, which could, independently, include multiple lines

                                          • To Write a Python script which :

                                            • Opens the Find/Replace dialog

                                            • Writes the first user selection, in the Find what: box

                                            • Writes the second user selection, in the Replace with: box

                                          Scott and Claudia, what is your feeling about it ?

                                          Best Regards,

                                          guy038

                                          C S 3 Replies Last reply Jul 1, 2017, 11:53 AM Reply Quote 0
                                          • First post
                                            Last post
                                          The Community of users of the Notepad++ text editor.
                                          Powered by NodeBB | Contributors