0
0
mirror of https://github.com/vim/vim.git synced 2025-09-26 04:04:07 -04:00

patch 7.4.753

Problem:    Appending in Visual mode with 'linebreak' set does not work
            properly.  Also when 'selection' is "exclusive". (Ingo Karkat)
Solution:   Recalculate virtual columns. (Christian Brabandt)
This commit is contained in:
Bram Moolenaar
2015-06-25 13:30:46 +02:00
parent 66312acf14
commit 74db34cc91
6 changed files with 112 additions and 60 deletions

View File

@@ -174,6 +174,7 @@ static void nv_drop __ARGS((cmdarg_T *cap));
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
static void nv_cursorhold __ARGS((cmdarg_T *cap)); static void nv_cursorhold __ARGS((cmdarg_T *cap));
#endif #endif
static void get_op_vcol __ARGS((oparg_T *oap, colnr_T col, int initial));
static char *e_noident = N_("E349: No identifier under cursor"); static char *e_noident = N_("E349: No identifier under cursor");
@@ -1418,6 +1419,8 @@ do_pending_operator(cap, old_col, gui_yank)
{ {
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
/* Avoid a problem with unwanted linebreaks in block mode. */ /* Avoid a problem with unwanted linebreaks in block mode. */
if (curwin->w_p_lbr)
curwin->w_valid &= ~VALID_VIRTCOL;
curwin->w_p_lbr = FALSE; curwin->w_p_lbr = FALSE;
#endif #endif
oap->is_VIsual = VIsual_active; oap->is_VIsual = VIsual_active;
@@ -1631,61 +1634,7 @@ do_pending_operator(cap, old_col, gui_yank)
if (VIsual_active || redo_VIsual_busy) if (VIsual_active || redo_VIsual_busy)
{ {
if (VIsual_mode == Ctrl_V) /* block mode */ get_op_vcol(oap, redo_VIsual_vcol, TRUE);
{
colnr_T start, end;
oap->block_mode = TRUE;
getvvcol(curwin, &(oap->start),
&oap->start_vcol, NULL, &oap->end_vcol);
if (!redo_VIsual_busy)
{
getvvcol(curwin, &(oap->end), &start, NULL, &end);
if (start < oap->start_vcol)
oap->start_vcol = start;
if (end > oap->end_vcol)
{
if (*p_sel == 'e' && start >= 1
&& start - 1 >= oap->end_vcol)
oap->end_vcol = start - 1;
else
oap->end_vcol = end;
}
}
/* if '$' was used, get oap->end_vcol from longest line */
if (curwin->w_curswant == MAXCOL)
{
curwin->w_cursor.col = MAXCOL;
oap->end_vcol = 0;
for (curwin->w_cursor.lnum = oap->start.lnum;
curwin->w_cursor.lnum <= oap->end.lnum;
++curwin->w_cursor.lnum)
{
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end);
if (end > oap->end_vcol)
oap->end_vcol = end;
}
}
else if (redo_VIsual_busy)
oap->end_vcol = oap->start_vcol + redo_VIsual_vcol - 1;
/*
* Correct oap->end.col and oap->start.col to be the
* upper-left and lower-right corner of the block area.
*
* (Actually, this does convert column positions into character
* positions)
*/
curwin->w_cursor.lnum = oap->end.lnum;
coladvance(oap->end_vcol);
oap->end = curwin->w_cursor;
curwin->w_cursor = oap->start;
coladvance(oap->start_vcol);
oap->start = curwin->w_cursor;
}
if (!redo_VIsual_busy && !gui_yank) if (!redo_VIsual_busy && !gui_yank)
{ {
@@ -1982,7 +1931,11 @@ do_pending_operator(cap, old_col, gui_yank)
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
/* Restore linebreak, so that when the user edits it looks as /* Restore linebreak, so that when the user edits it looks as
* before. */ * before. */
if (curwin->w_p_lbr != lbr_saved)
{
curwin->w_p_lbr = lbr_saved; curwin->w_p_lbr = lbr_saved;
get_op_vcol(oap, redo_VIsual_mode, FALSE);
}
#endif #endif
/* Reset finish_op now, don't want it set inside edit(). */ /* Reset finish_op now, don't want it set inside edit(). */
finish_op = FALSE; finish_op = FALSE;
@@ -2082,7 +2035,11 @@ do_pending_operator(cap, old_col, gui_yank)
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
/* Restore linebreak, so that when the user edits it looks as /* Restore linebreak, so that when the user edits it looks as
* before. */ * before. */
if (curwin->w_p_lbr != lbr_saved)
{
curwin->w_p_lbr = lbr_saved; curwin->w_p_lbr = lbr_saved;
get_op_vcol(oap, redo_VIsual_mode, FALSE);
}
#endif #endif
op_insert(oap, cap->count1); op_insert(oap, cap->count1);
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
@@ -2114,11 +2071,15 @@ do_pending_operator(cap, old_col, gui_yank)
#ifdef FEAT_VISUALEXTRA #ifdef FEAT_VISUALEXTRA
else else
{ {
#ifdef FEAT_LINEBREAK # ifdef FEAT_LINEBREAK
/* Restore linebreak, so that when the user edits it looks as /* Restore linebreak, so that when the user edits it looks as
* before. */ * before. */
if (curwin->w_p_lbr != lbr_saved)
{
curwin->w_p_lbr = lbr_saved; curwin->w_p_lbr = lbr_saved;
#endif get_op_vcol(oap, redo_VIsual_mode, FALSE);
}
# endif
op_replace(oap, cap->nchar); op_replace(oap, cap->nchar);
} }
#endif #endif
@@ -9542,3 +9503,70 @@ nv_cursorhold(cap)
cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */ cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */
} }
#endif #endif
/*
* calculate start/end virtual columns for operating in block mode
*/
static void
get_op_vcol(oap, redo_VIsual_vcol, initial)
oparg_T *oap;
colnr_T redo_VIsual_vcol;
int initial; /* when true: adjust position for 'selectmode' */
{
colnr_T start, end;
if (VIsual_mode != Ctrl_V)
return;
oap->block_mode = TRUE;
#ifdef FEAT_MBYTE
/* prevent from moving onto a trail byte */
if (has_mbyte)
mb_adjustpos(curwin->w_buffer, &oap->end);
#endif
getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol);
getvvcol(curwin, &(oap->end), &start, NULL, &end);
if (start < oap->start_vcol)
oap->start_vcol = start;
if (end > oap->end_vcol)
{
if (initial && *p_sel == 'e' && start >= 1
&& start - 1 >= oap->end_vcol)
oap->end_vcol = start - 1;
else
oap->end_vcol = end;
}
/* if '$' was used, get oap->end_vcol from longest line */
if (curwin->w_curswant == MAXCOL)
{
curwin->w_cursor.col = MAXCOL;
oap->end_vcol = 0;
for (curwin->w_cursor.lnum = oap->start.lnum;
curwin->w_cursor.lnum <= oap->end.lnum;
++curwin->w_cursor.lnum)
{
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end);
if (end > oap->end_vcol)
oap->end_vcol = end;
}
}
else if (redo_VIsual_busy)
oap->end_vcol = oap->start_vcol + redo_VIsual_vcol - 1;
/*
* Correct oap->end.col and oap->start.col to be the
* upper-left and lower-right corner of the block area.
*
* (Actually, this does convert column positions into character
* positions)
*/
curwin->w_cursor.lnum = oap->end.lnum;
coladvance(oap->end_vcol);
oap->end = curwin->w_cursor;
curwin->w_cursor = oap->start;
coladvance(oap->start_vcol);
oap->start = curwin->w_cursor;
}

View File

@@ -59,11 +59,21 @@ STARTTEST
:set cpo&vim linebreak :set cpo&vim linebreak
:let g:test ="Test 6: set linebreak with visual block mode" :let g:test ="Test 6: set linebreak with visual block mode"
:let line="REMOVE: this not" :let line="REMOVE: this not"
:$put =g:test
:$put =line :$put =line
:let line="REMOVE: aaaaaaaaaaaaa" :let line="REMOVE: aaaaaaaaaaaaa"
:$put =line :$put =line
:1/^REMOVE: :1/^REMOVE:
0jf x:$put 0jf x:$put
:set cpo&vim linebreak
:let g:test ="Test 7: set linebreak with visual block mode and v_b_A"
:$put =g:test
Golong line: 40afoobar aTARGET at end
:exe "norm! $3B\<C-v>eAx\<Esc>"
:set cpo&vim linebreak sbr=
:let g:test ="Test 8: set linebreak with visual char mode and changing block"
:$put =g:test
Go1111-1111-1111-11-1111-1111-11110f-lv3lc2222bgj.
:%w! test.out :%w! test.out
:qa! :qa!
ENDTEST ENDTEST

View File

@@ -32,7 +32,12 @@ Sabbbbbb bla
~ ~
~ ~
~ ~
Test 6: set linebreak with visual block mode
this not this not
aaaaaaaaaaaaa aaaaaaaaaaaaa
REMOVE: REMOVE:
REMOVE: REMOVE:
Test 7: set linebreak with visual block mode and v_b_A
long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETx at end
Test 8: set linebreak with visual char mode and changing block
1111-2222-1111-11-1111-2222-1111

View File

@@ -91,6 +91,11 @@ GGlGGlGGlGGlGGlGGlGGlGGlGGlGGl
:else :else
: call append('$', "Not all attributes are different") : call append('$', "Not all attributes are different")
:endif :endif
:set cpo&vim linebreak selection=exclusive
:let g:test ="Test 8: set linebreak with visual block mode and v_b_A and selection=exclusive and multibyte char"
:$put =g:test
Golong line: 40afoobar aTARGETÃ' at end
:exe "norm! $3B\<C-v>eAx\<Esc>"
:%w! test.out :%w! test.out
:qa! :qa!
ENDTEST ENDTEST

View File

@@ -44,3 +44,5 @@ Test 6: Screenattributes for comment
/* and some more */ /* and some more */
ScreenAttributes for test6: ScreenAttributes for test6:
Attribut 0 and 1 and 3 and 5 are different! Attribut 0 and 1 and 3 and 5 are different!
Test 8: set linebreak with visual block mode and v_b_A and selection=exclusive and multibyte char
long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETÃx' at end

View File

@@ -741,6 +741,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 */
/**/
753,
/**/ /**/
752, 752,
/**/ /**/