Column-block Paste problem with source block having jagged right edge
-
Sometimes I need to copy column block data and paste it into the middle (column-wise) of existing text. This works fine as long as all of the lines in the column are full (i.e., all of the columns are populated–if it is an “N” column block, then each column truly has N characters in it); however, it gets messy if some of the lines in the column block are shorter than N.
Perhaps an example explains better:
Selecting and copying the column block defined by A and G (including those characters) in the following data:
aaaaaaaAaaaaaaaaaaaaa bbbbbbbbbb ccc d eeee ffffffff gggggggggggGgggg
…and then pasting that column block into this data immediately to the right of the column of - characters:
1111111-111111111111111111 2222222-222222222222222222 3333333-333333333333333333 4444444-444444444444444444 5555555-555555555555555555 6666666-666666666666666666 7777777-777777777777777777
(note the nicely aligned right edge!)
results in:
1111111-Aaaaa111111111111111111 2222222-bbb222222222222222222 3333333-333333333333333333 4444444-444444444444444444 5555555-555555555555555555 6666666-f666666666666666666 7777777-ggggG777777777777777777
(note the now messy right-edge!)
but it would be more desirable to result in:
1111111-Aaaaa111111111111111111 2222222-bbb 222222222222222222 3333333- 333333333333333333 4444444- 444444444444444444 5555555- 555555555555555555 6666666-f 666666666666666666 7777777-ggggG777777777777777777
(note again the nicely aligned right edge!)
Is there a reasonable way to make Notepad++ do this, (without going to the trouble of padding the shorter source lines with spaces on their right first, in order to “fill out” the column block)?
-
That’s because Npp has a problem with blank spaces: It simply ignores them. I too think that’s a wrong action. It bothers me when I press Home to go to the beginning of a line that starts with blank spaces. Notepad++ always takes me to the beginning of the first non-blank-space word, instead of the very beginning of the line.
Maybe a new feature… although I heard from posters here that the author is quite stubborn in ignoring feature-requests…
Peace be with you and this community!
-
@Parpaluck209 said:
That’s because Npp has a problem with blank spaces: It simply ignores them.
No, that’s not it. PLEASE try not to spread misinformation via this Community. If you don’t know something to a high degree of certainty, don’t state it. Others might read these postings in the future and be misled by your wrong statements. Sure, everybody is wrong occasionally, but I can tell from what you stated that you have no idea what you are talking about.
-
Hello, @alan-kilborn,
Alan, the old TextFX plugin has this kind of feature ( TextFX > TextFX Edit > Paddle rectangular selection with spaces )
But, here is, below, my work-around, with native N++ commands !
-
Perform a single left click after the G letter
-
Press, simultaneously, the
Alt
andShift
keys and hit, six times, on theUp
arrow
=> A 6 x 0 column block should be defined, at column 13
- Hit the Space key and, right after, the Backspace key
=> This time, the 6 x 0 column block is preceded by some Space characters
- Now, press, simultaneously, the
Alt
andShift
keys and hit, five times, on theLeft
arrow
=> The column block between the letters A and G included, containing space characters, is, then, selected
-
Hit the usual
Ctrl + C
shortcut to copy this column block selection -
If you prefer to keep that block unchanged, hit, twice, the
Ctrl + Z
shortcut -
Finally, move the caret to the line 1111111-111111111111111111, after the dash character
-
Hit the usual
Ctrl + V
shortcut to column-paste it, at the caret position
=> The seven “digit-lines” should be, correctly, modified, as below :
1111111-Aaaaa111111111111111111 2222222-bbb 222222222222222222 3333333- 333333333333333333 4444444- 444444444444444444 5555555- 555555555555555555 6666666-f 666666666666666666 7777777-ggggG777777777777777777
Cheers,
guy038
-
-
From reading your description, I thought it was going to be a painful process. But no, it is pretty clean and it works nicely. Nice technique.
I’ve had a Pythonscript (surprise!) for doing this sort of operation. It works well; I’ve noticed it seems a bit slow on a large chunk of data, but no matter. Also, the source data (in the clipoard) can be a column block or a normal stream block (in which case the varying length lines are turned into a truly rectangular column block upon “pasting”).
Start by copying some data to the clipboard, then put the caret at the desired Top/Left insertion point. Then invoke PasteAsTrueRectBlock.py:
import ctypes def PATRB__GetClipboardText(): # see https://notepad-plus-plus.org/community/topic/12525/replace-current-line-without-inserting-a-new-line/12 # not the most error-proof function in the world! if ctypes.windll.user32.OpenClipboard(None): clipboard_handle = ctypes.windll.user32.GetClipboardData(1) if clipboard_handle: pointer_to_content = ctypes.windll.kernel32.GlobalLock(clipboard_handle) clipboard_data = ctypes.c_char_p(pointer_to_content).value ctypes.windll.kernel32.GlobalUnlock(clipboard_handle) else: return '' # invalid handle ctypes.windll.user32.CloseClipboard() return clipboard_data else: return '' # error def PATRB__main(): # "paste" current clipboard contents as a column block with TOP LEFT of resultant block at the caret point current_text_in_clipboard = PATRB__GetClipboardText() if editor.canPaste() and len(current_text_in_clipboard) > 0 and editor.getSelections() == 1 and editor.getSelectionEmpty(): line_ending = [ '\r\n', '\r', '\n' ][notepad.getFormatType()] lines_list = current_text_in_clipboard.split(line_ending) if len(lines_list[-1]) == 0: lines_list.pop() # if text in clipboard ended with line_ending, need to remove empty element at end of list longest_line_length = max([ len(z) for z in lines_list ]) uniform_horiz_len_lines_list = [ z + ' ' * (longest_line_length - len(z)) for z in lines_list ] # pad shorter lines out to length of longest starting_line_nbr = editor.lineFromPosition(editor.getCurrentPos()) orig_line_count = editor.getLineCount() insert_starting_col = editor.getColumn(editor.getCurrentPos()) + editor.getSelectionNCaretVirtualSpace(0) editor.beginUndoAction() if starting_line_nbr + len(uniform_horiz_len_lines_list) > orig_line_count - 1: # need to add some blank lines at bottom of file to hold line data we will be inserting nbr_of_new_lines_to_add = starting_line_nbr + len(uniform_horiz_len_lines_list) - orig_line_count editor.appendText(line_ending * nbr_of_new_lines_to_add) for line_nbr_offset in xrange(len(uniform_horiz_len_lines_list)): editor.gotoPos(editor.findColumn(starting_line_nbr + line_nbr_offset, insert_starting_col)) # try to go to the correct column; if can't, go to last column of the line col_data_to_ins = '' col_diff = insert_starting_col - editor.getColumn(editor.getCurrentPos()) if col_diff: col_data_to_ins = ' ' * col_diff # the correct column does not exist; pad with spaces out to the correct column: col_data_to_ins += uniform_horiz_len_lines_list[line_nbr_offset] editor.addText(col_data_to_ins) editor.endUndoAction() PATRB__main()
-
I found some deficiencies in
PasteAsTrueRectBlock.py
. There are situations where the desired rectangular blocking can’t be known at paste time, but only at copy time. So I wroteCopyAsTrueRectBlock.py
. Running this new script on a single selection, be it a normal selection or a column-based one, will result in a truly rectangular block in the clipboard, which can subsequently be pasted via a normal paste (e.g., ctrl+v). As a bonus, the logic for this script is simpler and shorter than the earlier script. :-)Here’s
CopyAsTrueRectBlock.py
:def CATRB__main(): # (C)opy (A)s (T)rue (R)ectangular (B)lock if not editor.getSelectionEmpty(): if editor.selectionIsRectangle() or editor.getSelections() == 1: line_ending = [ '\r\n', '\r', '\n' ][notepad.getFormatType()] lines_list = editor.getSelText().split(line_ending) if len(lines_list[-1]) == 0: lines_list.pop() # if text ended with line_ending, need to remove empty element at end of list rect_width = 0 if editor.selectionIsRectangle(): rect_anchor = editor.getColumn(editor.getRectangularSelectionAnchor()) rect_anchor += editor.getRectangularSelectionAnchorVirtualSpace() rect_caret = editor.getColumn(editor.getRectangularSelectionCaret()) rect_caret += editor.getRectangularSelectionCaretVirtualSpace() rect_width = abs(rect_anchor - rect_caret) longest_line_length = max([ len(line) for line in lines_list ] + [ rect_width ]) # pad shorter lines out to length of longest: truly_rectangular_lines_list = [ line + ' ' * (longest_line_length - len(line)) for line in lines_list ] remember_active_file = notepad.getCurrentFilename() notepad.new() editor.addText(line_ending.join(truly_rectangular_lines_list) + line_ending) editor.setSel(0, (longest_line_length + len(line_ending)) * len(truly_rectangular_lines_list)) editor.setSelectionMode(SELECTIONMODE.RECTANGLE) editor.copy() editor.undo() notepad.close() notepad.activateFile(remember_active_file) CATRB__main()