Karsten Hopp 61b297
To: vim-dev@vim.org
Karsten Hopp 61b297
Subject: Patch 7.2.137
Karsten Hopp 61b297
Fcc: outbox
Karsten Hopp 61b297
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 61b297
Mime-Version: 1.0
Karsten Hopp 61b297
Content-Type: text/plain; charset=ISO-8859-1
Karsten Hopp 61b297
Content-Transfer-Encoding: 8bit
Karsten Hopp 61b297
------------
Karsten Hopp 61b297
Karsten Hopp 61b297
Note: The special characters in the patch may cause problems.
Karsten Hopp 61b297
Karsten Hopp 61b297
Patch 7.2.137
Karsten Hopp 61b297
Problem:    When 'virtualedit' is set, a left shift of a blockwise selection
Karsten Hopp 61b297
	    that starts and ends inside a tab shifts too much. (Helmut
Karsten Hopp 61b297
	    Stiegler)
Karsten Hopp 61b297
Solution:   Redo the block left shift code. (Lech Lorens)
Karsten Hopp 61b297
Files:	    src/ops.c, src/testdir/Makefile, src/testdir/test66.in,
Karsten Hopp 61b297
	    src/testdir/test66.ok
Karsten Hopp 61b297
Karsten Hopp 61b297
Karsten Hopp 61b297
*** ../vim-7.2.136/src/ops.c	Wed Dec  3 13:38:00 2008
Karsten Hopp 61b297
--- src/ops.c	Thu Mar  5 04:47:09 2009
Karsten Hopp 61b297
***************
Karsten Hopp 61b297
*** 72,82 ****
Karsten Hopp 61b297
   */
Karsten Hopp 61b297
  struct block_def
