Patch 8.0.0548
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)
Files:      src/getchar.c, src/proto/getchar.pro, src/structs.h,
            src/fileio.c, src/userfunc.c, src/testdir/test_functions.vim


*** ../vim-8.0.0547/src/getchar.c       2017-03-16 17:23:26.823815869 +0100
--- src/getchar.c       2017-04-07 19:39:39.270876710 +0200
***************
*** 42,51 ****
  
  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 */
--- 42,47 ----
***************
*** 521,547 ****
   * 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)
  {
      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;
! 
!       /* 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);
!       }
      }
  }
  
--- 517,538 ----
   * Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
   * Used before executing autocommands and user functions.
   */
      void
! saveRedobuff(save_redo_T *save_redo)
  {
      char_u    *s;
  
!     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_redo->sr_redobuff, FALSE);
!     if (s != NULL)
      {
!       add_buff(&redobuff, s, -1L);
!       vim_free(s);
      }
  }
  
***************
*** 550,564 ****
   * Used after executing autocommands and user functions.
   */
      void
! restoreRedobuff(void)
  {
!     if (--save_level == 0)
!     {
!       free_buff(&redobuff);
!       redobuff = save_redobuff;
!       free_buff(&old_redobuff);
!       old_redobuff = save_old_redobuff;
!     }
  }
  #endif
  
--- 541,552 ----
   * Used after executing autocommands and user functions.
   */
      void
! restoreRedobuff(save_redo_T *save_redo)
  {
!     free_buff(&redobuff);
!     redobuff = save_redo->sr_redobuff;
!     free_buff(&old_redobuff);
!     old_redobuff = save_redo->sr_old_redobuff;
  }
  #endif
  
*** ../vim-8.0.0547/src/proto/getchar.pro       2016-09-12 13:04:04.000000000 
+0200
--- src/proto/getchar.pro       2017-04-07 19:42:58.705664267 +0200
***************
*** 8,15 ****
  void flush_buffers(int flush_typeahead);
  void ResetRedobuff(void);
  void CancelRedo(void);
! void saveRedobuff(void);
! void restoreRedobuff(void);
  void AppendToRedobuff(char_u *s);
  void AppendToRedobuffLit(char_u *str, int len);
  void AppendCharToRedobuff(int c);
--- 8,15 ----
  void flush_buffers(int flush_typeahead);
  void ResetRedobuff(void);
  void CancelRedo(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);
*** ../vim-8.0.0547/src/structs.h       2017-03-08 22:19:21.717870787 +0100
--- src/structs.h       2017-04-07 19:42:14.217934749 +0200
***************
*** 515,520 ****
--- 515,526 ----
      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
   */
*** ../vim-8.0.0547/src/fileio.c        2017-03-19 17:09:51.831080752 +0100
--- src/fileio.c        2017-04-07 19:40:58.598394480 +0200
***************
*** 9316,9321 ****
--- 9316,9322 ----
      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,9527 ****
        if (!ins_compl_active())
  #endif
        {
!           saveRedobuff();
            did_save_redobuff = TRUE;
        }
        did_filetype = keep_filetype;
--- 9522,9528 ----
        if (!ins_compl_active())
  #endif
        {
!           saveRedobuff(&save_redo);
            did_save_redobuff = TRUE;
        }
        did_filetype = keep_filetype;
***************
*** 9624,9630 ****
      {
        restore_search_patterns();
        if (did_save_redobuff)
!           restoreRedobuff();
        did_filetype = FALSE;
        while (au_pending_free_buf != NULL)
        {
--- 9625,9631 ----
      {
        restore_search_patterns();
        if (did_save_redobuff)
!           restoreRedobuff(&save_redo);
        did_filetype = FALSE;
        while (au_pending_free_buf != NULL)
        {
*** ../vim-8.0.0547/src/userfunc.c      2017-04-01 21:21:26.578627608 +0200
--- src/userfunc.c      2017-04-07 19:41:18.590272942 +0200
***************
*** 1408,1413 ****
--- 1408,1414 ----
                else
                {
                    int did_save_redo = FALSE;
+                   save_redo_T save_redo;
  
                    /*
                     * Call the user function.
***************
*** 1419,1425 ****
                    if (!ins_compl_active())
  #endif
                    {
!                       saveRedobuff();
                        did_save_redo = TRUE;
                    }
                    ++fp->uf_calls;
--- 1420,1426 ----
                    if (!ins_compl_active())
  #endif
                    {
!                       saveRedobuff(&save_redo);
                        did_save_redo = TRUE;
                    }
                    ++fp->uf_calls;
***************
*** 1431,1437 ****
                         * now. */
                        func_clear_free(fp, FALSE);
                    if (did_save_redo)
!                       restoreRedobuff();
                    restore_search_patterns();
                    error = ERROR_NONE;
                }
--- 1432,1438 ----
                         * now. */
                        func_clear_free(fp, FALSE);
                    if (did_save_redo)
!                       restoreRedobuff(&save_redo);
                    restore_search_patterns();
                    error = ERROR_NONE;
                }
*** ../vim-8.0.0547/src/testdir/test_functions.vim      2017-03-19 
16:09:41.157653918 +0100
--- src/testdir/test_functions.vim      2017-04-07 19:31:09.941971823 +0200
***************
*** 756,758 ****
--- 756,786 ----
    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
*** ../vim-8.0.0547/src/version.c       2017-04-07 16:17:35.585077280 +0200
--- src/version.c       2017-04-07 19:08:46.534123562 +0200
***************
*** 766,767 ****
--- 766,769 ----
  {   /* Add new patch number below this line */
+ /**/
+     548,
  /**/

-- 
The greatest lies of all time:
  (1) The check is in the mail.
  (2) We have a really challenging assignment for you.
  (3) I love you.
  (4) All bugs have been fixed.
  (5) This won't hurt a bit.
  (6) Honey, I just need to debug this program and be home in 5 minutes.
  (7) I have just sent you an e-mail about that.
  (8) Of course I'll respect you in the morning.
  (9) I'm from the government, and I'm here to help you.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui