]> granicus.if.org Git - vim/commitdiff
patch 9.0.0841: deletebufline() does not always return 1 on failure v9.0.0841
authorzeertzjq <zeertzjq@outlook.com>
Sun, 6 Nov 2022 22:26:05 +0000 (22:26 +0000)
committerBram Moolenaar <Bram@vim.org>
Sun, 6 Nov 2022 22:26:05 +0000 (22:26 +0000)
Problem:    deletebufline() does not always return 1 on failure.
Solution:   Refactor the code to make it work more predictable. (closes #11511)

src/evalbuffer.c
src/testdir/test_bufline.vim
src/version.c

index 9ce1d41aeb3a8f5a1241ecbb056fb87aee73d8e8..4a9d5989ebb88f9a6ecda0777ee073f04edc0b53 100644 (file)
@@ -535,6 +535,7 @@ f_deletebufline(typval_T *argvars, typval_T *rettv)
                           || first > buf->b_ml.ml_line_count || last < first)
        return;
 
+    // After this don't use "return", goto "cleanup"!
     if (!is_curbuf)
     {
        VIsual_active = FALSE;
@@ -556,38 +557,35 @@ f_deletebufline(typval_T *argvars, typval_T *rettv)
     }
 
     if (u_save(first - 1, last + 1) == FAIL)
-    {
-       rettv->vval.v_number = 1;       // FAIL
-    }
-    else
-    {
-       for (lnum = first; lnum <= last; ++lnum)
-           ml_delete_flags(first, ML_DEL_MESSAGE);
+       goto cleanup;
 
-       FOR_ALL_TAB_WINDOWS(tp, wp)
-           if (wp->w_buffer == buf)
-           {
-               if (wp->w_cursor.lnum > last)
-                   wp->w_cursor.lnum -= count;
-               else if (wp->w_cursor.lnum > first)
-                   wp->w_cursor.lnum = first;
-               if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count)
-                   wp->w_cursor.lnum = wp->w_buffer->b_ml.ml_line_count;
-               wp->w_valid = 0;
-               if (wp->w_cursor.lnum <= wp->w_topline)
-                   wp->w_topline = 1;
-           }
-       check_cursor_col();
-       deleted_lines_mark(first, count);
-    }
+    for (lnum = first; lnum <= last; ++lnum)
+       ml_delete_flags(first, ML_DEL_MESSAGE);
+
+    FOR_ALL_TAB_WINDOWS(tp, wp)
+       if (wp->w_buffer == buf)
+       {
+           if (wp->w_cursor.lnum > last)
+               wp->w_cursor.lnum -= count;
+           else if (wp->w_cursor.lnum > first)
+               wp->w_cursor.lnum = first;
+           if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count)
+               wp->w_cursor.lnum = wp->w_buffer->b_ml.ml_line_count;
+           wp->w_valid = 0;
+           if (wp->w_cursor.lnum <= wp->w_topline)
+               wp->w_topline = 1;
+       }
+    check_cursor_col();
+    deleted_lines_mark(first, count);
+    rettv->vval.v_number = 0; // OK
 
+cleanup:
     if (!is_curbuf)
     {
        curbuf = curbuf_save;
        curwin = curwin_save;
        VIsual_active = save_VIsual_active;
     }
-    rettv->vval.v_number = 0; // OK
 }
 
 /*
index 13e891bcf15327ccb046ccec092f9a43d67ef2df..da8c4a5aa2582755ab6cf5d1a9986908e899b214 100644 (file)
@@ -279,4 +279,20 @@ func Test_setbufline_startup_nofile()
   call delete('Xresult')
 endfunc
 
+" Test that setbufline(), appendbufline() and deletebufline() should fail and
+" return 1 when "textlock" is active.
+func Test_change_bufline_with_textlock()
+  new
+  inoremap <buffer> <expr> <F2> setbufline('', 1, '')
+  call assert_fails("normal a\<F2>", 'E565:')
+  call assert_equal('1', getline(1))
+  inoremap <buffer> <expr> <F2> appendbufline('', 1, '')
+  call assert_fails("normal a\<F2>", 'E565:')
+  call assert_equal('11', getline(1))
+  inoremap <buffer> <expr> <F2> deletebufline('', 1)
+  call assert_fails("normal a\<F2>", 'E565:')
+  call assert_equal('111', getline(1))
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index e7dc5a5b5c324e1b870c6389cfca8a841a7a1a96..0e59a7874cfef4f8d41535eabfcf2cc8d2c9dde8 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    841,
 /**/
     840,
 /**/