Karsten Hopp 61b297
  {
Karsten Hopp 61b297
!     int		startspaces;	/* 'extra' cols of first char */
Karsten Hopp 61b297
!     int		endspaces;	/* 'extra' cols of first char */
Karsten Hopp 61b297
      int		textlen;	/* chars in block */
Karsten Hopp 61b297
!     char_u	*textstart;	/* pointer to 1st char in block */
Karsten Hopp 61b297
!     colnr_T	textcol;	/* cols of chars (at least part.) in block */
Karsten Hopp 61b297
      colnr_T	start_vcol;	/* start col of 1st char wholly inside block */
Karsten Hopp 61b297
      colnr_T	end_vcol;	/* start col of 1st char wholly after block */
Karsten Hopp 61b297
  #ifdef FEAT_VISUALEXTRA
Karsten Hopp 61b297
--- 72,82 ----
Karsten Hopp 61b297
   */
Karsten Hopp 61b297
  struct block_def
Karsten Hopp 61b297
  {
Karsten Hopp 61b297
!     int		startspaces;	/* 'extra' cols before first char */
Karsten Hopp 61b297
!     int		endspaces;	/* 'extra' cols after last char */
Karsten Hopp 61b297
      int		textlen;	/* chars in block */
Karsten Hopp 61b297
!     char_u	*textstart;	/* pointer to 1st char (partially) in block */
Karsten Hopp 61b297
!     colnr_T	textcol;	/* index of chars (partially) in block */
Karsten Hopp 61b297
      colnr_T	start_vcol;	/* start col of 1st char wholly inside block */
Karsten Hopp 61b297
      colnr_T	end_vcol;	/* start col of 1st char wholly after block */
Karsten Hopp 61b297
  #ifdef FEAT_VISUALEXTRA
Karsten Hopp 61b297
***************
Karsten Hopp 61b297
*** 382,396 ****
Karsten Hopp 61b297
  {
Karsten Hopp 61b297
      int			left = (oap->op_type == OP_LSHIFT);
Karsten Hopp 61b297
      int			oldstate = State;
Karsten Hopp 61b297
!     int			total, split;
Karsten Hopp 61b297
!     char_u		*newp, *oldp, *midp, *ptr;
Karsten Hopp 61b297
      int			oldcol = curwin->w_cursor.col;
Karsten Hopp 61b297
      int			p_sw = (int)curbuf->b_p_sw;
Karsten Hopp 61b297
      int			p_ts = (int)curbuf->b_p_ts;
Karsten Hopp 61b297
      struct block_def	bd;
Karsten Hopp 61b297
-     int			internal = 0;
Karsten Hopp 61b297
      int			incr;
Karsten Hopp 61b297
!     colnr_T		vcol, col = 0, ws_vcol;
Karsten Hopp 61b297
      int			i = 0, j = 0;
Karsten Hopp 61b297
      int			len;
Karsten Hopp 61b297
  
Karsten Hopp 61b297
--- 382,395 ----
Karsten Hopp 61b297
  {
Karsten Hopp 61b297
      int			left = (oap->op_type == OP_LSHIFT);
Karsten Hopp 61b297
      int			oldstate = State;
Karsten Hopp 61b297
!     int			total;
Karsten Hopp 61b297
!     char_u		*newp, *oldp;
Karsten Hopp 61b297
      int			oldcol = curwin->w_cursor.col;
Karsten Hopp 61b297
      int			p_sw = (int)curbuf->b_p_sw;
Karsten Hopp 61b297
      int			p_ts = (int)curbuf->b_p_ts;
Karsten Hopp 61b297
      struct block_def	bd;
Karsten Hopp 61b297
      int			incr;
Karsten Hopp 61b297
!     colnr_T		ws_vcol;
Karsten Hopp 61b297
      int			i = 0, j = 0;
Karsten Hopp 61b297
      int			len;
Karsten Hopp 61b297
  
Karsten Hopp 61b297
***************
Karsten Hopp 61b297
*** 456,522 ****
Karsten Hopp 61b297
      }
Karsten Hopp 61b297
      else /* left */
Karsten Hopp 61b297
      {
Karsten Hopp 61b297
! 	vcol = oap->start_vcol;
Karsten Hopp 61b297
! 	/* walk vcol past ws to be removed */
Karsten Hopp 61b297
! 	for (midp = oldp + bd.textcol;
Karsten Hopp 61b297
! 	      vcol < (oap->start_vcol + total) && vim_iswhite(*midp); )
Karsten Hopp 61b297
! 	{
Karsten Hopp 61b297
! 	    incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol);
Karsten Hopp 61b297
! 	    vcol += incr;
Karsten Hopp 61b297
! 	}
Karsten Hopp 61b297
! 	/* internal is the block-internal ws replacing a split TAB */
Karsten Hopp 61b297
! 	if (vcol > (oap->start_vcol + total))
Karsten Hopp 61b297
! 	{
Karsten Hopp 61b297
! 	    /* we have to split the TAB *(midp-1) */
Karsten Hopp 61b297
! 	    internal = vcol - (oap->start_vcol + total);
Karsten Hopp 61b297
! 	}
Karsten Hopp 61b297
! 	/* if 'expandtab' is not set, use TABs */
Karsten Hopp 61b297
  
Karsten Hopp 61b297
! 	split = bd.startspaces + internal;
Karsten Hopp 61b297
! 	if (split > 0)
Karsten Hopp 61b297
! 	{
Karsten Hopp 61b297
! 	    if (!curbuf->b_p_et)
Karsten Hopp 61b297
! 	    {
Karsten Hopp 61b297
! 		for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; )
Karsten Hopp 61b297
! 		    col += lbr_chartabsize_adv(&ptr, (colnr_T)col);
Karsten Hopp 61b297
  
Karsten Hopp 61b297
! 		/* col+1 now equals the start col of the first char of the
Karsten Hopp 61b297
! 		 * block (may be < oap.start_vcol if we're splitting a TAB) */
Karsten Hopp 61b297
! 		i = ((col % p_ts) + split) / p_ts; /* number of tabs */
Karsten Hopp 61b297
! 	    }
Karsten Hopp 61b297
! 	    if (i)
Karsten Hopp 61b297
! 		j = ((col % p_ts) + split) % p_ts; /* number of spp */
Karsten Hopp 61b297
! 	    else
Karsten Hopp 61b297
! 		j = split;
Karsten Hopp 61b297
! 	}
Karsten Hopp 61b297
  
Karsten Hopp 61b297
! 	newp = alloc_check(bd.textcol + i + j + (unsigned)STRLEN(midp) + 1);
Karsten Hopp 61b297
! 	if (newp == NULL)
Karsten Hopp 61b297
! 	    return;
Karsten Hopp 61b297
! 	vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + STRLEN(midp) + 1));
Karsten Hopp 61b297
  
