mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
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)
This commit is contained in:
@@ -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
|
||||||
@@ -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;
|
||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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 */
|
||||||
@@ -521,28 +517,23 @@ 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;
|
||||||
{
|
|
||||||
save_redobuff = redobuff;
|
|
||||||
redobuff.bh_first.b_next = NULL;
|
redobuff.bh_first.b_next = NULL;
|
||||||
save_old_redobuff = old_redobuff;
|
save_redo->sr_old_redobuff = old_redobuff;
|
||||||
old_redobuff.bh_first.b_next = NULL;
|
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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -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);
|
free_buff(&redobuff);
|
||||||
redobuff = save_redobuff;
|
redobuff = save_redo->sr_redobuff;
|
||||||
free_buff(&old_redobuff);
|
free_buff(&old_redobuff);
|
||||||
old_redobuff = save_old_redobuff;
|
old_redobuff = save_redo->sr_old_redobuff;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
*/
|
*/
|
||||||
|
@@ -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
|
||||||
|
@@ -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.
|
||||||
@@ -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;
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user