updated for version 7.2-137
This commit is contained in:
		
							
								
								
									
										150
									
								
								src/ops.c
									
									
									
									
									
								
							
							
						
						
									
										150
									
								
								src/ops.c
									
									
									
									
									
								
							| @ -72,11 +72,11 @@ static struct yankreg	*y_previous = NULL; /* ptr to last written yankreg */ | |||||||
|  */ |  */ | ||||||
| struct block_def | struct block_def | ||||||
| { | { | ||||||
|     int		startspaces;	/* 'extra' cols of first char */ |     int		startspaces;	/* 'extra' cols before first char */ | ||||||
|     int		endspaces;	/* 'extra' cols of first char */ |     int		endspaces;	/* 'extra' cols after last char */ | ||||||
|     int		textlen;	/* chars in block */ |     int		textlen;	/* chars in block */ | ||||||
|     char_u	*textstart;	/* pointer to 1st char in block */ |     char_u	*textstart;	/* pointer to 1st char (partially) in block */ | ||||||
|     colnr_T	textcol;	/* cols of chars (at least part.) in block */ |     colnr_T	textcol;	/* index of chars (partially) in block */ | ||||||
|     colnr_T	start_vcol;	/* start col of 1st char wholly inside block */ |     colnr_T	start_vcol;	/* start col of 1st char wholly inside block */ | ||||||
|     colnr_T	end_vcol;	/* start col of 1st char wholly after block */ |     colnr_T	end_vcol;	/* start col of 1st char wholly after block */ | ||||||
| #ifdef FEAT_VISUALEXTRA | #ifdef FEAT_VISUALEXTRA | ||||||
| @ -382,15 +382,14 @@ shift_block(oap, amount) | |||||||
| { | { | ||||||
|     int			left = (oap->op_type == OP_LSHIFT); |     int			left = (oap->op_type == OP_LSHIFT); | ||||||
|     int			oldstate = State; |     int			oldstate = State; | ||||||
|     int			total, split; |     int			total; | ||||||
|     char_u		*newp, *oldp, *midp, *ptr; |     char_u		*newp, *oldp; | ||||||
|     int			oldcol = curwin->w_cursor.col; |     int			oldcol = curwin->w_cursor.col; | ||||||
|     int			p_sw = (int)curbuf->b_p_sw; |     int			p_sw = (int)curbuf->b_p_sw; | ||||||
|     int			p_ts = (int)curbuf->b_p_ts; |     int			p_ts = (int)curbuf->b_p_ts; | ||||||
|     struct block_def	bd; |     struct block_def	bd; | ||||||
|     int			internal = 0; |  | ||||||
|     int			incr; |     int			incr; | ||||||
|     colnr_T		vcol, col = 0, ws_vcol; |     colnr_T		ws_vcol; | ||||||
|     int			i = 0, j = 0; |     int			i = 0, j = 0; | ||||||
|     int			len; |     int			len; | ||||||
|  |  | ||||||
| @ -456,67 +455,89 @@ shift_block(oap, amount) | |||||||
|     } |     } | ||||||
|     else /* left */ |     else /* left */ | ||||||
|     { |     { | ||||||
| 	vcol = oap->start_vcol; | 	colnr_T	    destination_col;	/* column to which text in block will | ||||||
| 	/* walk vcol past ws to be removed */ | 					   be shifted */ | ||||||
| 	for (midp = oldp + bd.textcol; | 	char_u	    *verbatim_copy_end;	/* end of the part of the line which is | ||||||
| 	      vcol < (oap->start_vcol + total) && vim_iswhite(*midp); ) | 					   copied verbatim */ | ||||||
| 	{ | 	colnr_T	    verbatim_copy_width;/* the (displayed) width of this part | ||||||
| 	    incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol); | 					   of line */ | ||||||
| 	    vcol += incr; | 	unsigned    fill;		/* nr of spaces that replace a TAB */ | ||||||
| 	} | 	unsigned    new_line_len;	/* the length of the line after the | ||||||
| 	/* internal is the block-internal ws replacing a split TAB */ | 					   block shift */ | ||||||
| 	if (vcol > (oap->start_vcol + total)) | 	size_t	    block_space_width; | ||||||
| 	{ | 	size_t	    shift_amount; | ||||||
| 	    /* we have to split the TAB *(midp-1) */ | 	char_u	    *non_white = bd.textstart; | ||||||
| 	    internal = vcol - (oap->start_vcol + total); | 	colnr_T	    non_white_col; | ||||||
| 	} |  | ||||||
| 	/* if 'expandtab' is not set, use TABs */ |  | ||||||
|  |  | ||||||
| 	split = bd.startspaces + internal; | 	/* | ||||||
| 	if (split > 0) | 	 * Firstly, let's find the first non-whitespace character that is | ||||||
| 	{ | 	 * displayed after the block's start column and the character's column | ||||||
| 	    if (!curbuf->b_p_et) | 	 * number. Also, let's calculate the width of all the whitespace | ||||||
| 	    { | 	 * characters that are displayed in the block and precede the searched | ||||||
| 		for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; ) | 	 * non-whitespace character. | ||||||
| 		    col += lbr_chartabsize_adv(&ptr, (colnr_T)col); | 	 */ | ||||||
|  |  | ||||||
| 		/* col+1 now equals the start col of the first char of the | 	/* If "bd.startspaces" is set, "bd.textstart" points to the character, | ||||||
| 		 * block (may be < oap.start_vcol if we're splitting a TAB) */ | 	 * the part of which is displayed at the block's beginning. Let's start | ||||||
| 		i = ((col % p_ts) + split) / p_ts; /* number of tabs */ | 	 * searching from the next character. */ | ||||||
| 	    } | 	if (bd.startspaces) | ||||||
| 	    if (i) | 	    mb_ptr_adv(non_white); | ||||||
| 		j = ((col % p_ts) + split) % p_ts; /* number of spp */ |  | ||||||
| 	    else | 	/* The character's column is in "bd.start_vcol".  */ | ||||||
| 		j = split; | 	non_white_col = bd.start_vcol; | ||||||
|  |  | ||||||
|  | 	while (vim_iswhite(*non_white)) | ||||||
|  | 	{ | ||||||
|  | 	    incr = lbr_chartabsize_adv(&non_white, non_white_col); | ||||||
|  | 	    non_white_col += incr; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newp = alloc_check(bd.textcol + i + j + (unsigned)STRLEN(midp) + 1); | 	block_space_width = non_white_col - oap->start_vcol; | ||||||
|  | 	/* We will shift by "total" or "block_space_width", whichever is less. | ||||||
|  | 	 */ | ||||||
|  | 	shift_amount = (block_space_width < total? block_space_width: total); | ||||||
|  |  | ||||||
|  | 	/* The column to which we will shift the text.  */ | ||||||
|  | 	destination_col = non_white_col - shift_amount; | ||||||
|  |  | ||||||
|  | 	/* Now let's find out how much of the beginning of the line we can | ||||||
|  | 	 * reuse without modification.  */ | ||||||
|  | 	verbatim_copy_end = bd.textstart; | ||||||
|  | 	verbatim_copy_width = bd.start_vcol; | ||||||
|  |  | ||||||
|  | 	/* If "bd.startspaces" is set, "bd.textstart" points to the character | ||||||
|  | 	 * preceding the block. We have to subtract its width to obtain its | ||||||
|  | 	 * column number.  */ | ||||||
|  | 	if (bd.startspaces) | ||||||
|  | 	    verbatim_copy_width -= bd.start_char_vcols; | ||||||
|  | 	while (verbatim_copy_width < destination_col) | ||||||
|  | 	{ | ||||||
|  | 	    incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width); | ||||||
|  | 	    if (verbatim_copy_width + incr > destination_col) | ||||||
|  | 		break; | ||||||
|  | 	    verbatim_copy_width += incr; | ||||||
|  | 	    mb_ptr_adv(verbatim_copy_end); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* If "destination_col" is different from the width of the initial | ||||||
|  | 	 * part of the line that will be copied, it means we encountered a tab | ||||||
|  | 	 * character, which we will have to partly replace with spaces.  */ | ||||||
|  | 	fill = destination_col - verbatim_copy_width; | ||||||
|  |  | ||||||
|  | 	/* The replacement line will consist of: | ||||||
|  | 	 * - the beginning of the original line up to "verbatim_copy_end", | ||||||
|  | 	 * - "fill" number of spaces, | ||||||
|  | 	 * - the rest of the line, pointed to by non_white.  */ | ||||||
|  | 	new_line_len = (unsigned)(verbatim_copy_end - oldp) | ||||||
|  | 		       + fill | ||||||
|  | 		       + (unsigned)STRLEN(non_white) + 1; | ||||||
|  |  | ||||||
|  | 	newp = alloc_check(new_line_len); | ||||||
| 	if (newp == NULL) | 	if (newp == NULL) | ||||||
| 	    return; | 	    return; | ||||||
| 	vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + STRLEN(midp) + 1)); | 	mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp)); | ||||||
|  | 	copy_spaces(newp + (verbatim_copy_end - oldp), (size_t)fill); | ||||||
| 	/* copy first part we want to keep */ | 	STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white); | ||||||
| 	mch_memmove(newp, oldp, (size_t)bd.textcol); |  | ||||||
| 	/* Now copy any TABS and spp to ensure correct alignment! */ |  | ||||||
| 	while (vim_iswhite(*midp)) |  | ||||||
| 	{ |  | ||||||
| 	    if (*midp == TAB) |  | ||||||
| 		i++; |  | ||||||
| 	    else /*space */ |  | ||||||
| 		j++; |  | ||||||
| 	    midp++; |  | ||||||
| 	} |  | ||||||
| 	/* We might have an extra TAB worth of spp now! */ |  | ||||||
| 	if (j / p_ts && !curbuf->b_p_et) |  | ||||||
| 	{ |  | ||||||
| 	    i++; |  | ||||||
| 	    j -= p_ts; |  | ||||||
| 	} |  | ||||||
| 	copy_chars(newp + bd.textcol, (size_t)i, TAB); |  | ||||||
| 	copy_spaces(newp + bd.textcol + i, (size_t)j); |  | ||||||
|  |  | ||||||
| 	/* the end */ |  | ||||||
| 	STRMOVE(newp + STRLEN(newp), midp); |  | ||||||
|     } |     } | ||||||
|     /* replace the line */ |     /* replace the line */ | ||||||
|     ml_replace(curwin->w_cursor.lnum, newp, FALSE); |     ml_replace(curwin->w_cursor.lnum, newp, FALSE); | ||||||
| @ -4851,7 +4872,8 @@ paragraph_start(lnum) | |||||||
|  * - textlen includes the first/last char to be (partly) deleted |  * - textlen includes the first/last char to be (partly) deleted | ||||||
|  * - start/endspaces is the number of columns that are taken by the |  * - start/endspaces is the number of columns that are taken by the | ||||||
|  *   first/last deleted char minus the number of columns that have to be |  *   first/last deleted char minus the number of columns that have to be | ||||||
|  *   deleted.  for yank and tilde: |  *   deleted. | ||||||
|  |  * for yank and tilde: | ||||||
|  * - textlen includes the first/last char to be wholly yanked |  * - textlen includes the first/last char to be wholly yanked | ||||||
|  * - start/endspaces is the number of columns of the first/last yanked char |  * - start/endspaces is the number of columns of the first/last yanked char | ||||||
|  *   that are to be yanked. |  *   that are to be yanked. | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \ | |||||||
| 		test48.out test49.out test51.out test52.out test53.out \ | 		test48.out test49.out test51.out test52.out test53.out \ | ||||||
| 		test54.out test55.out test56.out test57.out test58.out \ | 		test54.out test55.out test56.out test57.out test58.out \ | ||||||
| 		test59.out test60.out test61.out test62.out test63.out \ | 		test59.out test60.out test61.out test62.out test63.out \ | ||||||
| 		test64.out test65.out | 		test64.out test65.out test66.out | ||||||
|  |  | ||||||
| SCRIPTS_GUI = test16.out | SCRIPTS_GUI = test16.out | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										25
									
								
								src/testdir/test66.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/testdir/test66.in
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  |  | ||||||
|  | Test for visual block shift and tab characters. | ||||||
|  |  | ||||||
|  | STARTTEST | ||||||
|  | :so small.vim | ||||||
|  | /^abcdefgh | ||||||
|  | 4jI    j<<11|D | ||||||
|  | 7|a		 | ||||||
|  | 7|a		    | ||||||
|  | 7|a	       	4k13|4j< | ||||||
|  | :$-4,$w! test.out | ||||||
|  | :$-4,$s/\s\+//g | ||||||
|  | 4kI    j<< | ||||||
|  | 7|a		 | ||||||
|  | 7|a					 | ||||||
|  | 7|a	       		4k13|4j3< | ||||||
|  | :$-4,$w >> test.out | ||||||
|  | :qa! | ||||||
|  | ENDTEST | ||||||
|  |  | ||||||
|  | abcdefghijklmnopqrstuvwxyz | ||||||
|  | abcdefghijklmnopqrstuvwxyz | ||||||
|  | abcdefghijklmnopqrstuvwxyz | ||||||
|  | abcdefghijklmnopqrstuvwxyz | ||||||
|  | abcdefghijklmnopqrstuvwxyz | ||||||
							
								
								
									
										10
									
								
								src/testdir/test66.ok
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/testdir/test66.ok
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  |     abcdefghijklmnopqrstuvwxyz | ||||||
|  | abcdefghij | ||||||
|  |     abc	    defghijklmnopqrstuvwxyz | ||||||
|  |     abc	    defghijklmnopqrstuvwxyz | ||||||
|  |     abc	    defghijklmnopqrstuvwxyz | ||||||
|  |     abcdefghijklmnopqrstuvwxyz | ||||||
|  | abcdefghij | ||||||
|  |     abc	    defghijklmnopqrstuvwxyz | ||||||
|  |     abc		defghijklmnopqrstuvwxyz | ||||||
|  |     abc	    defghijklmnopqrstuvwxyz | ||||||
| @ -676,6 +676,8 @@ static char *(features[]) = | |||||||
|  |  | ||||||
| static int included_patches[] = | static int included_patches[] = | ||||||
| {   /* Add new patch number below this line */ | {   /* Add new patch number below this line */ | ||||||
|  | /**/ | ||||||
|  |     137, | ||||||
| /**/ | /**/ | ||||||
|     136, |     136, | ||||||
| /**/ | /**/ | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user