Patch 8.2.4594
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 #9967)
Files: runtime/doc/repeat.txt, runtime/doc/todo.txt, src/alloc.c,
src/digraph.c, src/eval.c, src/ex_cmds.h, src/scriptfile.c,
src/proto/scriptfile.pro, src/vim9script.c,
src/testdir/test_source.vim
*** ../vim-8.2.4593/runtime/doc/repeat.txt 2022-01-18 16:25:58.618309943
+0000
--- runtime/doc/repeat.txt 2022-03-19 12:36:45.098120789 +0000
***************
*** 188,193 ****
--- 197,208 ----
:so[urce] {file} Read Ex commands from {file}. These are commands that
start with a ":".
Triggers the |SourcePre| autocommand.
+
+ :[range]so[urce] Read Ex commands from the [range] of lines in the
+ current buffer. When sourcing commands from the
+ current buffer, the same script-ID |<SID>| is used
+ even if the buffer is sourced multiple times.
+
*:source!*
:so[urce]! {file} Read Vim commands from {file}. These are commands
that are executed from Normal mode, like you type
*** ../vim-8.2.4593/runtime/doc/todo.txt 2021-02-13 17:24:19.322119004
+0000
--- runtime/doc/todo.txt 2022-03-19 12:36:45.098120789 +0000
***************
*** 4336,4347 ****
restore option values. Especially useful for new options. Problem: how
to avoid a performance penalty (esp. for string options)?
- range for ":exec", pass it on to the executed command. (Webb)
- 8 ":{range}source": source the lines from the current file.
- You can already yank lines and use :@" to execute them.
- Most of do_source() would not be used, need a new function.
- It's easy when not doing breakpoints or profiling.
- Requires copying the lines into a list and then creating a function to
- execute lines from the list. Similar to getnextac().
7 ":include" command: just like ":source" but doesn't start a new scriptID?
Will be tricky for the list of script names.
8 Have a look at VSEL. Would it be useful to include? (Bigham)
--- 4280,4285 ----
*** ../vim-8.2.4593/src/alloc.c 2022-01-29 15:19:19.542172491 +0000
--- src/alloc.c 2022-03-19 12:36:45.098120789 +0000
***************
*** 845,851 ****
void
ga_concat_len(garray_T *gap, char_u *s, size_t len)
{
! if (s == NULL || *s == NUL)
return;
if (ga_grow(gap, (int)len) == OK)
{
--- 845,851 ----
void
ga_concat_len(garray_T *gap, char_u *s, size_t len)
{
! if (s == NULL || *s == NUL || len == 0)
return;
if (ga_grow(gap, (int)len) == OK)
{
*** ../vim-8.2.4593/src/digraph.c 2022-01-31 14:59:33.510943820 +0000
--- src/digraph.c 2022-03-19 12:36:45.098120789 +0000
***************
*** 2507,2513 ****
int i;
char_u *save_cpo = p_cpo;
! if (!getline_equal(eap->getline, eap->cookie, getsourceline))
{
emsg(_(e_using_loadkeymap_not_in_sourced_file));
return;
--- 2507,2513 ----
int i;
char_u *save_cpo = p_cpo;
! if (!sourcing_a_script(eap))
{
emsg(_(e_using_loadkeymap_not_in_sourced_file));
return;
*** ../vim-8.2.4593/src/eval.c 2022-03-18 19:44:44.939089425 +0000
--- src/eval.c 2022-03-19 12:36:45.098120789 +0000
***************
*** 140,146 ****
if (eap != NULL)
{
evalarg->eval_cstack = eap->cstack;
! if (getline_equal(eap->getline, eap->cookie, getsourceline))
{
evalarg->eval_getline = eap->getline;
evalarg->eval_cookie = eap->cookie;
--- 140,146 ----
if (eap != NULL)
{
evalarg->eval_cstack = eap->cstack;
! if (sourcing_a_script(eap))
{
evalarg->eval_getline = eap->getline;
evalarg->eval_cookie = eap->cookie;
*** ../vim-8.2.4593/src/ex_cmds.h 2022-03-06 14:51:19.058997629 +0000
--- src/ex_cmds.h 2022-03-19 12:36:45.098120789 +0000
***************
*** 1428,1435 ****
EX_RANGE|EX_ZEROR|EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN|EX_LOCK_OK,
ADDR_OTHER),
EXCMD(CMD_source, "source", ex_source,
! EX_BANG|EX_FILE1|EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
! ADDR_NONE),
EXCMD(CMD_sort, "sort", ex_sort,
EX_RANGE|EX_DFLALL|EX_WHOLEFOLD|EX_BANG|EX_EXTRA|EX_NOTRLCOM|EX_MODIFY,
ADDR_LINES),
--- 1428,1435 ----
EX_RANGE|EX_ZEROR|EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN|EX_LOCK_OK,
ADDR_OTHER),
EXCMD(CMD_source, "source", ex_source,
!
EX_RANGE|EX_DFLALL|EX_BANG|EX_FILE1|EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
! ADDR_LINES),
EXCMD(CMD_sort, "sort", ex_sort,
EX_RANGE|EX_DFLALL|EX_WHOLEFOLD|EX_BANG|EX_EXTRA|EX_NOTRLCOM|EX_MODIFY,
ADDR_LINES),
*** ../vim-8.2.4593/src/scriptfile.c 2022-02-12 13:30:12.760432016 +0000
--- src/scriptfile.c 2022-03-19 12:51:07.033932219 +0000
***************
*** 18,23 ****
--- 18,28 ----
static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
#endif
+ // last used sequence number for sourcing scripts (current_sctx.sc_seq)
+ #ifdef FEAT_EVAL
+ static int last_current_SID_seq = 0;
+ #endif
+
/*
* Initialize the execution stack.
*/
***************
*** 1074,1085 ****
return OK;
}
static void
cmd_source(char_u *fname, exarg_T *eap)
{
! if (*fname == NUL)
! emsg(_(e_argument_required));
else if (eap != NULL && eap->forceit)
// ":source!": read Normal mode commands
// Need to execute the commands directly. This is required at least
--- 1079,1348 ----
return OK;
}
+ /*
+ * Cookie used to source Ex commands from a buffer.
+ */
+ typedef struct
+ {
+ garray_T lines_to_source;
+ int lnum;
+ linenr_T sourcing_lnum;
+ } bufline_cookie_T;
+
+ /*
+ * Concatenate a Vim script line if it starts with a line continuation into a
+ * growarray (excluding the continuation chars and leading whitespace).
+ * Growsize of the growarray may be changed to speed up concatenations!
+ *
+ * Returns TRUE if this line did begin with a continuation (the next line
+ * should also be considered, if it exists); FALSE otherwise.
+ */
+ static int
+ concat_continued_line(
+ garray_T *ga,
+ int init_growsize,
+ char_u *nextline,
+ int options)
+ {
+ int comment_char = in_vim9script() ? '#' : '"';
+ char_u *p = skipwhite(nextline);
+ int contline;
+ int do_vim9_all = in_vim9script()
+ && options == GETLINE_CONCAT_ALL;
+ int do_bar_cont = do_vim9_all
+ || options == GETLINE_CONCAT_CONTBAR;
+
+ if (*p == NUL)
+ return FALSE;
+
+ // Concatenate the next line when it starts with a backslash.
+ /* Also check for a comment in between continuation lines: "\ */
+ // Also check for a Vim9 comment, empty line, line starting with '|',
+ // but not "||".
+ if ((p[0] == comment_char && p[1] == '\\' && p[2] == ' ')
+ || (do_vim9_all && (*p == NUL
+ || vim9_comment_start(p))))
+ return TRUE;
+
+ contline = (*p == '\\' || (do_bar_cont && p[0] == '|' && p[1] != '|'));
+ if (!contline)
+ return FALSE;
+
+ // Adjust the growsize to the current length to speed up concatenating
many
+ // lines.
+ if (ga->ga_len > init_growsize)
+ ga->ga_growsize = ga->ga_len > 8000 ? 8000 : ga->ga_len;
+ if (*p == '\\')
+ ga_concat(ga, (char_u *)p + 1);
+ else if (*p == '|')
+ {
+ ga_concat(ga, (char_u *)" ");
+ ga_concat(ga, p);
+ }
+
+ return TRUE;
+ }
+
+ /*
+ * Get one full line from a sourced string (in-memory, no file).
+ * Called by do_cmdline() when it's called from source_using_linegetter().
+ *
+ * Returns a pointer to allocated line, or NULL for end-of-file.
+ */
+ static char_u *
+ source_getbufline(
+ int c UNUSED,
+ void *cookie,
+ int indent UNUSED,
+ getline_opt_T opts)
+ {
+ bufline_cookie_T *p = cookie;
+ char_u *line;
+ garray_T ga;
+
+ SOURCING_LNUM = p->sourcing_lnum + 1;
+
+ if (p->lnum >= p->lines_to_source.ga_len)
+ return NULL;
+ line = ((char_u **)p->lines_to_source.ga_data)[p->lnum];
+
+ ga_init2(&ga, sizeof(char_u), 400);
+ ga_concat(&ga, (char_u *)line);
+ p->lnum++;
+
+ if ((opts != GETLINE_NONE) && vim_strchr(p_cpo, CPO_CONCAT) == NULL)
+ {
+ while (p->lnum < p->lines_to_source.ga_len)
+ {
+ line = ((char_u **)p->lines_to_source.ga_data)[p->lnum];
+ if (!concat_continued_line(&ga, 400, line, opts))
+ break;
+ p->sourcing_lnum++;
+ p->lnum++;
+ }
+ }
+ ga_append(&ga, NUL);
+ p->sourcing_lnum++;
+
+ return ga.ga_data;
+ }
+
+ /*
+ * Source Ex commands from the lines in 'cookie'.
+ */
+ static int
+ do_sourcebuffer(
+ void *cookie,
+ char_u *scriptname)
+ {
+ char_u *save_sourcing_name = SOURCING_NAME;
+ linenr_T save_sourcing_lnum = SOURCING_LNUM;
+ char_u sourcing_name_buf[256];
+ sctx_T save_current_sctx;
+ #ifdef FEAT_EVAL
+ int sid;
+ funccal_entry_T funccalp_entry;
+ int save_estack_compiling = estack_compiling;
+ scriptitem_T *si = NULL;
+ #endif
+ int save_sticky_cmdmod_flags = sticky_cmdmod_flags;
+ int retval = FAIL;
+ ESTACK_CHECK_DECLARATION
+
+ if (save_sourcing_name == NULL)
+ SOURCING_NAME = (char_u *)scriptname;
+ else
+ {
+ vim_snprintf((char *)sourcing_name_buf, sizeof(sourcing_name_buf),
+ "%s called at %s:%ld", scriptname, save_sourcing_name,
+ save_sourcing_lnum);
+ SOURCING_NAME = sourcing_name_buf;
+ }
+ SOURCING_LNUM = 0;
+
+ // Keep the sourcing name/lnum, for recursive calls.
+ estack_push(ETYPE_SCRIPT, scriptname, 0);
+ ESTACK_CHECK_SETUP
+
+ // "legacy" does not apply to commands in the script
+ sticky_cmdmod_flags = 0;
+
+ save_current_sctx = current_sctx;
+ current_sctx.sc_version = 1; // default script version
+ #ifdef FEAT_EVAL
+ estack_compiling = FALSE;
+ // Always use a new sequence number.
+ current_sctx.sc_seq = ++last_current_SID_seq;
+ current_sctx.sc_lnum = save_sourcing_lnum;
+ save_funccal(&funccalp_entry);
+
+ sid = find_script_by_name(scriptname);
+ if (sid < 0)
+ {
+ int error = OK;
+
+ // First time sourcing this buffer, create a new script item.
+
+ sid = get_new_scriptitem(&error);
+ if (error == FAIL)
+ goto theend;
+ current_sctx.sc_sid = sid;
+ si = SCRIPT_ITEM(current_sctx.sc_sid);
+ si->sn_name = vim_strsave(scriptname);
+ si->sn_state = SN_STATE_NEW;
+ }
+ else
+ {
+ // the buffer was sourced previously, reuse the script ID.
+ current_sctx.sc_sid = sid;
+ si = SCRIPT_ITEM(current_sctx.sc_sid);
+ si->sn_state = SN_STATE_RELOAD;
+ }
+ #endif
+
+ retval = do_cmdline(NULL, source_getbufline, cookie,
+ DOCMD_VERBOSE | DOCMD_NOWAIT | DOCMD_REPEAT);
+
+ if (got_int)
+ emsg(_(e_interrupted));
+
+ #ifdef FEAT_EVAL
+ theend:
+ #endif
+ ESTACK_CHECK_NOW
+ estack_pop();
+ current_sctx = save_current_sctx;
+ SOURCING_LNUM = save_sourcing_lnum;
+ SOURCING_NAME = save_sourcing_name;
+ sticky_cmdmod_flags = save_sticky_cmdmod_flags;
+ #ifdef FEAT_EVAL
+ restore_funccal();
+ estack_compiling = save_estack_compiling;
+ #endif
+
+ return retval;
+ }
+
+ /*
+ * :source Ex commands from the current buffer
+ */
+ static void
+ cmd_source_buffer(exarg_T *eap)
+ {
+ char_u *line = NULL;
+ linenr_T curr_lnum;
+ bufline_cookie_T cp;
+ char_u sname[32];
+
+ if (curbuf == NULL)
+ return;
+
+ // Use ":source buffer=<num>" as the script name
+ vim_snprintf((char *)sname, sizeof(sname), ":source buffer=%d",
+ curbuf->b_fnum);
+
+ ga_init2(&cp.lines_to_source, sizeof(char_u *), 100);
+
+ // Copy the lines from the buffer into a grow array
+ for (curr_lnum = eap->line1; curr_lnum <= eap->line2; curr_lnum++)
+ {
+ line = vim_strsave(ml_get(curr_lnum));
+ if (line == NULL)
+ goto errret;
+ if (ga_add_string(&cp.lines_to_source, line) == FAIL)
+ goto errret;
+ line = NULL;
+ }
+ cp.sourcing_lnum = 0;
+ cp.lnum = 0;
+
+ // Execute the Ex commands
+ do_sourcebuffer((void *)&cp, (char_u *)sname);
+
+ errret:
+ vim_free(line);
+ ga_clear_strings(&cp.lines_to_source);
+ }
+
static void
cmd_source(char_u *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_no_range_allowed));
! return;
! }
+ if (eap != NULL && *fname == NUL)
+ {
+ if (eap->forceit)
+ // a file name is needed to source normal mode commands
+ emsg(_(e_argument_required));
+ else
+ // source ex commands from the current buffer
+ cmd_source_buffer(eap);
+ }
else if (eap != NULL && eap->forceit)
// ":source!": read Normal mode commands
// Need to execute the commands directly. This is required at least
***************
*** 1240,1246 ****
int retval = FAIL;
sctx_T save_current_sctx;
#ifdef FEAT_EVAL
- static int last_current_SID_seq = 0;
funccal_entry_T funccalp_entry;
int save_debug_break_level = debug_break_level;
int sid;
--- 1503,1508 ----
***************
*** 2016,2021 ****
--- 2278,2294 ----
}
/*
+ * 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->getline, eap->cookie, getsourceline)
+ || getline_equal(eap->getline, eap->cookie, source_getbufline));
+ }
+
+ /*
* ":scriptencoding": Set encoding conversion for a sourced script.
*/
void
***************
*** 2024,2030 ****
source_cookie_T *sp;
char_u *name;
! if (!getline_equal(eap->getline, eap->cookie, getsourceline))
{
emsg(_(e_scriptencoding_used_outside_of_sourced_file));
return;
--- 2297,2303 ----
source_cookie_T *sp;
char_u *name;
! if (!sourcing_a_script(eap))
{
emsg(_(e_scriptencoding_used_outside_of_sourced_file));
return;
***************
*** 2055,2061 ****
{
int nr;
! if (!getline_equal(eap->getline, eap->cookie, getsourceline))
{
emsg(_(e_scriptversion_used_outside_of_sourced_file));
return;
--- 2328,2334 ----
{
int nr;
! if (!sourcing_a_script(eap))
{
emsg(_(e_scriptversion_used_outside_of_sourced_file));
return;
***************
*** 2087,2093 ****
void
ex_finish(exarg_T *eap)
{
! if (getline_equal(eap->getline, eap->cookie, getsourceline))
do_finish(eap, FALSE);
else
emsg(_(e_finish_used_outside_of_sourced_file));
--- 2360,2366 ----
void
ex_finish(exarg_T *eap)
{
! if (sourcing_a_script(eap))
do_finish(eap, FALSE);
else
emsg(_(e_finish_used_outside_of_sourced_file));
*** ../vim-8.2.4593/src/proto/scriptfile.pro 2022-01-10 18:06:58.682381797
+0000
--- src/proto/scriptfile.pro 2022-03-19 12:36:45.102120794 +0000
***************
*** 42,45 ****
--- 42,46 ----
char_u *may_prefix_autoload(char_u *name);
char_u *autoload_name(char_u *name);
int script_autoload(char_u *name, int reload);
+ int sourcing_a_script(exarg_T *eap);
/* vim: set ft=c : */
*** ../vim-8.2.4593/src/vim9script.c 2022-03-08 13:18:10.809020782 +0000
--- src/vim9script.c 2022-03-19 12:36:45.102120794 +0000
***************
*** 71,77 ****
int found_noclear = FALSE;
char_u *p;
! if (!getline_equal(eap->getline, eap->cookie, getsourceline))
{
emsg(_(e_vim9script_can_only_be_used_in_script));
return;
--- 71,77 ----
int found_noclear = FALSE;
char_u *p;
! if (!sourcing_a_script(eap))
{
emsg(_(e_vim9script_can_only_be_used_in_script));
return;
***************
*** 633,639 ****
char_u *cmd_end;
evalarg_T evalarg;
! if (!getline_equal(eap->getline, eap->cookie, getsourceline))
{
emsg(_(e_import_can_only_be_used_in_script));
return;
--- 633,639 ----
char_u *cmd_end;
evalarg_T evalarg;
! if (!sourcing_a_script(eap))
{
emsg(_(e_import_can_only_be_used_in_script));
return;
*** ../vim-8.2.4593/src/testdir/test_source.vim 2021-12-27 17:21:38.020449109
+0000
--- src/testdir/test_source.vim 2022-03-19 12:36:45.102120794 +0000
***************
*** 94,99 ****
--- 94,105 ----
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
***************
*** 110,113 ****
--- 116,348 ----
call StopVimInTerminal(buf)
endfunc
+ " Test for sourcing a script from the current buffer
+ func Test_source_buffer()
+ new
+ " Source a simple script
+ let lines =<< trim END
+ let a = "Test"
+ let b = 20
+
+ let c = [1.1]
+ END
+ call setline(1, lines)
+ source
+ call assert_equal(['Test', 20, [1.1]], [g:a, g:b, g:c])
+
+ " Source a range of lines in the current buffer
+ %d _
+ let lines =<< trim END
+ let a = 10
+ let a += 20
+ let a += 30
+ let a += 40
+ END
+ call setline(1, lines)
+ .source
+ call assert_equal(10, g:a)
+ 3source
+ call assert_equal(40, g:a)
+ 2,3source
+ call assert_equal(90, g:a)
+
+ " Source a script with line continuation lines
+ %d _
+ let lines =<< trim END
+ let m = [
+ \ 1,
+ \ 2,
+ \ ]
+ call add(m, 3)
+ END
+ call setline(1, lines)
+ source
+ call assert_equal([1, 2, 3], g:m)
+ " Source a script with line continuation lines and a comment
+ %d _
+ let lines =<< trim END
+ let m = [
+ "\ first entry
+ \ 'a',
+ "\ second entry
+ \ 'b',
+ \ ]
+ " third entry
+ call add(m, 'c')
+ END
+ call setline(1, lines)
+ source
+ call assert_equal(['a', 'b', 'c'], g:m)
+ " Source an incomplete line continuation line
+ %d _
+ let lines =<< trim END
+ let k = [
+ \
+ END
+ call setline(1, lines)
+ call assert_fails('source', 'E697:')
+ " Source a function with a for loop
+ %d _
+ let lines =<< trim END
+ let m = []
+ " test function
+ func! Xtest()
+ for i in range(5, 7)
+ call add(g:m, i)
+ endfor
+ endfunc
+ call Xtest()
+ END
+ call setline(1, lines)
+ source
+ call assert_equal([5, 6, 7], g:m)
+ " Source an empty buffer
+ %d _
+ source
+
+ " test for script local functions and variables
+ let lines =<< trim END
+ let s:var1 = 10
+ func s:F1()
+ let s:var1 += 1
+ return s:var1
+ endfunc
+ func s:F2()
+ endfunc
+ let g:ScriptID = expand("<SID>")
+ END
+ call setline(1, lines)
+ source
+ call assert_true(g:ScriptID != '')
+ call assert_true(exists('*' .. g:ScriptID .. 'F1'))
+ call assert_true(exists('*' .. g:ScriptID .. 'F2'))
+ call assert_equal(11, call(g:ScriptID .. 'F1', []))
+
+ " the same script ID should be used even if the buffer is sourced more than
+ " once
+ %d _
+ let lines =<< trim END
+ let g:ScriptID = expand("<SID>")
+ let g:Count += 1
+ END
+ call setline(1, lines)
+ let g:Count = 0
+ source
+ call assert_true(g:ScriptID != '')
+ let scid = g:ScriptID
+ source
+ call assert_equal(scid, g:ScriptID)
+ call assert_equal(2, g:Count)
+ source
+ call assert_equal(scid, g:ScriptID)
+ call assert_equal(3, g:Count)
+
+ " test for the script line number
+ %d _
+ let lines =<< trim END
+ " comment
+ let g:Slnum1 = expand("<slnum>")
+ let i = 1 +
+ \ 2 +
+ "\ comment
+ \ 3
+ let g:Slnum2 = expand("<slnum>")
+ END
+ call setline(1, lines)
+ source
+ call assert_equal('2', g:Slnum1)
+ call assert_equal('7', g:Slnum2)
+
+ " test for retaining the same script number across source calls
+ let lines =<< trim END
+ let g:ScriptID1 = expand("<SID>")
+ let g:Slnum1 = expand("<slnum>")
+ let l =<< trim END
+ let g:Slnum2 = expand("<slnum>")
+ let g:ScriptID2 = expand("<SID>")
+ END
+ new
+ call setline(1, l)
+ source
+ bw!
+ let g:ScriptID3 = expand("<SID>")
+ let g:Slnum3 = expand("<slnum>")
+ END
+ call writefile(lines, 'Xscript')
+ source Xscript
+ call assert_true(g:ScriptID1 != g:ScriptID2)
+ call assert_equal(g:ScriptID1, g:ScriptID3)
+ call assert_equal('2', g:Slnum1)
+ call assert_equal('1', g:Slnum2)
+ call assert_equal('12', g:Slnum3)
+ call delete('Xscript')
+
+ " test for sourcing a heredoc
+ %d _
+ let lines =<< trim END
+ let a = 1
+ let heredoc =<< trim DATA
+ red
+ green
+ blue
+ DATA
+ let b = 2
+ END
+ call setline(1, lines)
+ source
+ call assert_equal(['red', ' green', 'blue'], g:heredoc)
+
+ " test for a while and for statement
+ %d _
+ let lines =<< trim END
+ let a = 0
+ let b = 1
+ while b <= 10
+ let a += 10
+ let b += 1
+ endwhile
+ for i in range(5)
+ let a += 10
+ endfor
+ END
+ call setline(1, lines)
+ source
+ call assert_equal(150, g:a)
+
+ " test for sourcing the same buffer multiple times after changing a function
+ %d _
+ let lines =<< trim END
+ func Xtestfunc()
+ return "one"
+ endfunc
+ END
+ call setline(1, lines)
+ source
+ call assert_equal("one", Xtestfunc())
+ call setline(2, ' return "two"')
+ source
+ call assert_equal("two", Xtestfunc())
+ call setline(2, ' return "three"')
+ source
+ call assert_equal("three", Xtestfunc())
+ delfunc Xtestfunc
+
+ " test for sourcing a Vim9 script
+ %d _
+ let lines =<< trim END
+ vim9script
+
+ # check dict
+ var x: number = 10
+ def g:Xtestfunc(): number
+ return x
+ enddef
+ END
+ call setline(1, lines)
+ source
+ call assert_equal(10, Xtestfunc())
+
+ %bw!
+ endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.4593/src/version.c 2022-03-19 11:42:13.449717210 +0000
--- src/version.c 2022-03-19 12:47:58.202122527 +0000
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 4594,
/**/
--
GALAHAD: No, please. Please! I can defeat them! There's only a hundred.
GIRLS: He will beat us easily. We haven't a chance.
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/20220319125738.A6D1B1C13E5%40moolenaar.net.