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 columnThen, 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)
ChNote : 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 the23-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 theIn selection
option to limit the process to that selection -
Click on the
Replace All
button TWICE ( Do not use theReplace
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 theCo
position, so23
-
Notes :
-
Any subsequent click on the
Replace All
button just replaces each Ch char, at positionCo
, 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:
- 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
- In replacement, this empty string is replaced with the range of space characters, as group
-
If the
2nd
alternative is chosen, the regex engine looks for a range of space characters, beginning at position23
, 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
- In replacement, this non-wanted range of space characters are simply deleted, as group
Cheers,
guy038
-