]> granicus.if.org Git - vim/commitdiff
patch 8.2.4594: need to write script to a file to be able to source them v8.2.4594
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 19 Mar 2022 12:56:51 +0000 (12:56 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 19 Mar 2022 12:56:51 +0000 (12:56 +0000)
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)

runtime/doc/repeat.txt
runtime/doc/todo.txt
src/alloc.c
src/digraph.c
src/eval.c
src/ex_cmds.h
src/proto/scriptfile.pro
src/scriptfile.c
src/testdir/test_source.vim
src/version.c
src/vim9script.c

index ce88a10bec1ac3c3c594751b84607fb1c6e63d57..a775af03a61a82c99266a64a4699e0ac5fe4f967 100644 (file)
@@ -197,6 +197,12 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
 :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
index 5a9705121a4d33c010beeb09405d495584280e8d..57a84e5cc4bf2e49ea4cbcdcb87493464b835fb3 100644 (file)
@@ -4333,12 +4333,6 @@ Vim script language:
     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)
index 19f8fcd6749989fa565f1d5b5dca4e147a9c01e0..e6e2633d21a13a98ae75408db8e4def38c445c07 100644 (file)
@@ -845,7 +845,7 @@ ga_concat(garray_T *gap, char_u *s)
     void
 ga_concat_len(garray_T *gap, char_u *s, size_t len)
 {
-    if (s == NULL || *s == NUL)
+    if (s == NULL || *s == NUL || len == 0)
        return;
     if (ga_grow(gap, (int)len) == OK)
     {
index bbab9584a68d20fe4b787f8cfe9e07964f4267f4..9fdd0b3f4e18f7f35023fd0016b39ce86258948b 100644 (file)
@@ -2507,7 +2507,7 @@ ex_loadkeymap(exarg_T *eap)
     int                i;
     char_u     *save_cpo = p_cpo;
 
-    if (!getline_equal(eap->getline, eap->cookie, getsourceline))
+    if (!sourcing_a_script(eap))
     {
        emsg(_(e_using_loadkeymap_not_in_sourced_file));
        return;
index 8d1e4fdf7ebcd023a66319d21e6ce57aa504b145..a963a15c01eaefc37d1dcd7df90342c55cd88f04 100644 (file)
@@ -140,7 +140,7 @@ fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, int skip)
     if (eap != NULL)
     {
        evalarg->eval_cstack = eap->cstack;
-       if (getline_equal(eap->getline, eap->cookie, getsourceline))
+       if (sourcing_a_script(eap))
        {
            evalarg->eval_getline = eap->getline;
            evalarg->eval_cookie = eap->cookie;
index a13de4d80b39a401242dbbb97173e03aa2126df9..c8ebcf6d94c62d37b5b9b11d1f1667a5ac7571bc 100644 (file)
@@ -1428,8 +1428,8 @@ EXCMD(CMD_snoremenu,      "snoremenu",    ex_menu,
        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),
+       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),
index 477dc3e6e1d693d26990ea7f121f02334909604d..d0ebdda103fd444e0d00c5483dbdf9b4e9695098 100644 (file)
@@ -42,4 +42,5 @@ char_u *get_autoload_prefix(scriptitem_T *si);
 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 : */
index 2606737545750cc8c5a817d8465f2f53f837d92c..9778843423bc4e0f501433db514b701860364233 100644 (file)
 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,12 +1079,270 @@ ExpandPackAddDir(
     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)
-       emsg(_(e_argument_required));
+    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,7 +1503,6 @@ do_source(
     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;
@@ -2015,6 +2277,17 @@ getsourceline(
     return line;
 }
 
+/*
+ * 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.
  */
@@ -2024,7 +2297,7 @@ ex_scriptencoding(exarg_T *eap)
     source_cookie_T    *sp;
     char_u             *name;
 
-    if (!getline_equal(eap->getline, eap->cookie, getsourceline))
+    if (!sourcing_a_script(eap))
     {
        emsg(_(e_scriptencoding_used_outside_of_sourced_file));
        return;
@@ -2055,7 +2328,7 @@ ex_scriptversion(exarg_T *eap UNUSED)
 {
     int                nr;
 
-    if (!getline_equal(eap->getline, eap->cookie, getsourceline))
+    if (!sourcing_a_script(eap))
     {
        emsg(_(e_scriptversion_used_outside_of_sourced_file));
        return;
@@ -2087,7 +2360,7 @@ ex_scriptversion(exarg_T *eap UNUSED)
     void
 ex_finish(exarg_T *eap)
 {
-    if (getline_equal(eap->getline, eap->cookie, getsourceline))
+    if (sourcing_a_script(eap))
        do_finish(eap, FALSE);
     else
        emsg(_(e_finish_used_outside_of_sourced_file));
index 8f8e9632a1b0ebb482f08e60afd0fd5dee310d15..bdf50e1bebe9e4df89a7d442ace23bf7aef277da 100644 (file)
@@ -94,6 +94,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
@@ -110,4 +116,233 @@ func Test_nested_script()
   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
index 442db2ca76b84ea24e821b511d3c57d3381e1e8c..1cb9ceba4c3a74ddf3b85efa4a9935ab129b39ee 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4594,
 /**/
     4593,
 /**/
index 6dce5722aece0c762daca43c75d8fd32cf7a26b7..870056fcc427a8d8cf6fecfed0f430bb6444ca14 100644 (file)
@@ -71,7 +71,7 @@ ex_vim9script(exarg_T *eap UNUSED)
     int                    found_noclear = FALSE;
     char_u         *p;
 
-    if (!getline_equal(eap->getline, eap->cookie, getsourceline))
+    if (!sourcing_a_script(eap))
     {
        emsg(_(e_vim9script_can_only_be_used_in_script));
        return;
@@ -633,7 +633,7 @@ ex_import(exarg_T *eap)
     char_u     *cmd_end;
     evalarg_T  evalarg;
 
-    if (!getline_equal(eap->getline, eap->cookie, getsourceline))
+    if (!sourcing_a_script(eap))
     {
        emsg(_(e_import_can_only_be_used_in_script));
        return;