mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-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)
74db34cc91
This commit is contained in:
parent
d25a59f4d0
commit
8771e84db7
@ -1430,6 +1430,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
|||||||
|| VIsual_active
|
|| VIsual_active
|
||||||
) && oap->op_type != OP_NOP) {
|
) && oap->op_type != OP_NOP) {
|
||||||
// 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;
|
||||||
oap->is_VIsual = VIsual_active;
|
oap->is_VIsual = VIsual_active;
|
||||||
if (oap->motion_force == 'V')
|
if (oap->motion_force == 'V')
|
||||||
@ -1598,55 +1601,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
|||||||
virtual_op = virtual_active();
|
virtual_op = virtual_active();
|
||||||
|
|
||||||
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->motion_type = MBLOCK;
|
|
||||||
|
|
||||||
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) {
|
||||||
/*
|
/*
|
||||||
@ -1894,9 +1849,14 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
|||||||
else
|
else
|
||||||
restart_edit_save = 0;
|
restart_edit_save = 0;
|
||||||
restart_edit = 0;
|
restart_edit = 0;
|
||||||
|
|
||||||
// Restore linebreak, so that when the user edits it looks as before.
|
// Restore linebreak, so that when the user edits it looks as before.
|
||||||
curwin->w_p_lbr = lbr_saved;
|
if (curwin->w_p_lbr != lbr_saved) {
|
||||||
/* Reset finish_op now, don't want it set inside edit(). */
|
curwin->w_p_lbr = lbr_saved;
|
||||||
|
get_op_vcol(oap, redo_VIsual_mode, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset finish_op now, don't want it set inside edit().
|
||||||
finish_op = false;
|
finish_op = false;
|
||||||
if (op_change(oap)) /* will call edit() */
|
if (op_change(oap)) /* will call edit() */
|
||||||
cap->retval |= CA_COMMAND_BUSY;
|
cap->retval |= CA_COMMAND_BUSY;
|
||||||
@ -1974,7 +1934,10 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
|||||||
restart_edit = 0;
|
restart_edit = 0;
|
||||||
|
|
||||||
// Restore linebreak, so that when the user edits it looks as before.
|
// Restore linebreak, so that when the user edits it looks as before.
|
||||||
curwin->w_p_lbr = lbr_saved;
|
if (curwin->w_p_lbr != lbr_saved) {
|
||||||
|
curwin->w_p_lbr = lbr_saved;
|
||||||
|
get_op_vcol(oap, redo_VIsual_mode, false);
|
||||||
|
}
|
||||||
|
|
||||||
op_insert(oap, cap->count1);
|
op_insert(oap, cap->count1);
|
||||||
|
|
||||||
@ -1997,7 +1960,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
|||||||
CancelRedo();
|
CancelRedo();
|
||||||
} else {
|
} else {
|
||||||
// Restore linebreak, so that when the user edits it looks as before.
|
// Restore linebreak, so that when the user edits it looks as before.
|
||||||
curwin->w_p_lbr = lbr_saved;
|
if (curwin->w_p_lbr != lbr_saved) {
|
||||||
|
curwin->w_p_lbr = lbr_saved;
|
||||||
|
get_op_vcol(oap, redo_VIsual_mode, false);
|
||||||
|
}
|
||||||
|
|
||||||
op_replace(oap, cap->nchar);
|
op_replace(oap, cap->nchar);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -7698,6 +7665,71 @@ static void nv_open(cmdarg_T *cap)
|
|||||||
n_opencmd(cap);
|
n_opencmd(cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calculate start/end virtual columns for operating in block mode
|
||||||
|
static void get_op_vcol(
|
||||||
|
oparg_T *oap,
|
||||||
|
colnr_T redo_VIsual_vcol,
|
||||||
|
bool initial // when true: adjust position for 'selectmode'
|
||||||
|
)
|
||||||
|
{
|
||||||
|
colnr_T start;
|
||||||
|
colnr_T end;
|
||||||
|
|
||||||
|
if (VIsual_mode != Ctrl_V) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
oap->motion_type = MBLOCK;
|
||||||
|
|
||||||
|
// prevent from moving onto a trail byte
|
||||||
|
if (has_mbyte) {
|
||||||
|
mb_adjustpos(curwin->w_buffer, &oap->end);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle an arbitrary event in normal mode
|
// Handle an arbitrary event in normal mode
|
||||||
static void nv_event(cmdarg_T *cap)
|
static void nv_event(cmdarg_T *cap)
|
||||||
{
|
{
|
||||||
|
@ -60,11 +60,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
|
||||||
|
@ -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
|
||||||
|
@ -371,7 +371,7 @@ static int included_patches[] = {
|
|||||||
// 756 NA
|
// 756 NA
|
||||||
// 755,
|
// 755,
|
||||||
// 754,
|
// 754,
|
||||||
// 753,
|
753,
|
||||||
// 752,
|
// 752,
|
||||||
// 751 NA
|
// 751 NA
|
||||||
// 750 NA
|
// 750 NA
|
||||||
|
@ -99,6 +99,13 @@ describe('linebreak', function()
|
|||||||
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
|
||||||
|
]])
|
||||||
|
feed("Golong line: <Esc>40afoobar <Esc>aTARGETÃ' at end<Esc>")
|
||||||
|
source([[
|
||||||
|
exe "norm! $3B\<C-v>eAx\<Esc>"
|
||||||
]])
|
]])
|
||||||
|
|
||||||
-- Assert buffer contents.
|
-- Assert buffer contents.
|
||||||
@ -148,6 +155,8 @@ describe('linebreak', function()
|
|||||||
Test 6: Screenattributes for comment
|
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]])
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user