Karsten Hopp 61b297
! 	/* copy first part we want to keep */
Karsten Hopp 61b297
! 	mch_memmove(newp, oldp, (size_t)bd.textcol);
Karsten Hopp 61b297
! 	/* Now copy any TABS and spp to ensure correct alignment! */
Karsten Hopp 61b297
! 	while (vim_iswhite(*midp))
Karsten Hopp 61b297
  	{
Karsten Hopp 61b297
! 	    if (*midp == TAB)
Karsten Hopp 61b297
! 		i++;
Karsten Hopp 61b297
! 	    else /*space */
Karsten Hopp 61b297
! 		j++;
Karsten Hopp 61b297
! 	    midp++;
Karsten Hopp 61b297
  	}
Karsten Hopp 61b297
! 	/* We might have an extra TAB worth of spp now! */
Karsten Hopp 61b297
! 	if (j / p_ts && !curbuf->b_p_et)
Karsten Hopp 61b297
  	{
Karsten Hopp 61b297
! 	    i++;
Karsten Hopp 61b297
! 	    j -= p_ts;
Karsten Hopp 61b297
  	}
Karsten Hopp 61b297
- 	copy_chars(newp + bd.textcol, (size_t)i, TAB);
Karsten Hopp 61b297
- 	copy_spaces(newp + bd.textcol + i, (size_t)j);
Karsten Hopp 61b297
  
Karsten Hopp 61b297
! 	/* the end */
Karsten Hopp 61b297
! 	STRMOVE(newp + STRLEN(newp), midp);
Karsten Hopp 61b297
      }
Karsten Hopp 61b297
      /* replace the line */
Karsten Hopp 61b297
      ml_replace(curwin->w_cursor.lnum, newp, FALSE);
Karsten Hopp 61b297
--- 455,543 ----
Karsten Hopp 61b297
      }
Karsten Hopp 61b297
      else /* left */
