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:
zeertzjq
2025-02-28 13:40:26 +08:00
parent 9b25c68db2
commit a3a9f86d4a
6 changed files with 48 additions and 16 deletions

View File

@@ -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;
}

View File

@@ -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',
},

View File

@@ -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.

View File

@@ -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"));