mirror of
https://github.com/neovim/neovim.git
synced 2025-10-05 17:36:29 +00:00
fix(input): fix clearing of reg_executing
vim-patch:8.2.4705
This commit is contained in:
@@ -1248,6 +1248,7 @@ static char_u *do_one_cmd(char_u **cmdlinep, int flags, cstack_T *cstack, LineGe
|
||||
const int save_msg_scroll = msg_scroll;
|
||||
cmdmod_T save_cmdmod;
|
||||
const int save_reg_executing = reg_executing;
|
||||
const bool save_pending_end_reg_executing = pending_end_reg_executing;
|
||||
char_u *cmd;
|
||||
|
||||
memset(&ea, 0, sizeof(ea));
|
||||
@@ -2018,6 +2019,7 @@ doend:
|
||||
undo_cmdmod(&ea, save_msg_scroll);
|
||||
cmdmod = save_cmdmod;
|
||||
reg_executing = save_reg_executing;
|
||||
pending_end_reg_executing = save_pending_end_reg_executing;
|
||||
|
||||
if (ea.did_sandbox) {
|
||||
sandbox--;
|
||||
@@ -8529,6 +8531,7 @@ bool save_current_state(save_state_T *sst)
|
||||
sst->save_finish_op = finish_op;
|
||||
sst->save_opcount = opcount;
|
||||
sst->save_reg_executing = reg_executing;
|
||||
sst->save_pending_end_reg_executing = pending_end_reg_executing;
|
||||
|
||||
msg_scroll = false; // no msg scrolling in Normal mode
|
||||
restart_edit = 0; // don't go to Insert mode
|
||||
@@ -8559,6 +8562,7 @@ void restore_current_state(save_state_T *sst)
|
||||
finish_op = sst->save_finish_op;
|
||||
opcount = sst->save_opcount;
|
||||
reg_executing = sst->save_reg_executing;
|
||||
pending_end_reg_executing = sst->save_pending_end_reg_executing;
|
||||
|
||||
// don't reset msg_didout now
|
||||
msg_didout |= sst->save_msg_didout;
|
||||
|
@@ -29,6 +29,7 @@ typedef struct {
|
||||
bool save_finish_op;
|
||||
long save_opcount;
|
||||
int save_reg_executing;
|
||||
bool save_pending_end_reg_executing;
|
||||
tasave_T tabuf;
|
||||
} save_state_T;
|
||||
|
||||
|
@@ -2060,7 +2060,7 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth)
|
||||
}
|
||||
|
||||
/// unget one character (can only be done once!)
|
||||
/// If the character was stuffed, vgetc() will get it next time it was called.
|
||||
/// If the character was stuffed, vgetc() will get it next time it is called.
|
||||
/// Otherwise vgetc() will only get it when the stuff buffer is empty.
|
||||
void vungetc(int c)
|
||||
{
|
||||
@@ -2072,6 +2072,20 @@ void vungetc(int c)
|
||||
old_KeyStuffed = KeyStuffed;
|
||||
}
|
||||
|
||||
/// When peeking and not getting a character, reg_executing cannot be cleared
|
||||
/// yet, so set a flag to clear it later.
|
||||
static void check_end_reg_executing(bool advance)
|
||||
{
|
||||
if (reg_executing != 0 && (typebuf.tb_maplen == 0 || pending_end_reg_executing)) {
|
||||
if (advance) {
|
||||
reg_executing = 0;
|
||||
pending_end_reg_executing = false;
|
||||
} else {
|
||||
pending_end_reg_executing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a byte:
|
||||
/// 1. from the stuffbuffer
|
||||
/// This is used for abbreviated commands like "D" -> "d$".
|
||||
@@ -2126,9 +2140,7 @@ static int vgetorpeek(bool advance)
|
||||
|
||||
init_typebuf();
|
||||
start_stuff();
|
||||
if (advance && typebuf.tb_maplen == 0) {
|
||||
reg_executing = 0;
|
||||
}
|
||||
check_end_reg_executing(advance);
|
||||
do {
|
||||
// get a character: 1. from the stuffbuffer
|
||||
if (typeahead_char != 0) {
|
||||
@@ -2155,6 +2167,7 @@ static int vgetorpeek(bool advance)
|
||||
// If a mapped key sequence is found we go back to the start to
|
||||
// try re-mapping.
|
||||
for (;;) {
|
||||
check_end_reg_executing(advance);
|
||||
// os_breakcheck() is slow, don't use it too often when
|
||||
// inside a mapping. But call it each time for typed
|
||||
// characters.
|
||||
|
@@ -643,6 +643,8 @@ EXTERN bool ex_no_reprint INIT(=false); // No need to print after z or p.
|
||||
|
||||
EXTERN int reg_recording INIT(= 0); // register for recording or zero
|
||||
EXTERN int reg_executing INIT(= 0); // register being executed or zero
|
||||
// Flag set when peeking a character and found the end of executed register
|
||||
EXTERN bool pending_end_reg_executing INIT(= false);
|
||||
EXTERN int reg_recorded INIT(= 0); // last recorded register or zero
|
||||
|
||||
EXTERN int no_mapping INIT(= false); // currently no mapping allowed
|
||||
|
@@ -690,5 +690,23 @@ func Test_record_in_select_mode()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_end_reg_executing()
|
||||
nnoremap s <Nop>
|
||||
let @a = 's'
|
||||
call feedkeys("@aqaq\<Esc>", 'tx')
|
||||
call assert_equal('', @a)
|
||||
call assert_equal('', getline(1))
|
||||
|
||||
call setline(1, 'aaa')
|
||||
nnoremap s qa
|
||||
let @a = 'fa'
|
||||
call feedkeys("@asq\<Esc>", 'tx')
|
||||
call assert_equal('', @a)
|
||||
call assert_equal('aaa', getline(1))
|
||||
|
||||
nunmap s
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
Reference in New Issue
Block a user