vim-patch:8.1.0020: cannot tell whether a register is executing or recording

Problem:    Cannot tell whether a register is being used for executing or
            recording.
Solution:   Add reg_executing() and reg_recording(). (Hirohito Higashi,
            closes vim/vim#2745)  Rename the global variables for consistency.  Store
            the register name in reg_executing.
0b6d911e5d
This commit is contained in:
Jan Edmund Lazo 2019-05-26 19:39:38 -04:00
parent fb4d5a1846
commit 21f160746a
13 changed files with 83 additions and 21 deletions

View File

@ -2227,6 +2227,8 @@ range({expr} [, {max} [, {stride}]])
List items from {expr} to {max} List items from {expr} to {max}
readfile({fname} [, {binary} [, {max}]]) readfile({fname} [, {binary} [, {max}]])
List get list of lines from file {fname} List get list of lines from file {fname}
reg_executing() Number get the executing register name
reg_recording() String get the recording register name
reltime([{start} [, {end}]]) List get time value reltime([{start} [, {end}]]) List get time value
reltimefloat({time}) Float turn the time value into a Float reltimefloat({time}) Float turn the time value into a Float
reltimestr({time}) String turn time value into a String reltimestr({time}) String turn time value into a String
@ -6434,6 +6436,15 @@ readfile({fname} [, {binary} [, {max}]])
the result is an empty list. the result is an empty list.
Also see |writefile()|. Also see |writefile()|.
reg_executing() *reg_executing()*
Returns the single letter name of the register being executed.
Returns an empty string when no register is being executed.
See |@|.
reg_recording() *reg_recording()*
Returns the single letter name of the register being recorded.
Returns an empty string string when not recording. See |q|.
reltime([{start} [, {end}]]) *reltime()* reltime([{start} [, {end}]]) *reltime()*
Return an item that represents a time value. The format of Return an item that represents a time value. The format of
the item depends on the system. It can be passed to the item depends on the system. It can be passed to

View File

@ -962,6 +962,8 @@ Various: *various-functions*
getreg() get contents of a register getreg() get contents of a register
getregtype() get type of a register getregtype() get type of a register
setreg() set contents and type of a register setreg() set contents and type of a register
reg_executing() return the name of the register being executed
reg_recording() return the name of the register being recorded
shiftwidth() effective value of 'shiftwidth' shiftwidth() effective value of 'shiftwidth'

View File

@ -7494,7 +7494,7 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
// When recording or for CTRL-O, need to display the new mode. // When recording or for CTRL-O, need to display the new mode.
// Otherwise remove the mode message. // Otherwise remove the mode message.
if (Recording || restart_edit != NUL) { if (reg_recording != 0 || restart_edit != NUL) {
showmode(); showmode();
} else if (p_smd) { } else if (p_smd) {
MSG(""); MSG("");

View File

@ -13556,6 +13556,26 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
fclose(fd); fclose(fd);
} }
static void return_register(int regname, typval_T *rettv)
{
char_u buf[2] = {0, 0};
buf[0] = (char_u)regname;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = vim_strsave(buf);
}
// "reg_executing()" function
static void f_reg_executing(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
return_register(reg_executing, rettv);
}
// "reg_recording()" function
static void f_reg_recording(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
return_register(reg_recording, rettv);
}
/// list2proftime - convert a List to proftime_T /// list2proftime - convert a List to proftime_T
/// ///

View File

@ -236,6 +236,8 @@ return {
pyxeval={args=1}, pyxeval={args=1},
range={args={1, 3}}, range={args={1, 3}},
readfile={args={1, 3}}, readfile={args={1, 3}},
reg_executing={},
reg_recording={},
reltime={args={0, 2}}, reltime={args={0, 2}},
reltimefloat={args=1}, reltimefloat={args=1},
reltimestr={args=1}, reltimestr={args=1},

View File

@ -6677,7 +6677,7 @@ bool trigger_cursorhold(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
if (!did_cursorhold if (!did_cursorhold
&& has_cursorhold() && has_cursorhold()
&& !Recording && reg_recording == 0
&& typebuf.tb_len == 0 && typebuf.tb_len == 0
&& !ins_compl_active() && !ins_compl_active()
) { ) {

View File

@ -1100,7 +1100,7 @@ static void gotchars(char_u *chars, size_t len)
int c; int c;
// remember how many chars were last recorded // remember how many chars were last recorded
if (Recording) { if (reg_recording != 0) {
last_recorded_len += len; last_recorded_len += len;
} }
@ -1109,7 +1109,7 @@ static void gotchars(char_u *chars, size_t len)
c = *s++; c = *s++;
updatescript(c); updatescript(c);
if (Recording) { if (reg_recording != 0) {
char buf[2] = { (char)c, NUL }; char buf[2] = { (char)c, NUL };
add_buff(&recordbuff, buf, 1L); add_buff(&recordbuff, buf, 1L);
} }
@ -1667,7 +1667,7 @@ static int vgetorpeek(int advance)
init_typebuf(); init_typebuf();
start_stuff(); start_stuff();
if (advance && typebuf.tb_maplen == 0) if (advance && typebuf.tb_maplen == 0)
Exec_reg = FALSE; reg_executing = 0;
do { do {
/* /*
* get a character: 1. from the stuffbuffer * get a character: 1. from the stuffbuffer

View File

@ -682,8 +682,8 @@ EXTERN int motion_force INIT(=0); // motion force for pending operator
EXTERN int exmode_active INIT(= 0); // Zero, EXMODE_NORMAL or EXMODE_VIM. EXTERN int exmode_active INIT(= 0); // Zero, EXMODE_NORMAL or EXMODE_VIM.
EXTERN int ex_no_reprint INIT(=false); // No need to print after z or p. EXTERN int ex_no_reprint INIT(=false); // No need to print after z or p.
EXTERN int Recording INIT(= false); // TRUE when recording into a reg. EXTERN int reg_recording INIT(= 0); // register for recording or zero
EXTERN int Exec_reg INIT(= false); // TRUE when executing a register. EXTERN int reg_executing INIT(= 0); // register being executed or zero
EXTERN int no_mapping INIT(= false); // currently no mapping allowed EXTERN int no_mapping INIT(= false); // currently no mapping allowed
EXTERN int no_zero_mapping INIT(= 0); // mapping zero not allowed EXTERN int no_zero_mapping INIT(= 0); // mapping zero not allowed

View File

@ -945,7 +945,6 @@ void wait_return(int redraw)
int oldState; int oldState;
int tmpState; int tmpState;
int had_got_int; int had_got_int;
int save_Recording;
FILE *save_scriptout; FILE *save_scriptout;
if (redraw == true) { if (redraw == true) {
@ -1011,16 +1010,16 @@ void wait_return(int redraw)
// Temporarily disable Recording. If Recording is active, the // Temporarily disable Recording. If Recording is active, the
// character will be recorded later, since it will be added to the // character will be recorded later, since it will be added to the
// typebuf after the loop // typebuf after the loop
save_Recording = Recording; const int save_reg_recording = reg_recording;
save_scriptout = scriptout; save_scriptout = scriptout;
Recording = FALSE; reg_recording = 0;
scriptout = NULL; scriptout = NULL;
c = safe_vgetc(); c = safe_vgetc();
if (had_got_int && !global_busy) { if (had_got_int && !global_busy) {
got_int = false; got_int = false;
} }
no_mapping--; no_mapping--;
Recording = save_Recording; reg_recording = save_reg_recording;
scriptout = save_scriptout; scriptout = save_scriptout;

View File

@ -552,7 +552,10 @@ static bool normal_need_additional_char(NormalState *s)
// needs to be followed by a second char, examples: // needs to be followed by a second char, examples:
// - qc => record using register c // - qc => record using register c
// - q: => open command-line window // - q: => open command-line window
|| (cmdchar == 'q' && !pending_op && !Recording && !Exec_reg) || (cmdchar == 'q'
&& !pending_op
&& reg_recording == 0
&& reg_executing == 0)
// 'a' or 'i' after an operator is a text object, examples: // 'a' or 'i' after an operator is a text object, examples:
// - ciw => change inside word // - ciw => change inside word
// - da( => delete parenthesis and everything inside. // - da( => delete parenthesis and everything inside.
@ -7686,7 +7689,7 @@ static void nv_record(cmdarg_T *cap)
} else { } else {
// (stop) recording into a named register, unless executing a // (stop) recording into a named register, unless executing a
// register. // register.
if (!Exec_reg && do_record(cap->nchar) == FAIL) { if (reg_executing == 0 && do_record(cap->nchar) == FAIL) {
clearopbeep(cap->oap); clearopbeep(cap->oap);
} }
} }

View File

@ -852,13 +852,13 @@ int do_record(int c)
yankreg_T *old_y_previous; yankreg_T *old_y_previous;
int retval; int retval;
if (Recording == false) { if (reg_recording == 0) {
// start recording // start recording
// registers 0-9, a-z and " are allowed // registers 0-9, a-z and " are allowed
if (c < 0 || (!ASCII_ISALNUM(c) && c != '"')) { if (c < 0 || (!ASCII_ISALNUM(c) && c != '"')) {
retval = FAIL; retval = FAIL;
} else { } else {
Recording = c; reg_recording = c;
showmode(); showmode();
regname = c; regname = c;
retval = OK; retval = OK;
@ -869,7 +869,7 @@ int do_record(int c)
* needs to be removed again to put it in a register. exec_reg then * needs to be removed again to put it in a register. exec_reg then
* adds the escaping back later. * adds the escaping back later.
*/ */
Recording = false; reg_recording = 0;
if (ui_has(kUIMessages)) { if (ui_has(kUIMessages)) {
showmode(); showmode();
} else { } else {
@ -1040,7 +1040,7 @@ do_execreg(
== FAIL) == FAIL)
return FAIL; return FAIL;
} }
Exec_reg = TRUE; /* disable the 'q' command */ reg_executing = regname == 0 ? '"' : regname; // disable the 'q' command
} }
return retval; return retval;
} }

View File

@ -6412,7 +6412,7 @@ int showmode(void)
|| restart_edit || restart_edit
|| VIsual_active || VIsual_active
)); ));
if (do_mode || Recording) { if (do_mode || reg_recording != 0) {
/* /*
* Don't show mode right now, when not redrawing or inside a mapping. * Don't show mode right now, when not redrawing or inside a mapping.
* Call char_avail() only when we are going to show something, because * Call char_avail() only when we are going to show something, because
@ -6533,7 +6533,7 @@ int showmode(void)
need_clear = TRUE; need_clear = TRUE;
} }
if (Recording if (reg_recording != 0
&& edit_submode == NULL /* otherwise it gets too long */ && edit_submode == NULL /* otherwise it gets too long */
) { ) {
recording_mode(attr); recording_mode(attr);
@ -6600,7 +6600,7 @@ void clearmode(void)
{ {
msg_ext_ui_flush(); msg_ext_ui_flush();
msg_pos_mode(); msg_pos_mode();
if (Recording) { if (reg_recording != 0) {
recording_mode(HL_ATTR(HLF_CM)); recording_mode(HL_ATTR(HLF_CM));
} }
msg_clr_eos(); msg_clr_eos();
@ -6612,7 +6612,7 @@ static void recording_mode(int attr)
MSG_PUTS_ATTR(_("recording"), attr); MSG_PUTS_ATTR(_("recording"), attr);
if (!shortmess(SHM_RECORDING)) { if (!shortmess(SHM_RECORDING)) {
char_u s[4]; char_u s[4];
vim_snprintf((char *)s, ARRAY_SIZE(s), " @%c", Recording); snprintf((char *)s, ARRAY_SIZE(s), " @%c", reg_recording);
MSG_PUTS_ATTR(s, attr); MSG_PUTS_ATTR(s, attr);
} }
} }

View File

@ -1076,3 +1076,28 @@ func Test_func_sandbox()
call assert_fails('call Fsandbox()', 'E48:') call assert_fails('call Fsandbox()', 'E48:')
delfunc Fsandbox delfunc Fsandbox
endfunc endfunc
" Test for reg_recording() and reg_executing()
func Test_reg_executing_and_recording()
let s:reg_stat = ''
func s:save_reg_stat()
let s:reg_stat = reg_recording() . ':' . reg_executing()
return ''
endfunc
new
call s:save_reg_stat()
call assert_equal(':', s:reg_stat)
call feedkeys("qa\"=s:save_reg_stat()\<CR>pq", 'xt')
call assert_equal('a:', s:reg_stat)
call feedkeys("@a", 'xt')
call assert_equal(':a', s:reg_stat)
call feedkeys("qb@aq", 'xt')
call assert_equal('b:a', s:reg_stat)
call feedkeys("q\"\"=s:save_reg_stat()\<CR>pq", 'xt')
call assert_equal('":', s:reg_stat)
bwipe!
delfunc s:save_reg_stat
unlet s:reg_stat
endfunc