Re: Insert non-rectangular selection

30 views
Skip to first unread message

Christian Brabandt

unread,
May 27, 2021, 3:59:10 AM5/27/21
to vim...@googlegroups.com, vim-dev Mailingliste

On Di, 25 Mai 2021, Andre Tann wrote:

> Hi all,
>
> I repeatedly have the following situation, and wonder how it can be handled
> better than I do it now. These lines must be merged
>
> /path;text
> /path;text
> /path;text
>
> with these:
>
> /subdir
> /longsubdir
> /longlongsubdir
>
> Result:
>
> /path/subdir;text
> /path/longsubdir;text
> /path/longlongsubdir;text
>
>
> What I do now is to mark and yank the second block, go to the first
> semicolon, and press P. Result is:
>
> /path/subdir ;text
> /path/longsubdir ;text
> /path/longlongsubdir;text
>
> But this is obviously not what I want. How can I avoid the extra blanks?

I have this annoyance a few times as well. I would go with the already
mentioned `:s` approach to remove the whitespace, afterwards. However, I
was wondering, if we not could do any better any perhaps have something
like a `zp` command, that does not add any trailing spaces.

diff --git a/src/normal.c b/src/normal.c
index 92135c18c..25f8233bb 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -2973,6 +2973,10 @@ dozet:
}
break;

+ // "zp", "zP" in block mode put without addind trailing spaces
+ case 'P':
+ case 'p': nv_put(cap);
+ break;
#ifdef FEAT_FOLDING
// "zF": create fold command
// "zf": create fold operator
@@ -7407,11 +7411,13 @@ nv_put_opt(cmdarg_T *cap, int fix_indent)
}
else
dir = (cap->cmdchar == 'P'
- || (cap->cmdchar == 'g' && cap->nchar == 'P'))
- ? BACKWARD : FORWARD;
+ || ((cap->cmdchar == 'g' || cap->cmdchar == 'z')
+ && cap->nchar == 'P')) ? BACKWARD : FORWARD;
prep_redo_cmd(cap);
if (cap->cmdchar == 'g')
flags |= PUT_CURSEND;
+ else if (cap->cmdchar == 'z')
+ flags |= PUT_BLOCK_INNER;

