aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-05-27 12:01:35 +0200
committerGitHub <noreply@github.com>2019-05-27 12:01:35 +0200
commit69b3d5acd375e36a06474c6ebd2622cb0c2fcca5 (patch)
treef34ba1b9e0e138f86666e77280da66f6ca0687e3
parentfb4d5a184678ab231da20ef559c8e423dfa54d6e (diff)
parent3c3b7844b95879bcfd86677df4cfac3edb0fb132 (diff)
downloadrneovim-69b3d5acd375e36a06474c6ebd2622cb0c2fcca5.tar.gz
rneovim-69b3d5acd375e36a06474c6ebd2622cb0c2fcca5.tar.bz2
rneovim-69b3d5acd375e36a06474c6ebd2622cb0c2fcca5.zip
Merge #10068 from janlazo/vim-8.1.0020
vim-patch:8.1.{20,995,1077}
-rw-r--r--runtime/doc/eval.txt11
-rw-r--r--runtime/doc/usr_41.txt2
-rw-r--r--src/nvim/edit.c2
-rw-r--r--src/nvim/eval.c19
-rw-r--r--src/nvim/eval.lua2
-rw-r--r--src/nvim/ex_docmd.c11
-rw-r--r--src/nvim/fileio.c2
-rw-r--r--src/nvim/getchar.c9
-rw-r--r--src/nvim/globals.h4
-rw-r--r--src/nvim/message.c7
-rw-r--r--src/nvim/normal.c46
-rw-r--r--src/nvim/ops.c8
-rw-r--r--src/nvim/screen.c21
-rw-r--r--src/nvim/testdir/test_functions.vim64
14 files changed, 153 insertions, 55 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index cd5632e70c..c96f51772d 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2227,6 +2227,8 @@ range({expr} [, {max} [, {stride}]])
List items from {expr} to {max}
readfile({fname} [, {binary} [, {max}]])
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
reltimefloat({time}) Float turn the time value into a Float
reltimestr({time}) String turn time value into a String
@@ -6434,6 +6436,15 @@ readfile({fname} [, {binary} [, {max}]])
the result is an empty list.
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()*
Return an item that represents a time value. The format of
the item depends on the system. It can be passed to
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index b8fd6cdf7b..def781c109 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -962,6 +962,8 @@ Various: *various-functions*
getreg() get contents of a register
getregtype() get 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'
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index bfd63aab7a..5ac95b64e7 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -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.
// Otherwise remove the mode message.
- if (Recording || restart_edit != NUL) {
+ if (reg_recording != 0 || restart_edit != NUL) {
showmode();
} else if (p_smd) {
MSG("");
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 1d15e04218..deaed17926 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -13556,6 +13556,25 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
fclose(fd);
}
+static void return_register(int regname, typval_T *rettv)
+{
+ char_u buf[2] = { regname, 0 };
+
+ 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
///
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index aff1ff2a74..f36a7ea6c0 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -236,6 +236,8 @@ return {
pyxeval={args=1},
range={args={1, 3}},
readfile={args={1, 3}},
+ reg_executing={},
+ reg_recording={},
reltime={args={0, 2}},
reltimefloat={args=1},
reltimestr={args=1},
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 527120ae9f..9e056d449b 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -1233,7 +1233,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
int did_esilent = 0;
int did_sandbox = FALSE;
cmdmod_T save_cmdmod;
- int ni; /* set when Not Implemented */
+ const int save_reg_executing = reg_executing;
char_u *cmd;
int address_count = 1;
@@ -1762,10 +1762,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
goto doend;
}
- ni = (!IS_USER_CMDIDX(ea.cmdidx)
- && (cmdnames[ea.cmdidx].cmd_func == ex_ni
- || cmdnames[ea.cmdidx].cmd_func == ex_script_ni
- ));
+ // set when Not Implemented
+ const int ni = !IS_USER_CMDIDX(ea.cmdidx)
+ && (cmdnames[ea.cmdidx].cmd_func == ex_ni
+ || cmdnames[ea.cmdidx].cmd_func == ex_script_ni);
// Forced commands.
@@ -2298,6 +2298,7 @@ doend:
}
cmdmod = save_cmdmod;
+ reg_executing = save_reg_executing;
if (save_msg_silent != -1) {
/* messages could be enabled for a serious error, need to check if the
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index f97ae8778d..e2b77d9605 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -6677,7 +6677,7 @@ bool trigger_cursorhold(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
if (!did_cursorhold
&& has_cursorhold()
- && !Recording
+ && reg_recording == 0
&& typebuf.tb_len == 0
&& !ins_compl_active()
) {
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index ec14803a2e..ef522242c6 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -1100,7 +1100,7 @@ static void gotchars(char_u *chars, size_t len)
int c;
// remember how many chars were last recorded
- if (Recording) {
+ if (reg_recording != 0) {
last_recorded_len += len;
}
@@ -1109,7 +1109,7 @@ static void gotchars(char_u *chars, size_t len)
c = *s++;
updatescript(c);
- if (Recording) {
+ if (reg_recording != 0) {
char buf[2] = { (char)c, NUL };
add_buff(&recordbuff, buf, 1L);
}
@@ -1666,8 +1666,9 @@ static int vgetorpeek(int advance)
init_typebuf();
start_stuff();
- if (advance && typebuf.tb_maplen == 0)
- Exec_reg = FALSE;
+ if (advance && typebuf.tb_maplen == 0) {
+ reg_executing = 0;
+ }
do {
/*
* get a character: 1. from the stuffbuffer
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 1a493317e1..78409267a4 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -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 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 Exec_reg INIT(= false); // TRUE when executing a register.
+EXTERN int reg_recording INIT(= 0); // register for recording or zero
+EXTERN int reg_executing INIT(= 0); // register being executed or zero
EXTERN int no_mapping INIT(= false); // currently no mapping allowed
EXTERN int no_zero_mapping INIT(= 0); // mapping zero not allowed
diff --git a/src/nvim/message.c b/src/nvim/message.c
index c5b9187117..7498091ade 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -945,7 +945,6 @@ void wait_return(int redraw)
int oldState;
int tmpState;
int had_got_int;
- int save_Recording;
FILE *save_scriptout;
if (redraw == true) {
@@ -1011,16 +1010,16 @@ void wait_return(int redraw)
// Temporarily disable Recording. If Recording is active, the
// character will be recorded later, since it will be added to the
// typebuf after the loop
- save_Recording = Recording;
+ const int save_reg_recording = reg_recording;
save_scriptout = scriptout;
- Recording = FALSE;
+ reg_recording = 0;
scriptout = NULL;
c = safe_vgetc();
if (had_got_int && !global_busy) {
got_int = false;
}
no_mapping--;
- Recording = save_Recording;
+ reg_recording = save_reg_recording;
scriptout = save_scriptout;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index d6e78d9ce4..db2da6a807 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -541,27 +541,29 @@ static bool normal_need_additional_char(NormalState *s)
int flags = nv_cmds[s->idx].cmd_flags;
bool pending_op = s->oa.op_type != OP_NOP;
int cmdchar = s->ca.cmdchar;
- return
- // without NV_NCH we never need to check for an additional char
- flags & NV_NCH && (
- // NV_NCH_NOP is set and no operator is pending, get a second char
- ((flags & NV_NCH_NOP) == NV_NCH_NOP && !pending_op)
- // NV_NCH_ALW is set, always get a second char
- || (flags & NV_NCH_ALW) == NV_NCH_ALW
- // 'q' without a pending operator, recording or executing a register,
- // needs to be followed by a second char, examples:
- // - qc => record using register c
- // - q: => open command-line window
- || (cmdchar == 'q' && !pending_op && !Recording && !Exec_reg)
- // 'a' or 'i' after an operator is a text object, examples:
- // - ciw => change inside word
- // - da( => delete parenthesis and everything inside.
- // Also, don't do anything when these keys are received in visual mode
- // so just get another char.
- //
- // TODO(tarruda): Visual state needs to be refactored into a
- // separate state that "inherits" from normal state.
- || ((cmdchar == 'a' || cmdchar == 'i') && (pending_op || VIsual_active)));
+ // without NV_NCH we never need to check for an additional char
+ return flags & NV_NCH && (
+ // NV_NCH_NOP is set and no operator is pending, get a second char
+ ((flags & NV_NCH_NOP) == NV_NCH_NOP && !pending_op)
+ // NV_NCH_ALW is set, always get a second char
+ || (flags & NV_NCH_ALW) == NV_NCH_ALW
+ // 'q' without a pending operator, recording or executing a register,
+ // needs to be followed by a second char, examples:
+ // - qc => record using register c
+ // - q: => open command-line window
+ || (cmdchar == 'q'
+ && !pending_op
+ && reg_recording == 0
+ && reg_executing == 0)
+ // 'a' or 'i' after an operator is a text object, examples:
+ // - ciw => change inside word
+ // - da( => delete parenthesis and everything inside.
+ // Also, don't do anything when these keys are received in visual mode
+ // so just get another char.
+ //
+ // TODO(tarruda): Visual state needs to be refactored into a
+ // separate state that "inherits" from normal state.
+ || ((cmdchar == 'a' || cmdchar == 'i') && (pending_op || VIsual_active)));
}
static bool normal_need_redraw_mode_message(NormalState *s)
@@ -7686,7 +7688,7 @@ static void nv_record(cmdarg_T *cap)
} else {
// (stop) recording into a named register, unless executing a
// register.
- if (!Exec_reg && do_record(cap->nchar) == FAIL) {
+ if (reg_executing == 0 && do_record(cap->nchar) == FAIL) {
clearopbeep(cap->oap);
}
}
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 1c5d4e98a7..9b68b713ad 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -852,13 +852,13 @@ int do_record(int c)
yankreg_T *old_y_previous;
int retval;
- if (Recording == false) {
+ if (reg_recording == 0) {
// start recording
// registers 0-9, a-z and " are allowed
if (c < 0 || (!ASCII_ISALNUM(c) && c != '"')) {
retval = FAIL;
} else {
- Recording = c;
+ reg_recording = c;
showmode();
regname = c;
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
* adds the escaping back later.
*/
- Recording = false;
+ reg_recording = 0;
if (ui_has(kUIMessages)) {
showmode();
} else {
@@ -1040,7 +1040,7 @@ do_execreg(
== FAIL)
return FAIL;
}
- Exec_reg = TRUE; /* disable the 'q' command */
+ reg_executing = regname == 0 ? '"' : regname; // disable the 'q' command
}
return retval;
}
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index b0109b0824..fe9fba7af6 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -6410,14 +6410,11 @@ int showmode(void)
&& ((State & TERM_FOCUS)
|| (State & INSERT)
|| restart_edit
- || VIsual_active
- ));
- if (do_mode || Recording) {
- /*
- * 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
- * it takes a bit of time.
- */
+ || VIsual_active));
+ if (do_mode || reg_recording != 0) {
+ // 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
+ // it takes a bit of time.
if (!redrawing() || (char_avail() && !KeyTyped) || msg_silent != 0) {
redraw_cmdline = TRUE; /* show mode later */
return 0;
@@ -6533,8 +6530,8 @@ int showmode(void)
need_clear = TRUE;
}
- if (Recording
- && edit_submode == NULL /* otherwise it gets too long */
+ if (reg_recording != 0
+ && edit_submode == NULL // otherwise it gets too long
) {
recording_mode(attr);
need_clear = true;
@@ -6600,7 +6597,7 @@ void clearmode(void)
{
msg_ext_ui_flush();
msg_pos_mode();
- if (Recording) {
+ if (reg_recording != 0) {
recording_mode(HL_ATTR(HLF_CM));
}
msg_clr_eos();
@@ -6612,7 +6609,7 @@ static void recording_mode(int attr)
MSG_PUTS_ATTR(_("recording"), attr);
if (!shortmess(SHM_RECORDING)) {
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);
}
}
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 46c2d0f4cd..ed9c70403e 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -1076,3 +1076,67 @@ func Test_func_sandbox()
call assert_fails('call Fsandbox()', 'E48:')
delfunc Fsandbox
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)
+
+ " :normal command saves and restores reg_executing
+ let s:reg_stat = ''
+
+ " getchar() command saves and restores reg_executing
+ map W :call TestFunc()<CR>
+ let @q = "W"
+ let g:typed = ''
+ let g:regs = []
+ func TestFunc() abort
+ let g:regs += [reg_executing()]
+ let g:typed = getchar(0)
+ let g:regs += [reg_executing()]
+ endfunc
+ call feedkeys("@qy", 'xt')
+ call assert_equal(char2nr("y"), g:typed)
+ call assert_equal(['q', 'q'], g:regs)
+ delfunc TestFunc
+ unmap W
+ unlet g:typed
+ unlet g:regs
+
+ " input() command saves and restores reg_executing
+ map W :call TestFunc()<CR>
+ let @q = "W"
+ let g:typed = ''
+ let g:regs = []
+ func TestFunc() abort
+ let g:regs += [reg_executing()]
+ let g:typed = input('?')
+ let g:regs += [reg_executing()]
+ endfunc
+ call feedkeys("@qy\<CR>", 'xt')
+ call assert_equal("y", g:typed)
+ call assert_equal(['q', 'q'], g:regs)
+ delfunc TestFunc
+ unmap W
+ unlet g:typed
+ unlet g:regs
+
+ bwipe!
+ delfunc s:save_reg_stat
+ unlet s:reg_stat
+endfunc