mirror of
https://github.com/neovim/neovim.git
synced 2025-12-05 22:22:44 +00: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:
@@ -1430,6 +1430,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
|| VIsual_active
|
||||
) && oap->op_type != OP_NOP) {
|
||||
// Avoid a problem with unwanted linebreaks in block mode
|
||||
if (curwin->w_p_lbr) {
|
||||
curwin->w_valid &= ~VALID_VIRTCOL;
|
||||
}
|
||||
curwin->w_p_lbr = false;
|
||||
oap->is_VIsual = VIsual_active;
|
||||
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();
|
||||
|
||||
if (VIsual_active || redo_VIsual_busy) {
|
||||
if (VIsual_mode == Ctrl_V) { /* block mode */
|
||||
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;
|
||||
}
|
||||
get_op_vcol(oap, redo_VIsual_vcol, true);
|
||||
|
||||
if (!redo_VIsual_busy && !gui_yank) {
|
||||
/*
|
||||
@@ -1894,9 +1849,14 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
else
|
||||
restart_edit_save = 0;
|
||||
restart_edit = 0;
|
||||
|
||||
// Restore linebreak, so that when the user edits it looks as before.
|
||||
curwin->w_p_lbr = lbr_saved;
|
||||
/* Reset finish_op now, don't want it set inside edit(). */
|
||||
if (curwin->w_p_lbr != lbr_saved) {
|
||||
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;
|
||||
if (op_change(oap)) /* will call edit() */
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -1997,7 +1960,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
CancelRedo();
|
||||
} else {
|
||||
// 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);
|
||||
}
|
||||
break;
|
||||
@@ -7698,6 +7665,71 @@ static void nv_open(cmdarg_T *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
|
||||
static void nv_event(cmdarg_T *cap)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user