if (VIsual_active)
{
diff --git a/src/register.c b/src/register.c
index 6ba4e896d..afa83cba8 100644
--- a/src/register.c
+++ b/src/register.c
@@ -1497,6 +1497,7 @@ copy_yank_reg(yankreg_T *reg)
* "flags": PUT_FIXINDENT make indent look nice
* PUT_CURSEND leave cursor after end of new text
* PUT_LINE force linewise put (":put")
+ * PUT_BLOCK_INNER in block mode, do not add trailing spaces
*/
void
do_put(
@@ -1845,12 +1846,17 @@ do_put(

yanklen = (int)STRLEN(y_array[i]);

- // calculate number of spaces required to fill right side of block
- spaces = y_width + 1;
- for (j = 0; j < yanklen; j++)
- spaces -= lbr_chartabsize(NULL, &y_array[i][j], 0);
- if (spaces < 0)
+ if (flags & PUT_BLOCK_INNER)
spaces = 0;
+ else
+ {
+ // calculate number of spaces required to fill right side of block
+ spaces = y_width + 1;
+ for (j = 0; j < yanklen; j++)
+ spaces -= lbr_chartabsize(NULL, &y_array[i][j], 0);
+ if (spaces < 0)
+ spaces = 0;
+ }

// insert the new text
totlen = count * (yanklen + spaces) + bd.startspaces + bd.endspaces;
diff --git a/src/vim.h b/src/vim.h
index 368cf3256..ef86312da 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1068,6 +1068,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define PUT_LINE 8 // put register as lines
#define PUT_LINE_SPLIT 16 // split line for linewise register
#define PUT_LINE_FORWARD 32 // put linewise register below Visual sel.
+#define PUT_BLOCK_INNER 64 // in block mode, do not add trailing spaces

// flags for set_indent()
#define SIN_CHANGED 1 // call changed_bytes() when line changed

Mit freundlichen Grüßen
Christian
--
Werfen Sie leere Konservendosen nicht weg! Bewahren Sie sie auf! Nach
einigen Jahren haben Sie dann eine schöne Sammlung alter Konservendosen.

Bram Moolenaar

unread,
May 27, 2021, 7:29:23 AM5/27/21
to vim...@googlegroups.com, Christian Brabandt, vim-dev Mailingliste

Christian wrote:

> On Di, 25 Mai 2021, Andre Tann wrote:
>
> > Hi all,
> >
> > I repeatedly have the following situation, and wonder how it can be handled
> > better than I do it now. These lines must be merged
> >
> > /path/subdir ;text
> > /path/longsubdir ;text
> > /path/longlongsubdir;text
> >
> > with these:
> >
> > /subdir
> > /longsubdir
> > /longlongsubdir
> >
> > Result:
> >
> > /path/subdir;text
> > /path/longsubdir;text
> > /path/longlongsubdir;text
> >
> >
> > What I do now is to mark and yank the second block, go to the first
> > semicolon, and press P. Result is:
> >
> > /path/subdir ;text
> > /path/longsubdir ;text
> > /path/longlongsubdir;text
> >
> > But this is obviously not what I want. How can I avoid the extra blanks?
>
> I have this annoyance a few times as well. I would go with the already
> mentioned `:s` approach to remove the whitespace, afterwards. However, I
> was wondering, if we not could do any better any perhaps have something
> like a `zp` command, that does not add any trailing spaces.

This makes a lot of sense. I don't see a problem using "zp" and "zP"
for this.

Can you turn this into a pull request and add a test?


The example yanks until the end of the line, thus the register does not
contain trailing spaces. I wonder what to do when yanking halfway a
line, e.g. a column in a table:

texttext /subdir columntext
texttext /longsubdir columntext
texttext /longlongsubdir columntext

Here you can only yank a block including the spaces, and they would also
be inserted with "zp". Perhaps we should also have a "zy" command to
exclude the trailing spaces when yanking. I think that's better than
having "zp" drop spaces that were yanked.


--
5 out of 4 people have trouble with fractions.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Maxim Kim

unread,
May 28, 2021, 3:41:06 AM5/28/21
to vim_dev

like a `zp` command, that does not add any trailing spaces.


Btw if you paste at the end of the `;text` no trailing spaces would be added. 

Maxim Kim

unread,
May 28, 2021, 3:42:17 AM5/28/21
to vim_dev

Here you can only yank a block including the spaces, and they would also
be inserted with "zp". Perhaps we should also have a "zy" command to
exclude the trailing spaces when yanking. I think that's better than
having "zp" drop spaces that were yanked.


What about "zd" then? 

Maxim Kim

unread,
May 28, 2021, 3:45:22 AM5/28/21
to vim_dev
пятница, 28 мая 2021 г. в 10:42:17 UTC+3, Maxim Kim:
I mean I know it deletes a fold and it is kind of gets out of the row of "zp", "zy" and "zd" 

Christian Brabandt

unread,
May 30, 2021, 1:42:38 PM5/30/21
to vim...@googlegroups.com, vim-dev Mailingliste
Okay done.

>
>
> The example yanks until the end of the line, thus the register does not
> contain trailing spaces. I wonder what to do when yanking halfway a
> line, e.g. a column in a table:
>
> texttext /subdir columntext
> texttext /longsubdir columntext
> texttext /longlongsubdir columntext
>
> Here you can only yank a block including the spaces, and they would also
> be inserted with "zp". Perhaps we should also have a "zy" command to
> exclude the trailing spaces when yanking. I think that's better than
> having "zp" drop spaces that were yanked.

Okay, I'll have a look at adding a zy command as well (this will be a
separate PR).

Best,
Christian
--
Wer irgendeine Art von Religion zur Stütze seiner Sittlichkeit bedarf,
dessen Moralität ist nicht rein, denn diese muß ihrer Natur nach in
sich selbst bestehen.
-- Karoline von Günderode

Charles Campbell

unread,
May 30, 2021, 3:49:20 PM5/30/21
to vim...@googlegroups.com
Well, that messes with my own zp and zP maps, but no problem. I've also
overridden p and P with them, so I can just eliminate zp and zP.

I've attached a compressed copy in case anyone is interested.

Regards,
Chip Campbell
zmaps.vim.gz

Bram Moolenaar

unread,
May 30, 2021, 4:23:35 PM5/30/21
to vim...@googlegroups.com, Charles Campbell
The mappings would still overrule the new commands. It's only that you
can't use the new commands unless you rename your mappings.

--
If cars evolved at the same rate as computers have, they'd cost five euro,
run for a year on a couple of liters of petrol, and explode once a day.
Reply all
Reply to author
Forward
0 new messages