diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2019-05-27 12:01:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-27 12:01:35 +0200 |
commit | 69b3d5acd375e36a06474c6ebd2622cb0c2fcca5 (patch) | |
tree | f34ba1b9e0e138f86666e77280da66f6ca0687e3 | |
parent | fb4d5a184678ab231da20ef559c8e423dfa54d6e (diff) | |
parent | 3c3b7844b95879bcfd86677df4cfac3edb0fb132 (diff) | |
download | rneovim-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.txt | 11 | ||||
-rw-r--r-- | runtime/doc/usr_41.txt | 2 | ||||
-rw-r--r-- | src/nvim/edit.c | 2 | ||||
-rw-r--r-- | src/nvim/eval.c | 19 | ||||
-rw-r--r-- | src/nvim/eval.lua | 2 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 11 | ||||
-rw-r--r-- | src/nvim/fileio.c | 2 | ||||
-rw-r--r-- | src/nvim/getchar.c | 9 | ||||
-rw-r--r-- | src/nvim/globals.h | 4 | ||||
-rw-r--r-- | src/nvim/message.c | 7 | ||||
-rw-r--r-- | src/nvim/normal.c | 46 | ||||
-rw-r--r-- | src/nvim/ops.c | 8 | ||||
-rw-r--r-- | src/nvim/screen.c | 21 | ||||
-rw-r--r-- | src/nvim/testdir/test_functions.vim | 64 |
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 |