Skip to content

Commit

Permalink
patch 8.0.0548: saving the redo buffer only works one time
Browse files Browse the repository at this point in the history
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 d4863aa
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 34 deletions.
5 changes: 3 additions & 2 deletions src/fileio.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -9316,6 +9316,7 @@ apply_autocmds_group(
proftime_T wait_time; proftime_T wait_time;
#endif #endif
int did_save_redobuff = FALSE; int did_save_redobuff = FALSE;
save_redo_T save_redo;


/* /*
* Quickly return if there are no autocommands for this event or * Quickly return if there are no autocommands for this event or
Expand Down Expand Up @@ -9521,7 +9522,7 @@ apply_autocmds_group(
if (!ins_compl_active()) if (!ins_compl_active())
#endif #endif
{ {
saveRedobuff(); saveRedobuff(&save_redo);
did_save_redobuff = TRUE; did_save_redobuff = TRUE;
} }
did_filetype = keep_filetype; did_filetype = keep_filetype;
Expand Down Expand Up @@ -9624,7 +9625,7 @@ apply_autocmds_group(
{ {
restore_search_patterns(); restore_search_patterns();
if (did_save_redobuff) if (did_save_redobuff)
restoreRedobuff(); restoreRedobuff(&save_redo);
did_filetype = FALSE; did_filetype = FALSE;
while (au_pending_free_buf != NULL) while (au_pending_free_buf != NULL)
{ {
Expand Down
44 changes: 16 additions & 28 deletions src/getchar.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@


static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0}; static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0};
static buffheader_T old_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 buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0};


static int typeahead_char = 0; /* typeahead char that's not flushed */ static int typeahead_char = 0; /* typeahead char that's not flushed */
Expand Down Expand Up @@ -521,27 +517,22 @@ CancelRedo(void)
* Save redobuff and old_redobuff to save_redobuff and save_old_redobuff. * Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
* Used before executing autocommands and user functions. * Used before executing autocommands and user functions.
*/ */
static int save_level = 0;

void void
saveRedobuff(void) saveRedobuff(save_redo_T *save_redo)
{ {
char_u *s; char_u *s;


if (save_level++ == 0) save_redo->sr_redobuff = redobuff;
{ redobuff.bh_first.b_next = NULL;
save_redobuff = redobuff; save_redo->sr_old_redobuff = old_redobuff;
redobuff.bh_first.b_next = NULL; old_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. */ /* Make a copy, so that ":normal ." in a function works. */
s = get_buffcont(&save_redobuff, FALSE); s = get_buffcont(&save_redo->sr_redobuff, FALSE);
if (s != NULL) if (s != NULL)
{ {
add_buff(&redobuff, s, -1L); add_buff(&redobuff, s, -1L);
vim_free(s); vim_free(s);
}
} }
} }


Expand All @@ -550,15 +541,12 @@ saveRedobuff(void)
* Used after executing autocommands and user functions. * Used after executing autocommands and user functions.
*/ */
void void
restoreRedobuff(void) restoreRedobuff(save_redo_T *save_redo)
{ {
if (--save_level == 0) free_buff(&redobuff);
{ redobuff = save_redo->sr_redobuff;
free_buff(&redobuff); free_buff(&old_redobuff);
redobuff = save_redobuff; old_redobuff = save_redo->sr_old_redobuff;
free_buff(&old_redobuff);
old_redobuff = save_old_redobuff;
}
} }
#endif #endif


Expand Down
4 changes: 2 additions & 2 deletions src/proto/getchar.pro
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ void typeahead_noflush(int c);
void flush_buffers(int flush_typeahead); void flush_buffers(int flush_typeahead);
void ResetRedobuff(void); void ResetRedobuff(void);
void CancelRedo(void); void CancelRedo(void);
void saveRedobuff(void); void saveRedobuff(save_redo_T *save_redo);
void restoreRedobuff(void); void restoreRedobuff(save_redo_T *save_redo);
void AppendToRedobuff(char_u *s); void AppendToRedobuff(char_u *s);
void AppendToRedobuffLit(char_u *str, int len); void AppendToRedobuffLit(char_u *str, int len);
void AppendCharToRedobuff(int c); void AppendCharToRedobuff(int c);
Expand Down
6 changes: 6 additions & 0 deletions src/structs.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -515,6 +515,12 @@ struct buffheader
int bh_space; /* space in bh_curr for appending */ 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 * used for completion on the command line
*/ */
Expand Down
28 changes: 28 additions & 0 deletions src/testdir/test_functions.vim
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -756,3 +756,31 @@ func Test_setbufvar_options()
call win_gotoid(dum1_id) call win_gotoid(dum1_id)
bwipe! bwipe!
endfunc 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
5 changes: 3 additions & 2 deletions src/userfunc.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1408,6 +1408,7 @@ call_func(
else else
{ {
int did_save_redo = FALSE; int did_save_redo = FALSE;
save_redo_T save_redo;


/* /*
* Call the user function. * Call the user function.
Expand All @@ -1419,7 +1420,7 @@ call_func(
if (!ins_compl_active()) if (!ins_compl_active())
#endif #endif
{ {
saveRedobuff(); saveRedobuff(&save_redo);
did_save_redo = TRUE; did_save_redo = TRUE;
} }
++fp->uf_calls; ++fp->uf_calls;
Expand All @@ -1431,7 +1432,7 @@ call_func(
* now. */ * now. */
func_clear_free(fp, FALSE); func_clear_free(fp, FALSE);
if (did_save_redo) if (did_save_redo)
restoreRedobuff(); restoreRedobuff(&save_redo);
restore_search_patterns(); restore_search_patterns();
error = ERROR_NONE; error = ERROR_NONE;
} }
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -764,6 +764,8 @@ static char *(features[]) =


static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
548,
/**/ /**/
547, 547,
/**/ /**/
Expand Down

0 comments on commit d4863aa

Please sign in to comment.