Skip to content

Commit 4db572e

Browse files
committed
patch 8.2.3178: Vim9: the file name of an :import cannot be an expression
Problem: Vim9: the file name of an :import cannot be an expression. Solution: Accept an expression that results in a string. Do not support :import in a function.
1 parent ad2d496 commit 4db572e

5 files changed

Lines changed: 25 additions & 65 deletions

File tree

runtime/doc/vim9.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,9 @@ script file to avoid confusion.
13541354
`:import` can also be used in legacy Vim script. The imported items still
13551355
become script-local, even when the "s:" prefix is not given.
13561356

1357+
`:import` can not be used in a function. Imported items are intended to exist
1358+
at the script level and only imported once.
1359+
13571360
The script name after `import` can be:
13581361
- A relative path, starting "." or "..". This finds a file relative to the
13591362
location of the script file itself. This is useful to split up a large
@@ -1363,6 +1366,7 @@ The script name after `import` can be:
13631366
- A path not being relative or absolute. This will be found in the
13641367
"import" subdirectories of 'runtimepath' entries. The name will usually be
13651368
longer and unique, to avoid loading the wrong file.
1369+
Note that "after/import" is not used.
13661370

13671371
Once a vim9 script file has been imported, the result is cached and used the
13681372
next time the same script is imported. It will not be read again.

src/testdir/test_vim9_script.vim

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,9 @@ def Test_vim9_import_export()
10851085
enddef
10861086
g:funcref_result = GetExported()
10871087

1088-
import {exp_name} from './Xexport.vim'
1088+
var dir = './'
1089+
var ext = ".vim"
1090+
import {exp_name} from dir .. 'Xexport' .. ext
10891091
g:imported_name = exp_name
10901092
exp_name ..= ' Doe'
10911093
g:imported_name_appended = exp_name
@@ -1148,26 +1150,6 @@ def Test_vim9_import_export()
11481150
unlet g:imported_func
11491151
delete('Ximport_lbr.vim')
11501152

1151-
# import inside :def function
1152-
var import_in_def_lines =<< trim END
1153-
vim9script
1154-
def ImportInDef()
1155-
import exported from './Xexport.vim'
1156-
g:imported = exported
1157-
exported += 7
1158-
g:imported_added = exported
1159-
enddef
1160-
ImportInDef()
1161-
END
1162-
writefile(import_in_def_lines, 'Ximport2.vim')
1163-
source Ximport2.vim
1164-
# TODO: this should be 9879
1165-
assert_equal(9876, g:imported)
1166-
assert_equal(9883, g:imported_added)
1167-
unlet g:imported
1168-
unlet g:imported_added
1169-
delete('Ximport2.vim')
1170-
11711153
var import_star_as_lines =<< trim END
11721154
vim9script
11731155
import * as Export from './Xexport.vim'
@@ -1181,8 +1163,9 @@ def Test_vim9_import_export()
11811163
END
11821164
writefile(import_star_as_lines, 'Ximport.vim')
11831165
source Ximport.vim
1184-
assert_equal(9883, g:imported_def)
1185-
assert_equal(9883, g:imported_script)
1166+
# FIXME: this should be 9881
1167+
assert_equal(9876, g:imported_def)
1168+
assert_equal(9876, g:imported_script)
11861169

11871170
var import_star_as_lines_no_dot =<< trim END
11881171
vim9script
@@ -1257,7 +1240,7 @@ def Test_vim9_import_export()
12571240
END
12581241
writefile(import_star_as_lbr_lines, 'Ximport.vim')
12591242
source Ximport.vim
1260-
assert_equal(9883, g:imported)
1243+
assert_equal(9876, g:imported)
12611244

12621245
var import_star_lines =<< trim END
12631246
vim9script
@@ -1345,7 +1328,7 @@ def Test_vim9_import_export()
13451328
import name from Xexport.vim
13461329
END
13471330
writefile(import_invalid_string_lines, 'Ximport.vim')
1348-
assert_fails('source Ximport.vim', 'E1071:', '', 2, 'Ximport.vim')
1331+
assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim')
13491332

13501333
var import_wrong_name_lines =<< trim END
13511334
vim9script
@@ -1659,22 +1642,6 @@ def Test_vim9script_reload_import()
16591642
source Xreload.vim
16601643
source Xreload.vim
16611644

