Skip to content

Commit d4863aa

Browse files
committed
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)
1 parent 52604f2 commit d4863aa

7 files changed

Lines changed: 60 additions & 34 deletions

File tree

src/fileio.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9316,6 +9316,7 @@ apply_autocmds_group(
93169316
proftime_T wait_time;
93179317
#endif
93189318
int did_save_redobuff = FALSE;
9319+
save_redo_T save_redo;
93199320

93209321
/*
93219322
* Quickly return if there are no autocommands for this event or
@@ -9521,7 +9522,7 @@ apply_autocmds_group(
95219522
if (!ins_compl_active())
95229523
#endif
95239524
{
9524-
saveRedobuff();
9525+
saveRedobuff(&save_redo);
95259526
did_save_redobuff = TRUE;
95269527
}
95279528
did_filetype = keep_filetype;
@@ -9624,7 +9625,7 @@ apply_autocmds_group(
96249625
{
96259626
restore_search_patterns();
96269627
if (did_save_redobuff)
9627-
restoreRedobuff();
9628+
restoreRedobuff(&save_redo);
96289629
did_filetype = FALSE;
96299630
while (au_pending_free_buf != NULL)
96309631
{

src/getchar.c

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@
4242

4343
static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0};
4444
static buffheader_T old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
45-
#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
46-
static buffheader_T save_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
47-
static buffheader_T save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
48-
#endif
4945
static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
5046

5147
static int typeahead_char = 0; /* typeahead char that's not flushed */
@@ -521,27 +517,22 @@ CancelRedo(void)
521517
* Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
522518
* Used before executing autocommands and user functions.
523519
*/
524-
static int save_level = 0;
525-
526520
void
527-
saveRedobuff(void)
521+
saveRedobuff(save_redo_T *save_redo)
528522
{
529523
char_u *s;
530524

531-
if (save_level++ == 0)
532-
{
533-
save_redobuff = redobuff;
534-
redobuff.bh_first.b_next = NULL;
535-
save_old_redobuff = old_redobuff;
536-
old_redobuff.bh_first.b_next = NULL;
525+
save_redo->sr_redobuff = redobuff;
526+
redobuff.bh_first.b_next = NULL;
527+
save_redo->sr_old_redobuff = old_redobuff;
528+
old_redobuff.bh_first.b_next = NULL;
537529

538-
/* Make a copy, so that ":normal ." in a function works. */
539-
s = get_buffcont(&save_redobuff, FALSE);
540-
if (s != NULL)
541-
{
542-
add_buff(&redobuff, s, -1L);
543-
vim_free(s);
544-
}
530+
/* Make a copy, so that ":normal ." in a function works. */
531+
s = get_buffcont(&save_redo->sr_redobuff, FALSE);
532+
if (s != NULL)
533+
{
534+
add_buff(&redobuff, s, -1L);
535+
vim_free(s);
545536
}
546537
}
547538

@@ -550,15 +541,12 @@ saveRedobuff(void)
550541
* Used after executing autocommands and user functions.
551542
*/
552543
void
553-
restoreRedobuff(void)
544+
restoreRedobuff(save_redo_T *save_redo)
554545
{
555-
if (--save_level == 0)
556-
{
557-
free_buff(&redobuff);
558-
redobuff = save_redobuff;
559-
free_buff(&old_redobuff);
560-
old_redobuff = save_old_redobuff;
561-
}
546+
free_buff(&redobuff);
547+
redobuff = save_redo->sr_redobuff;
548+
free_buff(&old_redobuff);
549+
old_redobuff = save_redo->sr_old_redobuff;
562550
}
563551
#endif
564552

src/proto/getchar.pro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ void typeahead_noflush(int c);
88
void flush_buffers(int flush_typeahead);
99
void ResetRedobuff(void);
1010
void CancelRedo(void);
11-
void saveRedobuff(void);
12-
void restoreRedobuff(void);
11+
void saveRedobuff(save_redo_T *save_redo);
12+
void restoreRedobuff(save_redo_T *save_redo);
1313
void AppendToRedobuff(char_u *s);
1414
void AppendToRedobuffLit(char_u *str, int len);
1515
void AppendCharToRedobuff(int c);

src/structs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,12 @@ struct buffheader
515515
int bh_space; /* space in bh_curr for appending */
516516
};
517517

518+
typedef struct
519+
{
520+
buffheader_T sr_redobuff;
521+
buffheader_T sr_old_redobuff;
522+
} save_redo_T;
523+
518524
/*
519525
* used for completion on the command line
520526
*/

src/testdir/test_functions.vim

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,3 +756,31 @@ func Test_setbufvar_options()
756756
call win_gotoid(dum1_id)
757757
bwipe!
758758
endfunc
759+
760+
func Test_redo_in_nested_functions()
761+
nnoremap g. :set opfunc=Operator<CR>g@
762+
function Operator( type, ... )
763+
let @x = 'XXX'
764+
execute 'normal! g`[' . (a:type ==# 'line' ? 'V' : 'v') . 'g`]' . '"xp'
765+
endfunction
766+
767+
function! Apply()
768+
5,6normal! .
769+
endfunction
770+
771+
new
772+
call setline(1, repeat(['some "quoted" text', 'more "quoted" text'], 3))
773+
1normal g.i"
774+
call assert_equal('some "XXX" text', getline(1))
775+
3,4normal .
776+
call assert_equal('some "XXX" text', getline(3))
777+
call assert_equal('more "XXX" text', getline(4))
778+
call Apply()
779+
call assert_equal('some "XXX" text', getline(5))
780+
call assert_equal('more "XXX" text', getline(6))
781+
bwipe!
782+
783+
nunmap g.
784+
delfunc Operator
785+
delfunc Apply
786+
endfunc

src/userfunc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,7 @@ call_func(
14081408
else
14091409
{
14101410
int did_save_redo = FALSE;
1411+
save_redo_T save_redo;
14111412

14121413
/*
14131414
* Call the user function.
@@ -1419,7 +1420,7 @@ call_func(
14191420
if (!ins_compl_active())
14201421
#endif
14211422
{
1422-
saveRedobuff();
1423+
saveRedobuff(&save_redo);
14231424
did_save_redo = TRUE;
14241425
}
14251426
++fp->uf_calls;
@@ -1431,7 +1432,7 @@ call_func(
14311432
* now. */
14321433
func_clear_free(fp, FALSE);
14331434
if (did_save_redo)
1434-
restoreRedobuff();
1435+
restoreRedobuff(&save_redo);
14351436
restore_search_patterns();
14361437
error = ERROR_NONE;
14371438
}

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
548,
767769
/**/
768770
547,
769771
/**/

0 commit comments

Comments
 (0)