Karsten Hopp 61b297
      {
Karsten Hopp 61b297
! 	colnr_T	    destination_col;	/* column to which text in block will
Karsten Hopp 61b297
! 					   be shifted */
Karsten Hopp 61b297
! 	char_u	    *verbatim_copy_end;	/* end of the part of the line which is
Karsten Hopp 61b297
! 					   copied verbatim */
Karsten Hopp 61b297
! 	colnr_T	    verbatim_copy_width;/* the (displayed) width of this part
Karsten Hopp 61b297
! 					   of line */
Karsten Hopp 61b297
! 	unsigned    fill;		/* nr of spaces that replace a TAB */
Karsten Hopp 61b297
! 	unsigned    new_line_len;	/* the length of the line after the
Karsten Hopp 61b297
! 					   block shift */
Karsten Hopp 61b297
! 	size_t	    block_space_width;
Karsten Hopp 61b297
! 	size_t	    shift_amount;
Karsten Hopp 61b297
! 	char_u	    *non_white = bd.textstart;
Karsten Hopp 61b297
! 	colnr_T	    non_white_col;
Karsten Hopp 61b297
  
Karsten Hopp 61b297
! 	/*
Karsten Hopp 61b297
! 	 * Firstly, let's find the first non-whitespace character that is
Karsten Hopp 61b297
! 	 * displayed after the block's start column and the character's column
Karsten Hopp 61b297
! 	 * number. Also, let's calculate the width of all the whitespace
Karsten Hopp 61b297
! 	 * characters that are displayed in the block and precede the searched
Karsten Hopp 61b297
! 	 * non-whitespace character.
Karsten Hopp 61b297
! 	 */
Karsten Hopp 61b297
  
Karsten Hopp 61b297
! 	/* If "bd.startspaces" is set, "bd.textstart" points to the character,
Karsten Hopp 61b297
! 	 * the part of which is displayed at the block's beginning. Let's start
Karsten Hopp 61b297
! 	 * searching from the next character. */
Karsten Hopp 61b297
! 	if (bd.startspaces)
Karsten Hopp 61b297
! 	    mb_ptr_adv(non_white);
Karsten Hopp 61b297
  
Karsten Hopp 61b297
! 	/* The character's column is in "bd.start_vcol".  */
Karsten Hopp 61b297
! 	non_white_col = bd.start_vcol;
Karsten Hopp 61b297
  
Karsten Hopp 61b297
! 	while (vim_iswhite(*non_white))
Karsten Hopp 61b297
  	{
Karsten Hopp 61b297
! 	    incr = lbr_chartabsize_adv(&non_white, non_white_col);
Karsten Hopp 61b297
! 	    non_white_col += incr;
Karsten Hopp 61b297
  	}
Karsten Hopp 61b297
! 
Karsten Hopp 61b297
! 	block_space_width = non_white_col - oap->start_vcol;
Karsten Hopp 61b297
! 	/* We will shift by "total" or "block_space_width", whichever is less.
Karsten Hopp 61b297
! 	 */
Karsten Hopp 61b297
! 	shift_amount = (block_space_width < total? block_space_width: total);
Karsten Hopp 61b297
! 
Karsten Hopp 61b297
! 	/* The column to which we will shift the text.  */
Karsten Hopp 61b297
! 	destination_col = non_white_col - shift_amount;
Karsten Hopp 61b297
! 
Karsten Hopp 61b297
! 	/* Now let's find out how much of the beginning of the line we can
Karsten Hopp 61b297
! 	 * reuse without modification.  */
Karsten Hopp 61b297
! 	verbatim_copy_end = bd.textstart;
Karsten Hopp 61b297
! 	verbatim_copy_width = bd.start_vcol;
Karsten Hopp 61b297
! 
Karsten Hopp 61b297
! 	/* If "bd.startspaces" is set, "bd.textstart" points to the character
Karsten Hopp 61b297
! 	 * preceding the block. We have to subtract its width to obtain its
Karsten Hopp 61b297
! 	 * column number.  */
Karsten Hopp 61b297
! 	if (bd.startspaces)
Karsten Hopp 61b297
! 	    verbatim_copy_width -= bd.start_char_vcols;
Karsten Hopp 61b297
! 	while (verbatim_copy_width < destination_col)
Karsten Hopp 61b297
  	{
Karsten Hopp 61b297
! 	    incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width);
Karsten Hopp 61b297
! 	    if (verbatim_copy_width + incr > destination_col)
Karsten Hopp 61b297
! 		break;
Karsten Hopp 61b297
! 	    verbatim_copy_width += incr;
Karsten Hopp 61b297
! 	    mb_ptr_adv(verbatim_copy_end);
Karsten Hopp 61b297
  	}
Karsten Hopp 61b297
  
