Permalink
Browse files

patch 8.0.0548: saving the redo buffer only works one time

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)
  • Loading branch information...
brammool committed Apr 7, 2017
1 parent 52604f2 commit d4863aa99e0527e9505c79cbeafc68a6832200bf
Showing with 60 additions and 34 deletions.
  1. +3 −2 src/fileio.c
  2. +16 −28 src/getchar.c
  3. +2 −2 src/proto/getchar.pro
  4. +6 −0 src/structs.h
  5. +28 −0 src/testdir/test_functions.vim
  6. +3 −2 src/userfunc.c
  7. +2 −0 src/version.c
View
@@ -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)
{
View
@@ -42,10 +42,6 @@
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
View
@@ -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);
View
@@ -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
*/
@@ -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
View
@@ -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;
}
View
@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
548,
/**/
547,
/**/

0 comments on commit d4863aa

Please sign in to comment.