Community
    • Login

    Macro: Delete lines that contains text in clipboard

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    9 Posts 4 Posters 4.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.
    • APica_AlA
      APica_Al
      last edited by

      Hi,

      I want to create a simple macro to delete the lines that contains the string that is stored in the clipboard (when is executed). The process that I follow is:

      • Start recording macro
      • Open the find window and paste wanted text XXX into the Mark section. Then mark the lines.
      • Execute the option “Delete marked lines”.

      The problem is when I change the content of the string to YYY (clipboard), the Macro keeps marking and deleting the string I’ve used to record the macro (XXX).

      How can I change the macro to use the content of the clipboard instead of the static string?

      Thank you

      Scott SumnerS 1 Reply Last reply Reply Quote 1
      • Scott SumnerS
        Scott Sumner @APica_Al
        last edited by

        @APica_Al

        The way it works is that only when you “run” a “find”-related function, that is when all of the settings (Find’s edit boxes, checkboxes, etc) get captured into the macro.

        Note that “run” here means “press a button to do a find operation”. So you can be macro recording and change all of the individual settings all you want but nothing is recorded until you actually press the (e.g.'s) Find Next button or the Find All button.

        So…in your case, when you paste from the clipboard into the Find what zone, that paste action isn’t recorded into the macro…but at some point farther on in your actions the text from the paste is. Thus the text becomes hardcoded as a constant into the macro.

        1 Reply Last reply Reply Quote 1
        • APica_AlA
          APica_Al
          last edited by

          Thank you.

          So, is there a way to reload that string text each time? I’ve found the shortcuts.xml file with the macro code, but I don’t know which commands to use (if they exist) .

          Scott SumnerS 1 Reply Last reply Reply Quote 0
          • Scott SumnerS
            Scott Sumner @APica_Al
            last edited by

            @APica_Al said:

            is there a way to reload that string text each time

            AFAIK, no. shortcuts.xml gets read into memory when Notepad++ starts; no (reasonable!) way to “intercept” that data item to insert something else…which I think is what you are considering…??

            APica_AlA 1 Reply Last reply Reply Quote 0
            • APica_AlA
              APica_Al @Scott Sumner
              last edited by

              @Scott-Sumner said:

              AFAIK, no. shortcuts.xml gets read into memory when Notepad++ starts; no (reasonable!) way to “intercept” that data item to insert something else…which I think is what you are considering…??

              Exactly. That’s why I wanted to read the data from clipboard dynamically.

              Thank you anyway

              1 Reply Last reply Reply Quote 0
              • dinkumoilD
                dinkumoil
                last edited by dinkumoil

                @APica_Al

                I’ve found a possible solution without using the macro feature of Notepad++ but it takes some effort.

                1. You need to install the NppExec Notepad++ plugin (available via PluginManager).

                2. You need a helper program - NirCmdC by Nir Sofer. It is available here, packaged with the GUI version (NirCmd) in a ZIP file (scroll down to the end of the site to find the download link).

                3. Unpack the ZIP file of NirCmdC to a folder of your choice.

                4. Go to Menu Plugins -> NppExec -> Execute... and paste the following code to the Command(s) area:

                  set NirCmdPath=<Path-to-the-folder-of-step-3>\nircmdc.exe
                  set SearchAndMarkDialogTitle=<Title-of-Npp’s-Mark-window-(depends on your locale, it’s “Mark” in english)>

                  npp_sendmsg WM_COMMAND IDM_SEARCH_MARK

                  “$(NirCmdPath)” sendkeypress ctrl+v
                  “$(NirCmdPath)” sendkeypress enter
                  “$(NirCmdPath)” win close title “$(SearchAndMarkDialogTitle)”

                  npp_sendmsg WM_COMMAND IDM_SEARCH_DELETEMARKEDLINES

                  unset SearchAndMarkDialogTitle
                  unset NirCmdPath

                5. Perform the required changes in lines 1 and 2 and save the code e.g. as DelLinesContainingClipboardContent.

                6. Go to Menu Plugins -> NppExec -> Advanced options.... Here you can associate the script of step 5 to a new entry in the Macros menu.

                7. Go to Menu Settings -> Shortcut Mapper... and assign the menu entry to a keyboard shortcut of your choice.

                8. Go to Menu Search -> Mark... and check the options Bookmark line and Purge for each search. Maybe it is possible to automate this using NirCmdC but this is your “homework” ;-).

                Now you can select the word you are searching for, hit CTRL+C, hit the keyboard shortcut of step 7, and all the lines containing the selected word will be deleted.

                1 Reply Last reply Reply Quote 1
                • Vitaliy DovganV
                  Vitaliy Dovgan
                  last edited by

                  Wow, this is very nice!
                  The script can be simplified a little:

                  set local NirCmdPath = <Path-to-the-folder-of-step-3>\nircmdc.exe
                  
                  npp_sendmsg WM_COMMAND IDM_SEARCH_MARK // show the Mark dialog
                  
                  "$(NirCmdPath)" sendkeypress ctrl+v // paste from the clipboard
                  "$(NirCmdPath)" sendkeypress enter // apply - i.e. mark all
                  "$(NirCmdPath)" sendkeypress esc // close the Mark dialig
                  
                  npp_sendmsg WM_COMMAND IDM_SEARCH_DELETEMARKEDLINES // delete the lines
                  // don't forget to check "Bookmark line" and "Purge for each search" for that!
                  
                  1 Reply Last reply Reply Quote 1
                  • dinkumoilD
                    dinkumoil
                    last edited by

                    @Vitaliy-Dovgan

                    Nice optimization.


                    For the script to work on ALL lines of course option Wrap around must be checked too.

                    1 Reply Last reply Reply Quote 0
                    • Scott SumnerS
                      Scott Sumner
                      last edited by

                      Well if we are opening it up to scripts, then I’ll offer up the following Pythonscript; I call it DeleteLinesWithClipboardText.py:

                      def DLWCT__main():
                      
                          if not editor.getSelectionEmpty(): return  # keep it simple; maybe prompt user to cancel selection and re-run...
                          if not editor.canPaste(): return           # keep it simple; maybe prompt user that no text is in clipboard...
                          orig_document_len = editor.getTextLength()
                          editor.beginUndoAction()
                          editor.paste()
                          pasted_text_len = editor.getTextLength() - orig_document_len
                          curr_pos = editor.getCurrentPos()
                          clipboard_text = editor.getTextRange(curr_pos - pasted_text_len, curr_pos)
                          editor.deleteRange(curr_pos - pasted_text_len, pasted_text_len)
                          if '\r' in clipboard_text or '\n' in clipboard_text:
                              # keep it simple; don't allow multiline search text
                              editor.endUndoAction()
                              return
                          del_line_list = []
                          find_start_pos = 0
                          while True:
                              f = editor.findText(FINDOPTION.MATCHCASE, find_start_pos, editor.getTextLength(), clipboard_text)
                              if f == None: break
                              (found_start_pos, found_end_pos) = f
                              line_nbr = editor.lineFromPosition(found_start_pos)
                              if len(del_line_list) > 0:
                                  if del_line_list[0] != line_nbr: del_line_list.insert(0, line_nbr)
                              else:
                                  del_line_list.append(line_nbr)
                              find_start_pos = found_end_pos
                          for line in del_line_list: editor.deleteLine(line)
                          editor.endUndoAction()
                      
                      DLWCT__main()
                      

                      The only tricky part is in getting the clipboard data. I paste the clipboard contents into the document, read what was just pasted, and then delete those contents. After that it is a simple matter to locate the desired text and delete the lines it occurs on.

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