Karsten Hopp 61b297
! 	/* If "destination_col" is different from the width of the initial
Karsten Hopp 61b297
! 	 * part of the line that will be copied, it means we encountered a tab
Karsten Hopp 61b297
! 	 * character, which we will have to partly replace with spaces.  */
Karsten Hopp 61b297
! 	fill = destination_col - verbatim_copy_width;
Karsten Hopp 61b297
! 
Karsten Hopp 61b297
! 	/* The replacement line will consist of:
Karsten Hopp 61b297
! 	 * - the beginning of the original line up to "verbatim_copy_end",
Karsten Hopp 61b297
! 	 * - "fill" number of spaces,
Karsten Hopp 61b297
! 	 * - the rest of the line, pointed to by non_white.  */
Karsten Hopp 61b297
! 	new_line_len = (unsigned)(verbatim_copy_end - oldp)
Karsten Hopp 61b297
! 		       + fill
Karsten Hopp 61b297
! 		       + (unsigned)STRLEN(non_white) + 1;
Karsten Hopp 61b297
! 
Karsten Hopp 61b297
! 	newp = alloc_check(new_line_len);
Karsten Hopp 61b297
! 	if (newp == NULL)
Karsten Hopp 61b297
! 	    return;
Karsten Hopp 61b297
! 	mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
Karsten Hopp 61b297
! 	copy_spaces(newp + (verbatim_copy_end - oldp), (size_t)fill);
Karsten Hopp 61b297
! 	STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
Karsten Hopp 61b297
      }
Karsten Hopp 61b297
      /* replace the line */
Karsten Hopp 61b297
      ml_replace(curwin->w_cursor.lnum, newp, FALSE);
Karsten Hopp 61b297
***************
Karsten Hopp 61b297
*** 4851,4857 ****
Karsten Hopp 61b297
   * - textlen includes the first/last char to be (partly) deleted
Karsten Hopp 61b297
   * - start/endspaces is the number of columns that are taken by the
Karsten Hopp 61b297
   *   first/last deleted char minus the number of columns that have to be
Karsten Hopp 61b297
!  *   deleted.  for yank and tilde:
Karsten Hopp 61b297
   * - textlen includes the first/last char to be wholly yanked
Karsten Hopp 61b297
   * - start/endspaces is the number of columns of the first/last yanked char
Karsten Hopp 61b297
   *   that are to be yanked.
Karsten Hopp 61b297
--- 4872,4879 ----
Karsten Hopp 61b297
   * - textlen includes the first/last char to be (partly) deleted
Karsten Hopp 61b297
   * - start/endspaces is the number of columns that are taken by the
Karsten Hopp 61b297
   *   first/last deleted char minus the number of columns that have to be
Karsten Hopp 61b297
!  *   deleted.
Karsten Hopp 61b297
!  * for yank and tilde:
Karsten Hopp 61b297
   * - textlen includes the first/last char to be wholly yanked
Karsten Hopp 61b297
   * - start/endspaces is the number of columns of the first/last yanked char
Karsten Hopp 61b297
   *   that are to be yanked.
Karsten Hopp 61b297
*** ../vim-7.2.136/src/testdir/Makefile	Wed Sep 10 18:25:18 2008
Karsten Hopp 61b297
--- src/testdir/Makefile	Thu Mar  5 04:53:58 2009
Karsten Hopp 61b297
***************
Karsten Hopp 61b297
*** 20,26 ****
Karsten Hopp 61b297
  		test48.out test49.out test51.out test52.out test53.out \
Karsten Hopp 61b297
  		test54.out test55.out test56.out test57.out test58.out \
Karsten Hopp 61b297
  		test59.out test60.out test61.out test62.out test63.out \
Karsten Hopp 61b297
! 		test64.out test65.out
Karsten Hopp 61b297
  
Karsten Hopp 61b297
  SCRIPTS_GUI = test16.out
Karsten Hopp 61b297
  
Karsten Hopp 61b297
--- 20,26 ----
Karsten Hopp 61b297
  		test48.out test49.out test51.out test52.out test53.out \
Karsten Hopp 61b297
  		test54.out test55.out test56.out test57.out test58.out \
Karsten Hopp 61b297
  		test59.out test60.out test61.out test62.out test63.out \
Karsten Hopp 61b297
! 		test64.out test65.out test66.out
Karsten Hopp 61b297
  
Karsten Hopp 61b297
  SCRIPTS_GUI = test16.out
