Community
    • Login

    How do I "replace all" in columnar selection?

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    column modereplace all
    10 Posts 3 Posters 1.2k 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.
    • rxsg 5176R
      rxsg 5176
      last edited by

      I’m trying to align a bunch of stuff and typically what I do in other text editors is a pair of find/replace commands, but when I have columnar data selected in npp and I go to use replace the “In selection” box is grey’d out.

      for example on this:

      [ITEM]=[ReqLineDetails.ITEM]
      [ITEM_TYPE]=[ReqLineDetails.ITEM_TYPE]
      [QUANTITY]=[ReqLineDetails.QUANTITY]
      [UNIT_COST]=[ReqLineDetails.UNIT_COST]
      [ENTERED_UOM]=[ReqLineDetails.ENTERED_UOM]
      ...
      [PO_CODE]=[ReqLineDetails.PO_CODE]
      [PO_NUMBER]=[ReqLineDetails.PO_NUMBER]
      

      I would first find and replace

      "="
      

      with

      "                       ="
      

      to create a ‘buffer zone’

      [ITEM]                       =[ReqLineDetails.ITEM]
      [ITEM_TYPE]                       =[ReqLineDetails.ITEM_TYPE]
      [QUANTITY]                       =[ReqLineDetails.QUANTITY]
      [UNIT_COST]                       =[ReqLineDetails.UNIT_COST]
      [ENTERED_UOM]                       =[ReqLineDetails.ENTERED_UOM]
      ...
      [PO_CODE]                       =[ReqLineDetails.PO_CODE]
      [PO_NUMBER]                       =[ReqLineDetails.PO_NUMBER]
      

      then drag a rectangle using columnar select (sorry I couldn’t figure out the md to show the highlighted text-brick) and replace

      " "
      

      with

      ""
      

      in the selection to get alignment

      [ITEM]        =[ReqLineDetails.ITEM]
      [ITEM_TYPE]   =[ReqLineDetails.ITEM_TYPE]
      [QUANTITY]    =[ReqLineDetails.QUANTITY]
      [UNIT_COST]   =[ReqLineDetails.UNIT_COST]
      [ENTERED_UOM] =[ReqLineDetails.ENTERED_UOM]
      ...
      [PO_CODE]     =[ReqLineDetails.PO_CODE]
      [PO_NUMBER]   =[ReqLineDetails.PO_NUMBER]
      
      

      where ... indicates enough lines of code to make it no fun to do each individually.

      or is there maybe a better way to accomplish this in npp?

      Alan KilbornA 1 Reply Last reply Reply Quote 0
      • Alan KilbornA
        Alan Kilborn @rxsg 5176
        last edited by

        @rxsg-5176 said in How do I "replace all" in columnar selection?:

        but when I have columnar data selected in npp and I go to use replace the “In selection” box is grey’d out.

        Yes, sadly a replace-in-selection only works upon the main selection. A columnar block is L selections, where L is the number of lines in the block. And so, such a replacement only works upon the main selection, or the one touching the caret after the block is made.

        I’m a bit surprised the In selection box is “greyed out” for you. For me in this situation it isn’t. ??

        Alan KilbornA rxsg 5176R 2 Replies Last reply Reply Quote 0
        • Alan KilbornA
          Alan Kilborn @Alan Kilborn
          last edited by

          @Alan-Kilborn said in How do I "replace all" in columnar selection?:

          I’m a bit surprised the In selection box is “greyed out” for you. For me in this situation it isn’t. ??

          Oops, actually it is greyed out for me as well. I had set up a test where I selected L individual blocks that just appeared visually like a column block. Then I got distracted and when I came back to it I forgot that it wasn’t a real column block. In this scenario as well In Selection should be greyed out, but it is not.

          1 Reply Last reply Reply Quote 0
          • rxsg 5176R
            rxsg 5176 @Alan Kilborn
            last edited by

            @Alan-Kilborn I’m running out-of-the-box Notepad++ v7.7.1 (32-bit) with no added plugins or macros. In the case of multiple selection regions such as columnar selections or otherwise, my expected behavior would be that the replace action would iterate over each region when the In selection box was ticked.

            Alan KilbornA 1 Reply Last reply Reply Quote 0
            • Alan KilbornA
              Alan Kilborn @rxsg 5176
              last edited by Alan Kilborn

              @rxsg-5176 said in How do I "replace all" in columnar selection?:

              my expected behavior would be that the replace action would iterate over each region when the In selection box was ticked.

              I fully agree. But, and this is what I said after “Sadly…” above, it doesn’t. As a user, I’ve come to accept this. There are probably some script-based solutions to replacing in a column block…

              BTW, others agree. Here are some links:

              https://community.notepad-plus-plus.org/topic/14644/replacement-in-vertical-block
              https://community.notepad-plus-plus.org/topic/15606/how-to-replace-in-block-mode
              https://github.com/notepad-plus-plus/notepad-plus-plus/issues/5113

              rxsg 5176R 1 Reply Last reply Reply Quote 0
              • rxsg 5176R
                rxsg 5176 @Alan Kilborn
                last edited by

                @Alan-Kilborn thanks, I guess we’re kinda on our own here. I’ve run out of time to look into it today, but I think a solution should lie near line 1899 of https://github.com/notepad-plus-plus/notepad-plus-plus/blob/master/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp

                Alan KilbornA 1 Reply Last reply Reply Quote 0
                • Alan KilbornA
                  Alan Kilborn @rxsg 5176
                  last edited by Alan Kilborn

                  @rxsg-5176 said:

                  but I think a solution should lie near line 1899

                  Well, I don’t think there is a “simple” solution to this. The “replace” function is designed to use a starting position and an ending position. Normally the start is beginning-of-doc and ending is end-of-doc. It is a simple matter to change those values when In selection is ticked with a single selection.

                  Multiple (or column) selections would require some processing to occur “several times” over as many selections as are in existence. While in theory this is not a hard thing, the code changes required would not be just a few.

                  And since “larger” code changes by non-Notepad++ developers are quite often rejected, it is probably worth leaving this to them. As issue #5113 (and earlier issues) has been left sitting open for quite a length of time, I’d guess they have chosen not to do it, or haven’t had time yet.

                  However, if you want to work on a solution for this in the code, from my perspective, that would be great.

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

                    Hello, @rxsg-5176, @alan-kilborn and All,

                    @rxsg-5176, your goal is very easy to reach with the use of regular expressions ;-)) I use, very often, this magic regex !


                    Let Co be the column number where the first char of second column must begin

                    Let Ch be the character which must be aligned, at position Co, beginning the second column

                    Then, the generic regex to use is :

                    SEARCH (?-s)(Ch)|^.{Co-1}\K\x20*(Ch)

                    REPLACE (?1\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)(?2)Ch

                    Note : Add a consequent amount of space chars, between (?1 and ), in the replacement regex


                    So, the road map is :

                    • Decide of a column number where the Ch character must be. I chose 23 for column Co of the = sign

                    • Open the Replace dialog ( Ctrl + H )

                    • Substitute the values to form a valid search and replace regular expressions :

                    • SEARCH (?-s)(=)|^.{22}\K\x20*(=) ( as the Co-1 re^presents the 23-1 first characters, of each line which are not changed )

                    • REPLACE (?1\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)(?2)= ( Lot of space chars inserted between (?1 and ) )

                    • Click on the Wrap around option to process all the current file or tick the In selection option to limit the process to that selection

                    • Click on the Replace All button TWICE ( Do not use the Replace button ! )

                      • After the first click, a lot of space chars are added, before the Ch character ( = )

                      • After the second click, all items of the second column are aligned, with the = character at the Co position, so 23

                    Notes :

                    • Any subsequent click on the Replace All button just replaces each Ch char, at position Co, by itself !

                    • In the replacement zone, you may, of course, type in real space chars, instead of several \x20 This syntax is necessary, in posts, as blank chars are compressed, when normal text is invoked :-(


                    So, from your original text :

                    [ITEM]=[ReqLineDetails.ITEM]
                    [ITEM_TYPE]=[ReqLineDetails.ITEM_TYPE]
                    [QUANTITY]=[ReqLineDetails.QUANTITY]
                    [UNIT_COST]=[ReqLineDetails.UNIT_COST]
                    [ENTERED_UOM]=[ReqLineDetails.ENTERED_UOM]
                    ...
                    [PO_CODE]=[ReqLineDetails.PO_CODE]
                    [PO_NUMBER]=[ReqLineDetails.PO_NUMBER]
                    

                    After a first click on the Replace All button, we get :

                    [ITEM]                 =[ReqLineDetails.ITEM]
                    [ITEM_TYPE]                 =[ReqLineDetails.ITEM_TYPE]
                    [QUANTITY]                 =[ReqLineDetails.QUANTITY]
                    [UNIT_COST]                 =[ReqLineDetails.UNIT_COST]
                    [ENTERED_UOM]                 =[ReqLineDetails.ENTERED_UOM]
                    ...
                    [PO_CODE]                 =[ReqLineDetails.PO_CODE]
                    [PO_NUMBER]                 =[ReqLineDetails.PO_NUMBER]
                    

                    And, after a second click on the Replace All button, we obtain the expected text :

                    [ITEM]                =[ReqLineDetails.ITEM]
                    [ITEM_TYPE]           =[ReqLineDetails.ITEM_TYPE]
                    [QUANTITY]            =[ReqLineDetails.QUANTITY]
                    [UNIT_COST]           =[ReqLineDetails.UNIT_COST]
                    [ENTERED_UOM]         =[ReqLineDetails.ENTERED_UOM]
                    ...
                    [PO_CODE]             =[ReqLineDetails.PO_CODE]
                    [PO_NUMBER]           =[ReqLineDetails.PO_NUMBER]
                    

                    Best Regards,

                    guy038

                    P.S. :

                    Of course, if the equal signs are randomly located, as below, it does not matter !

                    [ITEM]    =[ReqLineDetails.ITEM]
                    [ITEM_TYPE] =[ReqLineDetails.ITEM_TYPE]
                    [QUANTITY]      =[ReqLineDetails.QUANTITY]
                    [UNIT_COST]=[ReqLineDetails.UNIT_COST]
                    [ENTERED_UOM]=[ReqLineDetails.ENTERED_UOM]
                    ...
                    [PO_CODE]       =[ReqLineDetails.PO_CODE]
                    [PO_NUMBER]=[ReqLineDetails.PO_NUMBER]
                    

                    It will end up with the correct text, anyway !

                    [ITEM]                =[ReqLineDetails.ITEM]
                    [ITEM_TYPE]           =[ReqLineDetails.ITEM_TYPE]
                    [QUANTITY]            =[ReqLineDetails.QUANTITY]
                    [UNIT_COST]           =[ReqLineDetails.UNIT_COST]
                    [ENTERED_UOM]         =[ReqLineDetails.ENTERED_UOM]
                    ...
                    [PO_CODE]             =[ReqLineDetails.PO_CODE]
                    [PO_NUMBER]           =[ReqLineDetails.PO_NUMBER]
                    
                    1 Reply Last reply Reply Quote 0
                    • Alan KilbornA
                      Alan Kilborn
                      last edited by Alan Kilborn

                      Earlier, I said:

                      I selected L individual blocks that just appeared visually like a column block. Then I got distracted and when I came back to it I forgot that it wasn’t a real column block. In this scenario as well In Selection should be greyed out, but it is not.

                      Then I noticed in the 7.8.2 RC change log the following:

                      1. Enhance “In Selection” option in Find dialog.

                      I tried my test above again with 7.8.2 (was trying earlier with 7.8.1), and this time the In Selection box actually IS greyed out.

                      IMO that’s a fairly lame way of describing this behavior change, if that’s truly what is meant by that change log entry. But I suppose the behavior change is a step forward.

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

                        Hi, All,

                        I even found out a shorter syntax, both in the search and replacement parts !

                        So, the generic regex to use would be :

                        SEARCH (?-s)(()|^.{Co-1}\K\x20*)(?=Ch)

                        REPLACE ?2\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20


                        As the Ch character is the = sign and should be located at position Co = 23, we get the exact regex syntax :

                        SEARCH (?-s)(()|^.{22}\K\x20*)(?==)

                        REPLACE ?2\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20

                        Notes :

                        • Beware that the empty group 2 (), before the alternation symbol |, is needed !!

                        • If the 1st alternative is chosen, the regex engine looks for an empty string, only if followed with an = sign

                          • In replacement, this empty string is replaced with the range of space characters, as group 2 exists
                        • If the 2nd alternative is chosen, the regex engine looks for a range of space characters, beginning at position 23, but only if followed with an = sign

                          • In replacement, this non-wanted range of space characters are simply deleted, as group 2 does not exist

                        Cheers,

                        guy038

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