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.