Karsten Hopp 61b297
  
Karsten Hopp 61b297
*** ../vim-7.2.136/src/testdir/test66.in	Wed Mar 11 16:24:44 2009
Karsten Hopp 61b297
--- src/testdir/test66.in	Wed Mar 11 11:52:57 2009
Karsten Hopp 61b297
***************
Karsten Hopp 61b297
*** 0 ****
Karsten Hopp 61b297
--- 1,25 ----
Karsten Hopp 61b297
+ 
Karsten Hopp 61b297
+ Test for visual block shift and tab characters.
Karsten Hopp 61b297
+ 
Karsten Hopp 61b297
+ STARTTEST
Karsten Hopp 61b297
+ :so small.vim
Karsten Hopp 61b297
+ /^abcdefgh
Karsten Hopp 61b297
+ ?4jI    ?j<<11|D
Karsten Hopp 61b297
+ 7|a		?
Karsten Hopp 61b297
+ 7|a		   ?
Karsten Hopp 61b297
+ 7|a	       	?4k13|?4j<
Karsten Hopp 61b297
+ :$-4,$w! test.out
Karsten Hopp 61b297
+ :$-4,$s/\s\+//g
Karsten Hopp 61b297
+ ?4kI    ?j<<
Karsten Hopp 61b297
+ 7|a		?
Karsten Hopp 61b297
+ 7|a					?
Karsten Hopp 61b297
+ 7|a	       		?4k13|?4j3<
Karsten Hopp 61b297
+ :$-4,$w >> test.out
Karsten Hopp 61b297
+ :qa!
Karsten Hopp 61b297
+ ENDTEST
Karsten Hopp 61b297
+ 
Karsten Hopp 61b297
+ abcdefghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+ abcdefghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+ abcdefghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+ abcdefghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+ abcdefghijklmnopqrstuvwxyz
Karsten Hopp 61b297
*** ../vim-7.2.136/src/testdir/test66.ok	Wed Mar 11 16:24:44 2009
Karsten Hopp 61b297
--- src/testdir/test66.ok	Thu Mar  5 04:39:36 2009
Karsten Hopp 61b297
***************
Karsten Hopp 61b297
*** 0 ****
Karsten Hopp 61b297
--- 1,10 ----
Karsten Hopp 61b297
+     abcdefghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+ abcdefghij
Karsten Hopp 61b297
+     abc	    defghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+     abc	    defghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+     abc	    defghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+     abcdefghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+ abcdefghij
Karsten Hopp 61b297
+     abc	    defghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+     abc		defghijklmnopqrstuvwxyz
Karsten Hopp 61b297
+     abc	    defghijklmnopqrstuvwxyz
Karsten Hopp 61b297
*** ../vim-7.2.136/src/version.c	Wed Mar 11 15:36:01 2009
Karsten Hopp 61b297
--- src/version.c	Wed Mar 11 16:23:07 2009
Karsten Hopp 61b297
***************
Karsten Hopp 61b297
*** 678,679 ****
Karsten Hopp 61b297
--- 678,681 ----
Karsten Hopp 61b297
  {   /* Add new patch number below this line */
Karsten Hopp 61b297
+ /**/
Karsten Hopp 61b297
+     137,
Karsten Hopp 61b297
  /**/
Karsten Hopp 61b297
Karsten Hopp 61b297
-- 
Karsten Hopp 61b297
% cat /usr/include/sys/errno.h
Karsten Hopp 61b297
#define	EPERM		1		/* Operation not permitted */
Karsten Hopp 61b297
#define	ENOENT		2		/* No such file or directory */
Karsten Hopp 61b297
#define	ESRCH		3		/* No such process */
Karsten Hopp 61b297
[...]
Karsten Hopp 61b297
#define EMACS		666		/* Too many macros */
Karsten Hopp 61b297
%
Karsten Hopp 61b297
Karsten Hopp 61b297
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 61b297
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 61b297
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp 61b297
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///