mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
vim-patch:8.2.4594: need to write script to a file to be able to source them
Problem: Need to write script to a file to be able to source them.
Solution: Make ":source" use lines from the current buffer. (Yegappan
Lakshmanan et al., closes vim/vim#9967)
36a5b6867b
Most code and test changes are reverted or modified again in patch
8.2.4603, so only port parts that are untouched in patch 8.2.4603.
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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',
|
||||
},
|
||||
|
@@ -198,13 +198,14 @@ 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) {
|
||||
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.
|
||||
///
|
||||
|
@@ -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) {
|
||||
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"));
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user