mirror of
https://github.com/neovim/neovim.git
synced 2025-10-02 07:58:35 +00:00
vim-patch:7.4.734
Problem: ml_get error when using "p" in a Visual selection in the last
line.
Solution: Change the behavior at the last line. (Yukihiro Nakadaira)
d009e86826
This commit is contained in:
@@ -1538,9 +1538,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
curbuf->b_visual_mode_eval = VIsual_mode;
|
||||
}
|
||||
|
||||
/* In Select mode, a linewise selection is operated upon like a
|
||||
* characterwise selection. */
|
||||
if (VIsual_select && VIsual_mode == 'V') {
|
||||
// In Select mode, a linewise selection is operated upon like a
|
||||
// characterwise selection.
|
||||
// Special case: gH<Del> deletes the last line.
|
||||
if (VIsual_select && VIsual_mode == 'V'
|
||||
&& cap->oap->op_type != OP_DELETE) {
|
||||
if (lt(VIsual, curwin->w_cursor)) {
|
||||
VIsual.col = 0;
|
||||
curwin->w_cursor.col =
|
||||
@@ -1676,20 +1678,15 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
&& (include_line_break || !virtual_op)
|
||||
) {
|
||||
oap->inclusive = false;
|
||||
/* Try to include the newline, unless it's an operator
|
||||
* that works on lines only. */
|
||||
if (*p_sel != 'o' && !op_on_lines(oap->op_type)) {
|
||||
if (oap->end.lnum < curbuf->b_ml.ml_line_count) {
|
||||
++oap->end.lnum;
|
||||
// Try to include the newline, unless it's an operator
|
||||
// that works on lines only.
|
||||
if (*p_sel != 'o'
|
||||
&& !op_on_lines(oap->op_type)
|
||||
&& oap->end.lnum < curbuf->b_ml.ml_line_count) {
|
||||
oap->end.lnum++;
|
||||
oap->end.col = 0;
|
||||
oap->end.coladd = 0;
|
||||
++oap->line_count;
|
||||
} else {
|
||||
/* Cannot move below the last line, make the op
|
||||
* inclusive to tell the operation to include the
|
||||
* line break. */
|
||||
oap->inclusive = true;
|
||||
}
|
||||
oap->line_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1555,55 +1555,31 @@ int op_delete(oparg_T *oap)
|
||||
if (gchar_cursor() != NUL)
|
||||
curwin->w_cursor.coladd = 0;
|
||||
}
|
||||
if (oap->op_type == OP_DELETE
|
||||
&& oap->inclusive
|
||||
&& oap->end.lnum == curbuf->b_ml.ml_line_count
|
||||
&& n > (int)STRLEN(ml_get(oap->end.lnum))) {
|
||||
/* Special case: gH<Del> deletes the last line. */
|
||||
del_lines(1L, FALSE);
|
||||
|
||||
(void)del_bytes((long)n, !virtual_op,
|
||||
oap->op_type == OP_DELETE && !oap->is_VIsual);
|
||||
} else {
|
||||
(void)del_bytes((long)n, !virtual_op, oap->op_type == OP_DELETE
|
||||
&& !oap->is_VIsual
|
||||
);
|
||||
}
|
||||
} else { /* delete characters between lines */
|
||||
// delete characters between lines
|
||||
pos_T curpos;
|
||||
int delete_last_line;
|
||||
|
||||
/* save deleted and changed lines for undo */
|
||||
if (u_save((linenr_T)(curwin->w_cursor.lnum - 1),
|
||||
(linenr_T)(curwin->w_cursor.lnum + oap->line_count)) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
delete_last_line = (oap->end.lnum == curbuf->b_ml.ml_line_count);
|
||||
truncate_line(TRUE); /* delete from cursor to end of line */
|
||||
truncate_line(true); // delete from cursor to end of line
|
||||
|
||||
curpos = curwin->w_cursor; /* remember curwin->w_cursor */
|
||||
++curwin->w_cursor.lnum;
|
||||
del_lines(oap->line_count - 2, FALSE);
|
||||
|
||||
if (delete_last_line)
|
||||
oap->end.lnum = curbuf->b_ml.ml_line_count;
|
||||
curpos = curwin->w_cursor; // remember curwin->w_cursor
|
||||
curwin->w_cursor.lnum++;
|
||||
del_lines(oap->line_count - 2, false);
|
||||
|
||||
// delete from start of line until op_end
|
||||
n = (oap->end.col + 1 - !oap->inclusive);
|
||||
if (oap->inclusive && delete_last_line
|
||||
&& n > (int)STRLEN(ml_get(oap->end.lnum))) {
|
||||
/* Special case: gH<Del> deletes the last line. */
|
||||
del_lines(1L, FALSE);
|
||||
curwin->w_cursor = curpos; /* restore curwin->w_cursor */
|
||||
if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
|
||||
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
|
||||
} else {
|
||||
/* delete from start of line until op_end */
|
||||
curwin->w_cursor.col = 0;
|
||||
(void)del_bytes((long)n, !virtual_op, oap->op_type == OP_DELETE
|
||||
&& !oap->is_VIsual
|
||||
);
|
||||
curwin->w_cursor = curpos; /* restore curwin->w_cursor */
|
||||
}
|
||||
if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
|
||||
do_join(2, FALSE, FALSE, FALSE, false);
|
||||
}
|
||||
(void)del_bytes((long)n, !virtual_op,
|
||||
oap->op_type == OP_DELETE && !oap->is_VIsual);
|
||||
curwin->w_cursor = curpos; // restore curwin->w_cursor
|
||||
(void)do_join(2, false, false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -554,7 +554,7 @@ static int included_patches[] = {
|
||||
737,
|
||||
736,
|
||||
// 735 NA
|
||||
// 734,
|
||||
734,
|
||||
// 733,
|
||||
732,
|
||||
// 731 NA
|
||||
|
@@ -24,6 +24,20 @@ local function source_user_functions()
|
||||
]])
|
||||
end
|
||||
|
||||
local function put_abc()
|
||||
source([[
|
||||
$put ='a'
|
||||
$put ='b'
|
||||
$put ='c']])
|
||||
end
|
||||
|
||||
local function define_select_mode_maps()
|
||||
source([[
|
||||
snoremap <lt>End> <End>
|
||||
snoremap <lt>Down> <Down>
|
||||
snoremap <lt>Del> <Del>]])
|
||||
end
|
||||
|
||||
describe('Visual mode and operator', function()
|
||||
before_each(function()
|
||||
clear()
|
||||
@@ -150,4 +164,147 @@ describe('Visual mode and operator', function()
|
||||
ok
|
||||
ok]])
|
||||
end)
|
||||
|
||||
describe('characterwise visual mode:', function()
|
||||
it('replace last line', function()
|
||||
source([[
|
||||
$put ='a'
|
||||
let @" = 'x']])
|
||||
feed('v$p')
|
||||
|
||||
expect([[
|
||||
|
||||
x]])
|
||||
end)
|
||||
|
||||
it('delete middle line', function()
|
||||
put_abc()
|
||||
feed('kkv$d')
|
||||
|
||||
expect([[
|
||||
|
||||
b
|
||||
c]])
|
||||
end)
|
||||
|
||||
it('delete middle two line', function()
|
||||
put_abc()
|
||||
feed('kkvj$d')
|
||||
|
||||
expect([[
|
||||
|
||||
c]])
|
||||
end)
|
||||
|
||||
it('delete last line', function()
|
||||
put_abc()
|
||||
feed('v$d')
|
||||
|
||||
expect([[
|
||||
|
||||
a
|
||||
b
|
||||
]])
|
||||
end)
|
||||
|
||||
it('delete last two line', function()
|
||||
put_abc()
|
||||
feed('kvj$d')
|
||||
|
||||
expect([[
|
||||
|
||||
a
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('characterwise select mode:', function()
|
||||
before_each(function()
|
||||
define_select_mode_maps()
|
||||
end)
|
||||
|
||||
it('delete middle line', function()
|
||||
put_abc()
|
||||
feed('kkgh<End><Del>')
|
||||
|
||||
expect([[
|
||||
|
||||
b
|
||||
c]])
|
||||
end)
|
||||
|
||||
it('delete middle two line', function()
|
||||
put_abc()
|
||||
feed('kkgh<Down><End><Del>')
|
||||
|
||||
expect([[
|
||||
|
||||
c]])
|
||||
end)
|
||||
|
||||
it('delete last line', function()
|
||||
put_abc()
|
||||
feed('gh<End><Del>')
|
||||
|
||||
expect([[
|
||||
|
||||
a
|
||||
b
|
||||
]])
|
||||
end)
|
||||
|
||||
it('delete last two line', function()
|
||||
put_abc()
|
||||
feed('kgh<Down><End><Del>')
|
||||
|
||||
expect([[
|
||||
|
||||
a
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('linewise select mode:', function()
|
||||
before_each(function()
|
||||
define_select_mode_maps()
|
||||
end)
|
||||
|
||||
it('delete middle line', function()
|
||||
put_abc()
|
||||
feed(' kkgH<Del> ')
|
||||
|
||||
expect([[
|
||||
|
||||
b
|
||||
c]])
|
||||
end)
|
||||
|
||||
it('delete middle two line', function()
|
||||
put_abc()
|
||||
feed('kkgH<Down><Del>')
|
||||
|
||||
expect([[
|
||||
|
||||
c]])
|
||||
end)
|
||||
|
||||
it('delete last line', function()
|
||||
put_abc()
|
||||
feed('gH<Del>')
|
||||
|
||||
expect([[
|
||||
|
||||
a
|
||||
b]])
|
||||
end)
|
||||
|
||||
it('delete last two line', function()
|
||||
put_abc()
|
||||
feed('kgH<Down><Del>')
|
||||
|
||||
expect([[
|
||||
|
||||
a]])
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
Reference in New Issue
Block a user