vim-patch:8.1.1890: ml_get error when deleting fold marker

Problem:    Ml_get error when deleting fold marker.
Solution:   Check that the line number is not below the last line.  Adjust the
            fold when deleting the empty line.  (Christian Brabandt,
            closes vim/vim#4834)
9a4a8c4d59
This commit is contained in:
Jan Edmund Lazo
2019-08-19 21:23:43 -04:00
parent 419c946f03
commit ec9b57cb6e
3 changed files with 36 additions and 11 deletions

View File

@@ -1645,19 +1645,22 @@ deleteFoldMarkers(
foldendmarkerlen); foldendmarkerlen);
} }
/* foldDelMarker() {{{2 */ // foldDelMarker() {{{2
/* //
* Delete marker "marker[markerlen]" at the end of line "lnum". // Delete marker "marker[markerlen]" at the end of line "lnum".
* Delete 'commentstring' if it matches. // Delete 'commentstring' if it matches.
* If the marker is not found, there is no error message. Could a missing // If the marker is not found, there is no error message. Could be a missing
* close-marker. // close-marker.
*/
static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen) static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen)
{ {
char_u *newline; char_u *newline;
char_u *cms = curbuf->b_p_cms; char_u *cms = curbuf->b_p_cms;
char_u *cms2; char_u *cms2;
// end marker may be missing and fold extends below the last line
if (lnum > curbuf->b_ml.ml_line_count) {
return;
}
char_u *line = ml_get(lnum); char_u *line = ml_get(lnum);
for (char_u *p = line; *p != NUL; ++p) { for (char_u *p = line; *p != NUL; ++p) {
if (STRNCMP(p, marker, markerlen) != 0) { if (STRNCMP(p, marker, markerlen) != 0) {
@@ -2426,15 +2429,18 @@ static linenr_T foldUpdateIEMSRecurse(
* lvl >= level: fold continues below "bot" * lvl >= level: fold continues below "bot"
*/ */
/* Current fold at least extends until lnum. */ // Current fold at least extends until lnum.
if (fp->fd_len < flp->lnum - fp->fd_top) { if (fp->fd_len < flp->lnum - fp->fd_top) {
fp->fd_len = flp->lnum - fp->fd_top; fp->fd_len = flp->lnum - fp->fd_top;
fp->fd_small = kNone; fp->fd_small = kNone;
fold_changed = true; fold_changed = true;
} else if (fp->fd_top + fp->fd_len > linecount) {
// running into the end of the buffer (deleted last line)
fp->fd_len = linecount - fp->fd_top + 1;
} }
/* Delete contained folds from the end of the last one found until where // Delete contained folds from the end of the last one found until where
* we stopped looking. */ // we stopped looking.
foldRemove(&fp->fd_nested, startlnum2 - fp->fd_top, foldRemove(&fp->fd_nested, startlnum2 - fp->fd_top,
flp->lnum - 1 - fp->fd_top); flp->lnum - 1 - fp->fd_top);

View File

@@ -7827,13 +7827,15 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
// 'virtualedit' and past the end of the line, we use the 'c' operator in // 'virtualedit' and past the end of the line, we use the 'c' operator in
// do_put(), which requires the visual selection to still be active. // do_put(), which requires the visual selection to still be active.
if (!VIsual_active || VIsual_mode == 'V' || regname != '.') { if (!VIsual_active || VIsual_mode == 'V' || regname != '.') {
// Now delete the selected text. // Now delete the selected text. Avoid messages here.
cap->cmdchar = 'd'; cap->cmdchar = 'd';
cap->nchar = NUL; cap->nchar = NUL;
cap->oap->regname = NUL; cap->oap->regname = NUL;
msg_silent++;
nv_operator(cap); nv_operator(cap);
do_pending_operator(cap, 0, false); do_pending_operator(cap, 0, false);
empty = (curbuf->b_ml.ml_flags & ML_EMPTY); empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
msg_silent--;
// delete PUT_LINE_BACKWARD; // delete PUT_LINE_BACKWARD;
cap->oap->regname = regname; cap->oap->regname = regname;
@@ -7882,6 +7884,7 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
* line that needs to be deleted now. */ * line that needs to be deleted now. */
if (empty && *ml_get(curbuf->b_ml.ml_line_count) == NUL) { if (empty && *ml_get(curbuf->b_ml.ml_line_count) == NUL) {
ml_delete(curbuf->b_ml.ml_line_count, true); ml_delete(curbuf->b_ml.ml_line_count, true);
deleted_lines(curbuf->b_ml.ml_line_count + 1, 1);
/* If the cursor was in that line, move it to the end of the last /* If the cursor was in that line, move it to the end of the last
* line. */ * line. */

View File

@@ -740,3 +740,19 @@ func Test_folds_marker_in_comment2()
set foldmethod& set foldmethod&
bwipe! bwipe!
endfunc endfunc
func Test_fold_delete_with_marker()
new
call setline(1, ['func Func() {{{1', 'endfunc'])
1,2yank
new
set fdm=marker
call setline(1, 'x')
normal! Vp
normal! zd
call assert_equal(['func Func() ', 'endfunc'], getline(1, '$'))
set fdm&
bwipe!
bwipe!
endfunc