# HG changeset patch # User Bram Moolenaar # Date 1433874003 -7200 # Node ID bf3e6012dfbd3b404ae1d0e41ff90a9628380062 # Parent e274ed6dd30894cab5a4f76679539aeb8189ce9d 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) diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -1547,8 +1547,10 @@ do_pending_operator(cap, old_col, gui_ya } /* In Select mode, a linewise selection is operated upon like a - * characterwise selection. */ - if (VIsual_select && VIsual_mode == 'V') + * characterwise selection. + * Special case: gH deletes the last line. */ + if (VIsual_select && VIsual_mode == 'V' + && cap->oap->op_type != OP_DELETE) { if (lt(VIsual, curwin->w_cursor)) { @@ -1770,24 +1772,16 @@ do_pending_operator(cap, old_col, gui_ya 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 (*p_sel != 'o' + && !op_on_lines(oap->op_type) + && oap->end.lnum < curbuf->b_ml.ml_line_count) { - if (oap->end.lnum < curbuf->b_ml.ml_line_count) - { - ++oap->end.lnum; - oap->end.col = 0; + ++oap->end.lnum; + oap->end.col = 0; #ifdef FEAT_VIRTUALEDIT - oap->end.coladd = 0; -#endif - ++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->end.coladd = 0; +#endif + ++oap->line_count; } } } diff --git a/src/ops.c b/src/ops.c --- a/src/ops.c +++ b/src/ops.c @@ -1959,60 +1959,31 @@ op_delete(oap) curwin->w_cursor.coladd = 0; } #endif - 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 deletes the last line. */ - del_lines(1L, FALSE); - } - else - { - (void)del_bytes((long)n, !virtual_op, - oap->op_type == OP_DELETE && !oap->is_VIsual); - } + (void)del_bytes((long)n, !virtual_op, + oap->op_type == OP_DELETE && !oap->is_VIsual); } else /* 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 */ curpos = curwin->w_cursor; /* remember curwin->w_cursor */ ++curwin->w_cursor.lnum; del_lines((long)(oap->line_count - 2), FALSE); - if (delete_last_line) - oap->end.lnum = curbuf->b_ml.ml_line_count; - + /* 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 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) - (void)do_join(2, FALSE, FALSE, FALSE, FALSE); + 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 */ + (void)do_join(2, FALSE, FALSE, FALSE, FALSE); } } diff --git a/src/testdir/test94.in b/src/testdir/test94.in --- a/src/testdir/test94.in +++ b/src/testdir/test94.in @@ -64,6 +64,116 @@ dV: dv: :set noma | let v:errmsg = '' d: :set ma | put = v:errmsg =~# '^E21' ? 'ok' : 'failed' dv:dV::set noma | let v:errmsg = '' d::set ma | put = v:errmsg =~# '^E21' ? 'failed' : 'ok' +: +:$put ='' +:$put ='characterwise visual mode: replace last line' +:$put ='a' +:let @" = 'x' +:let v:errmsg = '' +v$p +:$put ='---' +:$put ='v:errmsg='.v:errmsg +: +:$put ='' +:$put ='characterwise visual mode: delete middle line' +:$put ='a' +:$put ='b' +:$put ='c' +kkv$d +:$put ='---' +: +:$put ='' +:$put ='characterwise visual mode: delete middle two line' +:$put ='a' +:$put ='b' +:$put ='c' +kkvj$d +:$put ='---' +: +:$put ='' +:$put ='characterwise visual mode: delete last line' +:$put ='a' +:$put ='b' +:$put ='c' +v$d +:$put ='---' +: +:$put ='' +:$put ='characterwise visual mode: delete last two line' +:$put ='a' +:$put ='b' +:$put ='c' +kvj$d +:$put ='---' +: +:" Select mode maps +:snoremap End> +:snoremap Down> +:snoremap Del> +: +:$put ='' +:$put ='characterwise select mode: delete middle line' +:$put ='a' +:$put ='b' +:$put ='c' +kkgh +:$put ='---' +: +:$put ='' +:$put ='characterwise select mode: delete middle two line' +:$put ='a' +:$put ='b' +:$put ='c' +kkgh +:$put ='---' +: +:$put ='' +:$put ='characterwise select mode: delete last line' +:$put ='a' +:$put ='b' +:$put ='c' +gh +:$put ='---' +: +:$put ='' +:$put ='characterwise select mode: delete last two line' +:$put ='a' +:$put ='b' +:$put ='c' +kgh +:$put ='---' +: +:$put ='' +:$put ='linewise select mode: delete middle line' +:$put ='a' +:$put ='b' +:$put ='c' +kkgH +:$put ='---' +: +:$put ='' +:$put ='linewise select mode: delete middle two line' +:$put ='a' +:$put ='b' +:$put ='c' +kkgH +:$put ='---' +: +:$put ='' +:$put ='linewise select mode: delete last line' +:$put ='a' +:$put ='b' +:$put ='c' +gH +:$put ='---' +: +:$put ='' +:$put ='linewise select mode: delete last two line' +:$put ='a' +:$put ='b' +:$put ='c' +kgH +:$put ='---' :/^start:/+2,$w! test.out :q! ENDTEST diff --git a/src/testdir/test94.ok b/src/testdir/test94.ok --- a/src/testdir/test94.ok +++ b/src/testdir/test94.ok @@ -18,3 +18,66 @@ LemonNewNewZ zzz ok ok + +characterwise visual mode: replace last line +x +--- +v:errmsg= + +characterwise visual mode: delete middle line +b +c +--- + +characterwise visual mode: delete middle two line +c +--- + +characterwise visual mode: delete last line +a +b + +--- + +characterwise visual mode: delete last two line +a + +--- + +characterwise select mode: delete middle line +b +c +--- + +characterwise select mode: delete middle two line +c +--- + +characterwise select mode: delete last line +a +b + +--- + +characterwise select mode: delete last two line +a + +--- + +linewise select mode: delete middle line +b +c +--- + +linewise select mode: delete middle two line +c +--- + +linewise select mode: delete last line +a +b +--- + +linewise select mode: delete last two line +a +--- diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 734, +/**/ 733, /**/ 732,