Patch 8.2.2971
Problem:    Cannot yank a block without trailing spaces.
Solution:   Add the "zy" command. (Christian Brabandt, closes #8292)
Files:      runtime/doc/change.txt, runtime/doc/index.txt, src/normal.c,
            src/ops.c, src/register.c, src/structs.h,
            src/testdir/test_visual.vim


*** ../vim-8.2.2970/runtime/doc/change.txt      2021-05-30 22:17:21.035457554 
+0200
--- runtime/doc/change.txt      2021-06-10 19:37:49.349851290 +0200
***************
*** 1034,1039 ****
--- 1042,1051 ----
                        cursor to the end of line (which is more logical,
                        but not Vi-compatible) use ":map Y y$".
  
+                                                       *zy*
+ ["x]zy{motion}                Yank {motion} text [into register x].  Only 
differs
+                       from `y` when selecting a block of text, see |v_zy|.
+ 
                                                        *v_y*
  {Visual}["x]y         Yank the highlighted text [into register x] (for
                        {Visual} see |Visual-mode|).
***************
*** 1042,1047 ****
--- 1054,1065 ----
  {Visual}["x]Y         Yank the highlighted lines [into register x] (for
                        {Visual} see |Visual-mode|).
  
+                                                       *v_zy*
+ {Visual}["x]zy                Yank the highlighted text [into register x].  
Trailing
+                       whitespace at the end of each line of a selected block
+                       won't be yanked.  Especially useful in combination
+                       with `zp`.  (for {Visual} see |Visual-mode|)
+ 
                                                        *:y* *:yank* *E850*
  :[range]y[ank] [x]    Yank [range] lines [into register x]. Yanking to the
                        "* or "+ registers is possible only when the
***************
*** 1121,1127 ****
  ["x]zp                    or                                  *zp* *zP*
  ["x]zP                        Like "p" and "P", except without adding 
trailing spaces
                        when pasting a block.  Thus the inserted text will not
!                       always be a rectangle.
  
  You can use these commands to copy text from one place to another.  Do this
  by first getting the text into a register with a yank, delete or change
--- 1139,1146 ----
  ["x]zp                    or                                  *zp* *zP*
  ["x]zP                        Like "p" and "P", except without adding 
trailing spaces
                        when pasting a block.  Thus the inserted text will not
!                       always be a rectangle.  Especially useful in
!                       combination with |v_zy|.
  
  You can use these commands to copy text from one place to another.  Do this
  by first getting the text into a register with a yank, delete or change
*** ../vim-8.2.2970/runtime/doc/index.txt       2021-05-30 22:17:21.035457554 
+0200
--- runtime/doc/index.txt       2021-06-10 19:21:37.239742866 +0200
***************
*** 878,883 ****
--- 878,884 ----
  |zv|          zv                 open enough folds to view the cursor line
  |zw|          zw                 permanently mark word as incorrectly spelled
  |zx|          zx                 re-apply 'foldlevel' and do "zv"
+ |zy|          zy                 yank without trailing spaces
  |zz|          zz                 redraw, cursor line at center of window
  |z<Left>|     z<Left>            same as "zh"
  |z<Right>|    z<Right>           same as "zl"
*** ../vim-8.2.2970/src/normal.c        2021-06-04 21:57:53.935646716 +0200
--- src/normal.c        2021-06-10 19:21:37.239742866 +0200
***************
*** 2985,2990 ****
--- 2985,2993 ----
      case 'P':
      case 'p':  nv_put(cap);
               break;
+               // "zy" Yank without trailing spaces
+     case 'y':  nv_operator(cap);
+              break;
  #ifdef FEAT_FOLDING
                // "zF": create fold command
                // "zf": create fold operator
*** ../vim-8.2.2970/src/ops.c   2021-06-02 13:28:11.435120452 +0200
--- src/ops.c   2021-06-10 19:21:37.239742866 +0200
***************
*** 78,83 ****
--- 78,85 ----
        return OP_NR_ADD;
      if (char1 == 'g' && char2 == Ctrl_X)      // subtract
        return OP_NR_SUB;
+     if (char1 == 'z' && char2 == 'y') // OP_YANK
+       return OP_YANK;
      for (i = 0; ; ++i)
      {
        if (opchars[i][0] == char1 && opchars[i][1] == char2)
***************
*** 3894,3899 ****
--- 3896,3902 ----
  #ifdef FEAT_LINEBREAK
                curwin->w_p_lbr = lbr_saved;
  #endif
+               oap->excl_tr_ws = cap->cmdchar == 'z';
                (void)op_yank(oap, FALSE, !gui_yank);
            }
            check_cursor_col();
*** ../vim-8.2.2970/src/register.c      2021-06-04 19:17:03.645562505 +0200
--- src/register.c      2021-06-10 19:31:53.742565522 +0200
***************
*** 32,38 ****
  static void   put_reedit_in_typebuf(int silent);
  static int    put_in_typebuf(char_u *s, int esc, int colon,
                                                                 int silent);
! static int    yank_copy_line(struct block_def *bd, long y_idx);
  #ifdef FEAT_CLIPBOARD
  static void   copy_yank_reg(yankreg_T *reg);
  #endif
--- 32,38 ----
  static void   put_reedit_in_typebuf(int silent);
  static int    put_in_typebuf(char_u *s, int esc, int colon,
                                                                 int silent);
! static int    yank_copy_line(struct block_def *bd, long y_idx, int 
exclude_trailing_space);
  #ifdef FEAT_CLIPBOARD
  static void   copy_yank_reg(yankreg_T *reg);
  #endif
***************
*** 1208,1227 ****
        {
            case MBLOCK:
                block_prep(oap, &bd, lnum, FALSE);
!               if (yank_copy_line(&bd, y_idx) == FAIL)
                    goto fail;
                break;
  
            case MLINE:
                if ((y_current->y_array[y_idx] =
!                           vim_strsave(ml_get(lnum))) == NULL)
                    goto fail;
                break;
  
            case MCHAR:
                {
                    colnr_T startcol = 0, endcol = MAXCOL;
!                   int is_oneChar = FALSE;
                    colnr_T cs, ce;
  
                    p = ml_get(lnum);
--- 1208,1227 ----
        {
            case MBLOCK:
                block_prep(oap, &bd, lnum, FALSE);
!               if (yank_copy_line(&bd, y_idx, oap->excl_tr_ws) == FAIL)
                    goto fail;
                break;
  
            case MLINE:
                if ((y_current->y_array[y_idx] =
!                                           vim_strsave(ml_get(lnum))) == NULL)
                    goto fail;
                break;
  
            case MCHAR:
                {
                    colnr_T startcol = 0, endcol = MAXCOL;
!                   int     is_oneChar = FALSE;
                    colnr_T cs, ce;
  
                    p = ml_get(lnum);
***************
*** 1282,1288 ****
                    else
                        bd.textlen = endcol - startcol + oap->inclusive;
                    bd.textstart = p + startcol;
!                   if (yank_copy_line(&bd, y_idx) == FAIL)
                        goto fail;
                    break;
                }
--- 1282,1288 ----
                    else
                        bd.textlen = endcol - startcol + oap->inclusive;
                    bd.textstart = p + startcol;
!                   if (yank_copy_line(&bd, y_idx, FALSE) == FAIL)
                        goto fail;
                    break;
                }
***************
*** 1443,1450 ****
      return FAIL;
  }
  
      static int
! yank_copy_line(struct block_def *bd, long y_idx)
  {
      char_u    *pnew;
  
--- 1443,1454 ----
      return FAIL;
  }
  
+ /*
+  * Copy a block range into a register.
+  * If "exclude_trailing_space" is set, do not copy trailing whitespaces.
+  */
      static int
! yank_copy_line(struct block_def *bd, long y_idx, int exclude_trailing_space)
  {
      char_u    *pnew;
  
***************
*** 1458,1463 ****
--- 1462,1477 ----
      pnew += bd->textlen;
      vim_memset(pnew, ' ', (size_t)bd->endspaces);
      pnew += bd->endspaces;
+     if (exclude_trailing_space)
+     {
+       int s = bd->textlen + bd->endspaces;
+ 
+       while (VIM_ISWHITE(*(bd->textstart + s - 1)) && s > 0)
+       {
+           s = s - (*mb_head_off)(bd->textstart, bd->textstart + s - 1) - 1;
+           pnew--;
+       }
+     }
      *pnew = NUL;
      return OK;
  }
*** ../vim-8.2.2970/src/structs.h       2021-06-09 19:29:59.884951204 +0200
--- src/structs.h       2021-06-10 19:27:29.907092571 +0200
***************
*** 3772,3778 ****
      int               use_reg_one;    // TRUE if delete uses reg 1 even when 
not
                                // linewise
      int               inclusive;      // TRUE if char motion is inclusive 
(only
!                               // valid when motion_type is MCHAR
      int               end_adjusted;   // backuped b_op_end one char (only 
used by
                                // do_format())
      pos_T     start;          // start of the operator
--- 3772,3778 ----
      int               use_reg_one;    // TRUE if delete uses reg 1 even when 
not
                                // linewise
      int               inclusive;      // TRUE if char motion is inclusive 
(only
!                               // valid when motion_type is MCHAR)
      int               end_adjusted;   // backuped b_op_end one char (only 
used by
                                // do_format())
      pos_T     start;          // start of the operator
***************
*** 3789,3794 ****
--- 3789,3796 ----
      colnr_T   end_vcol;       // end col for block mode operator
      long      prev_opcount;   // ca.opcount saved for K_CURSORHOLD
      long      prev_count0;    // ca.count0 saved for K_CURSORHOLD
+     int               excl_tr_ws;     // exclude trailing whitespace for yank 
of a
+                               // block
  } oparg_T;
  
  /*
*** ../vim-8.2.2970/src/testdir/test_visual.vim 2021-06-05 20:59:18.623771739 
+0200
--- src/testdir/test_visual.vim 2021-06-10 19:33:14.726400475 +0200
***************
*** 1171,1174 ****
--- 1171,1229 ----
    bwipe!
  endfunc
  
+ func Test_visual_put_in_block_using_zy_and_zp()
+   new
+ 
+   " Test 1) Paste using zp - after the cursor without trailing spaces
+   call setline(1, ['/path;text', '/path;text', '/path;text', '', 
+     \ 'texttext  /subdir           columntext',
+               \ 'texttext  /longsubdir       columntext',
+     \ 'texttext  /longlongsubdir   columntext'])
+   exe "normal! 5G0f/\<c-v>2jezy"
+   norm! 1G0f;hzp
+   call assert_equal(['/path/subdir;text', '/path/longsubdir;text', 
'/path/longlongsubdir;text'], getline(1, 3))
+ 
+   " Test 2) Paste using zP - in front of the cursor without trailing spaces
+   %d
+   call setline(1, ['/path;text', '/path;text', '/path;text', '', 
+     \ 'texttext  /subdir           columntext',
+               \ 'texttext  /longsubdir       columntext',
+     \ 'texttext  /longlongsubdir   columntext'])
+   exe "normal! 5G0f/\<c-v>2jezy"
+   norm! 1G0f;zP
+   call assert_equal(['/path/subdir;text', '/path/longsubdir;text', 
'/path/longlongsubdir;text'], getline(1, 3))
+ 
+   " Test 3) Paste using p - with trailing spaces
+   %d
+   call setline(1, ['/path;text', '/path;text', '/path;text', '', 
+     \ 'texttext  /subdir           columntext',
+               \ 'texttext  /longsubdir       columntext',
+     \ 'texttext  /longlongsubdir   columntext'])
+   exe "normal! 5G0f/\<c-v>2jezy"
+   norm! 1G0f;hp
+   call assert_equal(['/path/subdir        ;text', '/path/longsubdir    
;text', '/path/longlongsubdir;text'], getline(1, 3))
+ 
+   " Test 4) Paste using P - with trailing spaces
+   %d
+   call setline(1, ['/path;text', '/path;text', '/path;text', '', 
+     \ 'texttext  /subdir           columntext',
+               \ 'texttext  /longsubdir       columntext',
+     \ 'texttext  /longlongsubdir   columntext'])
+   exe "normal! 5G0f/\<c-v>2jezy"
+   norm! 1G0f;P
+   call assert_equal(['/path/subdir        ;text', '/path/longsubdir    
;text', '/path/longlongsubdir;text'], getline(1, 3))
+ 
+   " Test 5) Yank with spaces inside the block
+   %d
+   call setline(1, ['/path;text', '/path;text', '/path;text', '', 
+     \ 'texttext  /sub    dir/           columntext',
+     \ 'texttext  /lon    gsubdir/       columntext',
+     \ 'texttext  /lon    glongsubdir/   columntext'])
+   exe "normal! 5G0f/\<c-v>2jf/zy"
+   norm! 1G0f;zP
+   call assert_equal(['/path/sub    dir/;text', '/path/lon    gsubdir/;text', 
'/path/lon    glongsubdir/;text'], getline(1, 3))
+   bwipe!
+ endfunc
+ 
+ 
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.2970/src/version.c       2021-06-10 18:50:51.806711124 +0200
--- src/version.c       2021-06-10 19:38:07.057816326 +0200
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2971,
  /**/

-- 
"Lisp has all the visual appeal of oatmeal with nail clippings thrown in."
                                                         -- Larry Wall

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202106101739.15AHdbtW1438479%40masaka.moolenaar.net.

Raspunde prin e-mail lui