]> granicus.if.org Git - vim/commitdiff
patch 8.0.0548: saving the redo buffer only works one time v8.0.0548
authorBram Moolenaar <Bram@vim.org>
Fri, 7 Apr 2017 17:50:12 +0000 (19:50 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 7 Apr 2017 17:50:12 +0000 (19:50 +0200)
Problem:    Saving the redo buffer only works one time, resulting in the "."
            command not working well for a function call inside another
            function call. (Ingo Karkat)
Solution:   Save the redo buffer at every user function call. (closes #1619)

src/fileio.c
src/getchar.c
src/proto/getchar.pro
src/structs.h
src/testdir/test_functions.vim
src/userfunc.c
src/version.c

index e74392075be0b9670d6fca8f6d883cfe44ba274c..b41df3e7b8ec578693cd89dc55e5f59b0258e7a9 100644 (file)
@@ -9316,6 +9316,7 @@ apply_autocmds_group(
     proftime_T wait_time;
 #endif
     int                did_save_redobuff = FALSE;
+    save_redo_T        save_redo;
 
     /*
      * Quickly return if there are no autocommands for this event or
@@ -9521,7 +9522,7 @@ apply_autocmds_group(
        if (!ins_compl_active())
 #endif
        {
-           saveRedobuff();
+           saveRedobuff(&save_redo);
            did_save_redobuff = TRUE;
        }
        did_filetype = keep_filetype;
@@ -9624,7 +9625,7 @@ apply_autocmds_group(
     {
        restore_search_patterns();
        if (did_save_redobuff)
-           restoreRedobuff();
+           restoreRedobuff(&save_redo);
        did_filetype = FALSE;
        while (au_pending_free_buf != NULL)
        {
index 011648d64c58e3890a656ed891a51dbf4358ff35..c057861a61698c0f6ecb4d63a8199e008374111a 100644 (file)
 
 static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0};
 static buffheader_T old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
-#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
-static buffheader_T save_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
-static buffheader_T save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
-#endif
 static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
 
 static int typeahead_char = 0;         /* typeahead char that's not flushed */
@@ -521,27 +517,22 @@ CancelRedo(void)
  * Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
  * Used before executing autocommands and user functions.
  */
-static int save_level = 0;
-
     void
-saveRedobuff(void)
+saveRedobuff(save_redo_T *save_redo)
 {
     char_u     *s;
 
-    if (save_level++ == 0)
-    {
-       save_redobuff = redobuff;
-       redobuff.bh_first.b_next = NULL;
-       save_old_redobuff = old_redobuff;
-       old_redobuff.bh_first.b_next = NULL;
+    save_redo->sr_redobuff = redobuff;
+    redobuff.bh_first.b_next = NULL;
+    save_redo->sr_old_redobuff = old_redobuff;
+    old_redobuff.bh_first.b_next = NULL;
 
-       /* Make a copy, so that ":normal ." in a function works. */
-       s = get_buffcont(&save_redobuff, FALSE);
-       if (s != NULL)
-       {
-           add_buff(&redobuff, s, -1L);
-           vim_free(s);
-       }
+    /* Make a copy, so that ":normal ." in a function works. */
+    s = get_buffcont(&save_redo->sr_redobuff, FALSE);
+    if (s != NULL)
+    {
+       add_buff(&redobuff, s, -1L);
+       vim_free(s);
     }
 }
 
@@ -550,15 +541,12 @@ saveRedobuff(void)
  * Used after executing autocommands and user functions.
  */
     void
-restoreRedobuff(void)
+restoreRedobuff(save_redo_T *save_redo)
 {
-    if (--save_level == 0)
-    {
-       free_buff(&redobuff);
-       redobuff = save_redobuff;
-       free_buff(&old_redobuff);
-       old_redobuff = save_old_redobuff;
-    }
+    free_buff(&redobuff);
+    redobuff = save_redo->sr_redobuff;
+    free_buff(&old_redobuff);
+    old_redobuff = save_redo->sr_old_redobuff;
 }
 #endif
 
index de33bfd147b5567aa1efb143fa922dbe3ad193d6..aac522f1529e440fc44bdd736257ea12d20f0d90 100644 (file)
@@ -8,8 +8,8 @@ void typeahead_noflush(int c);
 void flush_buffers(int flush_typeahead);
 void ResetRedobuff(void);
 void CancelRedo(void);
-void saveRedobuff(void);
-void restoreRedobuff(void);
+void saveRedobuff(save_redo_T *save_redo);
+void restoreRedobuff(save_redo_T *save_redo);
 void AppendToRedobuff(char_u *s);
 void AppendToRedobuffLit(char_u *str, int len);
 void AppendCharToRedobuff(int c);
index 475280af12dc7ea15d56cde6cb70f4e5a0674166..0175017423c72d15c3b2c9421009b7e4150e44ee 100644 (file)
@@ -515,6 +515,12 @@ struct buffheader
     int                bh_space;       /* space in bh_curr for appending */
 };
 
+typedef struct
+{
+    buffheader_T sr_redobuff;
+    buffheader_T sr_old_redobuff;
+} save_redo_T;
+
 /*
  * used for completion on the command line
  */
index 2a0c1cf72dbfffe568f7bc5e77d7923bdef62b0f..e569ef1dcaa642e1a230fcbc45b120708030cd5c 100644 (file)
@@ -756,3 +756,31 @@ func Test_setbufvar_options()
   call win_gotoid(dum1_id)
   bwipe!
 endfunc
+
+func Test_redo_in_nested_functions()
+  nnoremap g. :set opfunc=Operator<CR>g@
+  function Operator( type, ... )
+     let @x = 'XXX'
+     execute 'normal! g`[' . (a:type ==# 'line' ? 'V' : 'v') . 'g`]' . '"xp'
+  endfunction
+
+  function! Apply()
+      5,6normal! .
+  endfunction
+
+  new
+  call setline(1, repeat(['some "quoted" text', 'more "quoted" text'], 3))
+  1normal g.i"
+  call assert_equal('some "XXX" text', getline(1))
+  3,4normal .
+  call assert_equal('some "XXX" text', getline(3))
+  call assert_equal('more "XXX" text', getline(4))
+  call Apply()
+  call assert_equal('some "XXX" text', getline(5))
+  call assert_equal('more "XXX" text', getline(6))
+  bwipe!
+
+  nunmap g.
+  delfunc Operator
+  delfunc Apply
+endfunc
index fc2216dd8a20f8c59bb9b90d081d8836d4305e7f..859e6ebec08de97e7743da5e168b84f7d3001048 100644 (file)
@@ -1408,6 +1408,7 @@ call_func(
                else
                {
                    int did_save_redo = FALSE;
+                   save_redo_T save_redo;
 
                    /*
                     * Call the user function.
@@ -1419,7 +1420,7 @@ call_func(
                    if (!ins_compl_active())
 #endif
                    {
-                       saveRedobuff();
+                       saveRedobuff(&save_redo);
                        did_save_redo = TRUE;
                    }
                    ++fp->uf_calls;
@@ -1431,7 +1432,7 @@ call_func(
                         * now. */
                        func_clear_free(fp, FALSE);
                    if (did_save_redo)
-                       restoreRedobuff();
+                       restoreRedobuff(&save_redo);
                    restore_search_patterns();
                    error = ERROR_NONE;
                }
index 12cf4841a5f81c71e914e4e834fb86b1d63f282f..e856ba5c07784967d266b0696cd108c32b644686 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    548,
 /**/
     547,
 /**/