diff options
-rw-r--r-- | runtime/doc/repeat.txt | 17 | ||||
-rw-r--r-- | src/nvim/eval.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_cmds.lua | 2 | ||||
-rw-r--r-- | src/nvim/garray.c | 11 | ||||
-rw-r--r-- | src/nvim/runtime.c | 26 | ||||
-rw-r--r-- | test/old/testdir/test_source.vim | 6 |
6 files changed, 48 insertions, 16 deletions
diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index e65caa72ed..4c95066998 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -192,14 +192,19 @@ Using Vim scripts *using-scripts* For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|. *:so* *:source* *load-vim-script* -:[range]so[urce] [file] Runs |Ex-commands| or Lua code (".lua" files) from - [file]. - If no [file], the current buffer is used and treated - as Lua code if 'filetype' is "lua" or its filename - ends with ".lua". +:so[urce] {file} Runs |Ex-commands| or Lua code (".lua" files) from + {file}. Triggers the |SourcePre| autocommand. + +:[range]so[urce] Read Ex commands or Lua code from the [range] of lines + in the current buffer. The buffer is treated as Lua + code if 'filetype' is "lua" or its filename ends with + ".lua". When sourcing commands or Lua code from the + current buffer, the same script-ID |<SID>| is used + even if the buffer is sourced multiple times. + *:source!* -:[range]so[urce]! {file} +:so[urce]! {file} Runs |Normal-mode| commands from {file}. When used after |:global|, |:argdo|, |:windo|, |:bufdo|, in a loop or when another command follows the display diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 2b6fefbf82..ee5dd25e93 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -759,7 +759,7 @@ void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, bool skip) return; } - if (getline_equal(eap->ea_getline, eap->cookie, getsourceline)) { + if (sourcing_a_script(eap)) { evalarg->eval_getline = eap->ea_getline; evalarg->eval_cookie = eap->cookie; } diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index d118c808d3..d68d5a9afa 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -2533,7 +2533,7 @@ M.cmds = { }, { command = 'source', - flags = bit.bor(RANGE, DFLALL, WHOLEFOLD, BANG, FILE1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + flags = bit.bor(RANGE, DFLALL, BANG, FILE1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type = 'ADDR_LINES', func = 'ex_source', }, diff --git a/src/nvim/garray.c b/src/nvim/garray.c index a8d15a1fa8..b3dce90b11 100644 --- a/src/nvim/garray.c +++ b/src/nvim/garray.c @@ -198,12 +198,13 @@ void ga_concat(garray_T *gap, const char *restrict s) void ga_concat_len(garray_T *const gap, const char *restrict s, const size_t len) FUNC_ATTR_NONNULL_ALL { - if (len) { - ga_grow(gap, (int)len); - char *data = gap->ga_data; - memcpy(data + gap->ga_len, s, len); - gap->ga_len += (int)len; + if (len == 0) { + return; } + ga_grow(gap, (int)len); + char *data = gap->ga_data; + memcpy(data + gap->ga_len, s, len); + gap->ga_len += (int)len; } /// Append one byte to a growarray which contains bytes. diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 861a44cc05..f02c8660f1 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -106,6 +106,7 @@ garray_T script_items = { 0, 0, sizeof(scriptitem_T *), 20, NULL }; /// The names of packages that once were loaded are remembered. static garray_T ga_loaded = { 0, 0, sizeof(char *), 4, NULL }; +/// last used sequence number for sourcing scripts (current_sctx.sc_seq) static int last_current_SID_seq = 0; /// Initialize the execution stack. @@ -1825,8 +1826,20 @@ freeall: static void cmd_source(char *fname, exarg_T *eap) { + if (*fname != NUL && eap != NULL && eap->addr_count > 0) { + // if a filename is specified to :source, then a range is not allowed + emsg(_(e_norange)); + return; + } + if (eap != NULL && *fname == NUL) { - cmd_source_buffer(eap, false); + if (eap->forceit) { + // a file name is needed to source normal mode commands + emsg(_(e_argreq)); + } else { + // source ex commands from the current buffer + cmd_source_buffer(eap, false); + } } else if (eap != NULL && eap->forceit) { // ":source!": read Normal mode commands // Need to execute the commands directly. This is required at least @@ -2784,11 +2797,18 @@ retry: return NULL; } +/// Returns true if sourcing a script either from a file or a buffer. +/// Otherwise returns false. +int sourcing_a_script(exarg_T *eap) +{ + return getline_equal(eap->ea_getline, eap->cookie, getsourceline); +} + /// ":scriptencoding": Set encoding conversion for a sourced script. /// Without the multi-byte feature it's simply ignored. void ex_scriptencoding(exarg_T *eap) { - if (!getline_equal(eap->ea_getline, eap->cookie, getsourceline)) { + if (!sourcing_a_script(eap)) { emsg(_("E167: :scriptencoding used outside of a sourced file")); return; } @@ -2807,7 +2827,7 @@ void ex_scriptencoding(exarg_T *eap) /// ":finish": Mark a sourced file as finished. void ex_finish(exarg_T *eap) { - if (getline_equal(eap->ea_getline, eap->cookie, getsourceline)) { + if (sourcing_a_script(eap)) { do_finish(eap, false); } else { emsg(_("E168: :finish used outside of a sourced file")); diff --git a/test/old/testdir/test_source.vim b/test/old/testdir/test_source.vim index 01c08b183c..130d859224 100644 --- a/test/old/testdir/test_source.vim +++ b/test/old/testdir/test_source.vim @@ -92,6 +92,12 @@ func Test_source_error() call assert_fails('scriptencoding utf-8', 'E167:') call assert_fails('finish', 'E168:') " call assert_fails('scriptversion 2', 'E984:') + call assert_fails('source!', 'E471:') + new + call setline(1, ['', '', '', '']) + call assert_fails('1,3source Xscript.vim', 'E481:') + call assert_fails('1,3source! Xscript.vim', 'E481:') + bw! endfunc " Test for sourcing a script recursively |