1662-
var testlines =<< trim END
1663-
vim9script
1664-
def TheFunc()
1665-
import GetValtwo from './Xreload.vim'
1666-
assert_equal(222, GetValtwo())
1667-
enddef
1668-
TheFunc()
1669-
END
1670-
writefile(testlines, 'Ximport.vim')
1671-
source Ximport.vim
1672-
1673-
# Test that when not using "morelines" GetValtwo() and valtwo are still
1674-
# defined, because import doesn't reload a script.
1675-
writefile(lines, 'Xreload.vim')
1676-
source Ximport.vim
1677-
16781645
# cannot declare a var twice
16791646
lines =<< trim END
16801647
vim9script

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,8 @@ static char *(features[]) =
755755

756756
static int included_patches[] =
757757
{ /* Add new patch number below this line */
758+
/**/
759+
3178,
758760
/**/
759761
3177,
760762
/**/

src/vim9compile.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4335,7 +4335,6 @@ compile_subscript(
43354335
semsg(_(e_missing_paren), *arg);
43364336
return FAIL;
43374337
}
4338-
// TODO: base value may not be the first argument
43394338
if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL)
43404339
return FAIL;
43414340
}
@@ -7293,15 +7292,6 @@ compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
72937292
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
72947293
}
72957294

7296-
/*
7297-
* Compile an :import command.
7298-
*/
7299-
static char_u *
7300-
compile_import(char_u *arg, cctx_T *cctx)
7301-
{
7302-
return handle_import(arg, &cctx->ctx_imports, 0, NULL, cctx);
7303-
}
7304-
73057295
/*
73067296
* generate a jump to the ":endif"/":endfor"/":endwhile"/":finally"/":endtry".
73077297
*/
@@ -9638,7 +9628,8 @@ compile_def_function(
96389628
break;
96399629

96409630
case CMD_import:
9641-
line = compile_import(p, &cctx);
9631+
emsg(_(e_import_can_only_be_used_in_script));
9632+
line = NULL;
96429633
break;
96439634

96449635
case CMD_if:

src/vim9script.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ handle_import(
412412
garray_T names;
413413
garray_T as_names;
414414

415+
tv.v_type = VAR_UNKNOWN;
415416
ga_init2(&names, sizeof(char_u *), 10);
416417
ga_init2(&as_names, sizeof(char_u *), 10);
417418
if (*arg == '{')
@@ -496,14 +497,14 @@ handle_import(
496497
goto erret;
497498
}
498499

500+
// The name of the file can be an expression, which must evaluate to a
501+
// string.
499502
arg = skipwhite_and_linebreak(arg + 4, evalarg);
500-
tv.v_type = VAR_UNKNOWN;
501-
// TODO: should we accept any expression?
502-
if (*arg == '\'')
503-
ret = eval_lit_string(&arg, &tv, TRUE);
504-
else if (*arg == '"')
505-
ret = eval_string(&arg, &tv, TRUE);
506-
if (ret == FAIL || tv.vval.v_string == NULL || *tv.vval.v_string == NUL)
503+
ret = eval0(arg, &tv, NULL, evalarg);
504+
if (ret == FAIL)
505+
goto erret;
506+
if (tv.v_type != VAR_STRING
507+
|| tv.vval.v_string == NULL || *tv.vval.v_string == NUL)
507508
{
508509
emsg(_(e_invalid_string_after_from));
509510
goto erret;
@@ -524,10 +525,7 @@ handle_import(
524525
len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2;
525526
from_name = alloc((int)len);
526527
if (from_name == NULL)
527-
{
528-
clear_tv(&tv);
529528
goto erret;
530-
}
531529
vim_strncpy(from_name, si->sn_name, tail - si->sn_name);
532530
add_pathsep(from_name);
533531
STRCAT(from_name, tv.vval.v_string);
@@ -550,7 +548,6 @@ handle_import(
550548
from_name = alloc((int)len);
551549
if (from_name == NULL)
552550
{
553-
clear_tv(&tv);
554551
goto erret;
555552
}
556553
vim_snprintf((char *)from_name, len, "import/%s", tv.vval.v_string);
@@ -561,10 +558,8 @@ handle_import(
561558
if (res == FAIL || sid <= 0)
562559
{
563560
semsg(_(e_could_not_import_str), tv.vval.v_string);
564-
clear_tv(&tv);
565561
goto erret;
566562
}
567-
clear_tv(&tv);
568563

569564
if (*arg_start == '*')
570565
{
@@ -669,6 +664,7 @@ handle_import(
669664
}
670665
}
671666
erret:
667+
clear_tv(&tv);
672668
ga_clear_strings(&names);
673669
ga_clear_strings(&as_names);
674670
return cmd_end;

0 commit comments

Comments
 (0)