How do I "replace all" in columnar selection?



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



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



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



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



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



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



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


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



  • 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


Log in to reply