summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-01-07 21:39:52 +0000
committerBram Moolenaar <Bram@vim.org>2022-01-07 21:39:52 +0000
commitd844862bcec5db210116847a67de93578ba781d7 (patch)
treecb1d924b4da4349322ff85d47ec35a949d552d21
parent48d0ac775cb2da3b5aa9d46711ff17c50ce0f707 (diff)
downloadvim-git-d844862bcec5db210116847a67de93578ba781d7.tar.gz
patch 8.2.4036: Vim9: script test file is getting too longv8.2.4036
Problem: Vim9: script test file is getting too long. Solution: Split the import/export functionality to a separate file.
-rw-r--r--src/testdir/Make_all.mak2
-rw-r--r--src/testdir/test_vim9_import.vim1069
-rw-r--r--src/testdir/test_vim9_script.vim1060
-rw-r--r--src/version.c2
4 files changed, 1074 insertions, 1059 deletions
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 3c54087a6..ec12b6b40 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -37,6 +37,7 @@ TEST_VIM9 = \
test_vim9_expr \
test_vim9_fails \
test_vim9_func \
+ test_vim9_import \
test_vim9_script
TEST_VIM9_RES = \
@@ -47,6 +48,7 @@ TEST_VIM9_RES = \
test_vim9_expr.res \
test_vim9_fails.res \
test_vim9_func.res \
+ test_vim9_import.res \
test_vim9_script.res
# Benchmark scripts.
diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim
new file mode 100644
index 000000000..9d09c63f6
--- /dev/null
+++ b/src/testdir/test_vim9_import.vim
@@ -0,0 +1,1069 @@
+" Test import/export of the Vim9 script language.
+
+source check.vim
+source term_util.vim
+source vim9.vim
+
+let s:export_script_lines =<< trim END
+ vim9script
+ var name: string = 'bob'
+ def Concat(arg: string): string
+ return name .. arg
+ enddef
+ g:result = Concat('bie')
+ g:localname = name
+
+ export const CONST = 1234
+ export var exported = 9876
+ export var exp_name = 'John'
+ export def Exported(): string
+ return 'Exported'
+ enddef
+ export def ExportedValue(): number
+ return exported
+ enddef
+ export def ExportedInc()
+ exported += 5
+ enddef
+ export final theList = [1]
+END
+
+def Undo_export_script_lines()
+ unlet g:result
+ unlet g:localname
+enddef
+
+def Test_vim9_import_export()
+ writefile(s:export_script_lines, 'Xexport.vim')
+ var import_script_lines =<< trim END
+ vim9script
+ var dir = './'
+ var ext = ".vim"
+ import dir .. 'Xexport' .. ext as expo
+
+ g:exported1 = expo.exported
+ expo.exported += 3
+ g:exported2 = expo.exported
+ g:exported3 = expo.ExportedValue()
+
+ expo.ExportedInc()
+ g:exported_i1 = expo.exported
+ g:exported_i2 = expo.ExportedValue()
+
+ expo.exported = 11
+ g:exported_s1 = expo.exported
+ g:exported_s2 = expo.ExportedValue()
+
+ g:imported_func = expo.Exported()
+
+ def GetExported(): string
+ var local_dict = {ref: expo.Exported}
+ return local_dict.ref()
+ enddef
+ g:funcref_result = GetExported()
+
+ g:imported_name = expo.exp_name
+ expo.exp_name ..= ' Doe'
+ g:imported_name_appended = expo.exp_name
+ g:exported_later = expo.exported
+
+ expo.theList->add(2)
+ assert_equal([1, 2], expo.theList)
+ END
+ writefile(import_script_lines, 'Ximport.vim')
+ source Ximport.vim
+
+ assert_equal('bobbie', g:result)
+ assert_equal('bob', g:localname)
+ assert_equal(9876, g:exported1)
+ assert_equal(9879, g:exported2)
+ assert_equal(9879, g:exported3)
+
+ assert_equal(9884, g:exported_i1)
+ assert_equal(9884, g:exported_i2)
+
+ assert_equal(11, g:exported_s1)
+ assert_equal(11, g:exported_s2)
+ assert_equal(11, g:exported_later)
+
+ assert_equal('Exported', g:imported_func)
+ assert_equal('Exported', g:funcref_result)
+ assert_equal('John', g:imported_name)
+ assert_equal('John Doe', g:imported_name_appended)
+ assert_false(exists('g:name'))
+
+ Undo_export_script_lines()
+ unlet g:exported1
+ unlet g:exported2
+ unlet g:exported3
+ unlet g:exported_i1
+ unlet g:exported_i2
+ unlet g:exported_later
+ unlet g:imported_func
+ unlet g:imported_name g:imported_name_appended
+ delete('Ximport.vim')
+
+ # similar, with line breaks
+ var import_line_break_script_lines =<< trim END
+ vim9script
+ import './Xexport.vim'
+ as expo
+ g:exported = expo.exported
+ expo.exported += 7
+ g:exported_added = expo.exported
+ g:imported_func = expo.Exported()
+ END
+ writefile(import_line_break_script_lines, 'Ximport_lbr.vim')
+ source Ximport_lbr.vim
+
+ assert_equal(11, g:exported)
+ assert_equal(18, g:exported_added)
+ assert_equal('Exported', g:imported_func)
+
+ # exported script not sourced again
+ assert_false(exists('g:result'))
+ unlet g:exported
+ unlet g:exported_added
+ unlet g:imported_func
+ delete('Ximport_lbr.vim')
+
+ var line_break_before_dot =<< trim END
+ vim9script
+ import './Xexport.vim' as expo
+ g:exported = expo
+ .exported
+ END
+ writefile(line_break_before_dot, 'Ximport_lbr_before_dot.vim')
+ assert_fails('source Ximport_lbr_before_dot.vim', 'E1060:', '', 3)
+ delete('Ximport_lbr_before_dot.vim')
+
+ var line_break_after_dot =<< trim END
+ vim9script
+ import './Xexport.vim' as expo
+ g:exported = expo.
+ exported
+ END
+ writefile(line_break_after_dot, 'Ximport_lbr_after_dot.vim')
+ assert_fails('source Ximport_lbr_after_dot.vim', 'E1074:', '', 3)
+ delete('Ximport_lbr_after_dot.vim')
+
+ var import_star_as_lines =<< trim END
+ vim9script
+ import './Xexport.vim' as Export
+ def UseExport()
+ g:exported_def = Export.exported
+ enddef
+ g:exported_script = Export.exported
+ assert_equal(1, exists('Export.exported'))
+ assert_equal(0, exists('Export.notexported'))
+ UseExport()
+ END
+ writefile(import_star_as_lines, 'Ximport.vim')
+ source Ximport.vim
+
+ assert_equal(18, g:exported_def)
+ assert_equal(18, g:exported_script)
+ unlet g:exported_def
+ unlet g:exported_script
+
+ var import_star_as_lines_no_dot =<< trim END
+ vim9script
+ import './Xexport.vim' as Export
+ def Func()
+ var dummy = 1
+ var imported = Export + dummy
+ enddef
+ defcompile
+ END
+ writefile(import_star_as_lines_no_dot, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1060:', '', 2, 'Func')
+
+ var import_star_as_lines_dot_space =<< trim END
+ vim9script
+ import './Xexport.vim' as Export
+ def Func()
+ var imported = Export . exported
+ enddef
+ defcompile
+ END
+ writefile(import_star_as_lines_dot_space, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func')
+
+ var import_func_duplicated =<< trim END
+ vim9script
+ import './Xexport.vim' as expo
+ import './Xexport.vim' as expo
+
+ ExportedInc()
+ END
+ writefile(import_func_duplicated, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1073:', '', 3, 'Ximport.vim')
+
+ var import_star_as_duplicated =<< trim END
+ vim9script
+ import './Xexport.vim' as Export
+ var some = 'other'
+ import './Xexport.vim' as Export
+ defcompile
+ END
+ writefile(import_star_as_duplicated, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim')
+
+ var import_star_as_lines_script_no_dot =<< trim END
+ vim9script
+ import './Xexport.vim' as Export
+ g:imported_script = Export exported
+ END
+ writefile(import_star_as_lines_script_no_dot, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1060: Expected dot after name: Export exported')
+
+ var import_star_as_lines_script_space_after_dot =<< trim END
+ vim9script
+ import './Xexport.vim' as Export
+ g:imported_script = Export. exported
+ END
+ writefile(import_star_as_lines_script_space_after_dot, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1074:')
+
+ var import_star_as_lines_missing_name =<< trim END
+ vim9script
+ import './Xexport.vim' as Export
+ def Func()
+ var imported = Export.
+ enddef
+ defcompile
+ END
+ writefile(import_star_as_lines_missing_name, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1048:', '', 1, 'Func')
+
+ var import_star_as_lbr_lines =<< trim END
+ vim9script
+ import './Xexport.vim'
+ as Export
+ def UseExport()
+ g:exported = Export.exported
+ enddef
+ UseExport()
+ END
+ writefile(import_star_as_lbr_lines, 'Ximport.vim')
+ source Ximport.vim
+ assert_equal(18, g:exported)
+ unlet g:exported
+
+ # try to use something that exists but is not exported
+ var import_not_exported_lines =<< trim END
+ vim9script
+ import './Xexport.vim' as expo
+ echo expo.name
+ END
+ writefile(import_not_exported_lines, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1049:', '', 3, 'Ximport.vim')
+
+ # try to import something that is already defined
+ var import_already_defined =<< trim END
+ vim9script
+ var exported = 'something'
+ import './Xexport.vim' as exported
+ END
+ writefile(import_already_defined, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim')
+
+ # try changing an imported const
+ var import_assign_to_const =<< trim END
+ vim9script
+ import './Xexport.vim' as expo
+ def Assign()
+ expo.CONST = 987
+ enddef
+ defcompile
+ END
+ writefile(import_assign_to_const, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign')
+
+ # try changing an imported final
+ var import_assign_to_final =<< trim END
+ vim9script
+ import './Xexport.vim' as expo
+ def Assign()
+ expo.theList = [2]
+ enddef
+ defcompile
+ END
+ writefile(import_assign_to_final, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign')
+
+ var import_no_as_lines =<< trim END
+ vim9script
+ import './Xexport.vim' name
+ END
+ writefile(import_no_as_lines, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E488:', '', 2, 'Ximport.vim')
+
+ var import_invalid_string_lines =<< trim END
+ vim9script
+ import Xexport.vim
+ END
+ writefile(import_invalid_string_lines, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim')
+
+ var import_wrong_name_lines =<< trim END
+ vim9script
+ import './XnoExport.vim'
+ END
+ writefile(import_wrong_name_lines, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1053:', '', 2, 'Ximport.vim')
+
+ var import_redefining_lines =<< trim END
+ vim9script
+ import './Xexport.vim' as exported
+ var exported = 5
+ END
+ writefile(import_redefining_lines, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1213: Redefining imported item "exported"', '', 3)
+
+ var import_assign_wrong_type_lines =<< trim END
+ vim9script
+ import './Xexport.vim' as expo
+ expo.exported = 'xxx'
+ END
+ writefile(import_assign_wrong_type_lines, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1012: Type mismatch; expected number but got string', '', 3)
+
+ var import_assign_const_lines =<< trim END
+ vim9script
+ import './Xexport.vim' as expo
+ expo.CONST = 4321
+ END
+ writefile(import_assign_const_lines, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E46: Cannot change read-only variable "CONST"', '', 3)
+
+ delete('Ximport.vim')
+ delete('Ximport3.vim')
+ delete('Xexport.vim')
+
+ # Check that in a Vim9 script 'cpo' is set to the Vim default.
+ # Flags added or removed are also applied to the restored value.
+ set cpo=abcd
+ var lines =<< trim END
+ vim9script
+ g:cpo_in_vim9script = &cpo
+ set cpo+=f
+ set cpo-=c
+ g:cpo_after_vim9script = &cpo
+ END
+ writefile(lines, 'Xvim9_script')
+ source Xvim9_script
+ assert_equal('fabd', &cpo)
+ set cpo&vim
+ assert_equal(&cpo, g:cpo_in_vim9script)
+ var newcpo = substitute(&cpo, 'c', '', '') .. 'f'
+ assert_equal(newcpo, g:cpo_after_vim9script)
+
+ delete('Xvim9_script')
+enddef
+
+def Test_import_funcref()
+ var lines =<< trim END
+ vim9script
+ export def F(): number
+ return 42
+ enddef
+ export const G = F
+ END
+ writefile(lines, 'Xlib.vim')
+
+ lines =<< trim END
+ vim9script
+ import './Xlib.vim' as lib
+ const Foo = lib.G()
+ assert_equal(42, Foo)
+
+ def DoTest()
+ const Goo = lib.G()
+ assert_equal(42, Goo)
+ enddef
+ DoTest()
+ END
+ CheckScriptSuccess(lines)
+
+ delete('Xlib.vim')
+enddef
+
+def Test_import_fails()
+ writefile([], 'Xfoo.vim')
+ var lines =<< trim END
+ import './Xfoo.vim' as foo
+ foo = 'bar'
+ END
+ CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use foo itself'])
+ lines =<< trim END
+ vim9script
+ import './Xfoo.vim' as foo
+ var that = foo
+ END
+ CheckScriptFailure(lines, 'E1060: Expected dot after name: foo')
+
+ lines =<< trim END
+ vim9script
+ import './Xfoo.vim' as 9foo
+ END
+ CheckScriptFailure(lines, 'E1047:')
+ lines =<< trim END
+ vim9script
+ import './Xfoo.vim' as the#foo
+ END
+ CheckScriptFailure(lines, 'E1047:')
+ lines =<< trim END
+ vim9script
+ import './Xfoo.vim' as g:foo
+ END
+ CheckScriptFailure(lines, 'E1047:')
+
+ delete('Xfoo.vim')
+
+ lines =<< trim END
+ vim9script
+ def TheFunc()
+ echo 'the func'
+ enddef
+ export var Ref = TheFunc
+ END
+ writefile([], 'Xthat.vim')
+ lines =<< trim END
+ import './Xthat.vim' as That
+ That()
+ END
+ CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use That itself'])
+
+ mkdir('Ximport')
+
+ writefile(['vim9script'], 'Ximport/.vim')
+ lines =<< trim END
+ vim9script
+ import './Ximport/.vim'
+ END
+ CheckScriptFailure(lines, 'E1261: Cannot import .vim without using "as"')
+ lines =<< trim END
+ vim9script
+ import './Ximport/.vim' as vim
+ END
+ CheckScriptSuccess(lines)
+
+ writefile(['vim9script'], 'Ximport/.vimrc')
+ lines =<< trim END
+ vim9script
+ import './Ximport/.vimrc'
+ END
+ CheckScriptFailure(lines, 'E1257: Imported script must use "as" or end in .vim')
+ lines =<< trim END
+ vim9script
+ import './Ximport/.vimrc' as vimrc
+ END
+ CheckScriptSuccess(lines)
+
+ delete('Ximport', 'rf')
+enddef
+
+func g:Trigger()
+ source Ximport.vim
+ return "echo 'yes'\<CR>"
+endfunc
+
+def Test_import_export_expr_map()
+ # check that :import and :export work when buffer is locked
+ var export_lines =<< trim END
+ vim9script
+ export def That(): string
+ return 'yes'
+ enddef
+ END
+ writefile(export_lines, 'Xexport_that.vim')
+
+ var import_lines =<< trim END
+ vim9script
+ import './Xexport_that.vim' as that
+ assert_equal('yes', that.That())
+ END
+ writefile(import_lines, 'Ximport.vim')
+
+ nnoremap <expr> trigger g:Trigger()
+ feedkeys('trigger', "xt")
+
+ delete('Xexport_that.vim')
+ delete('Ximport.vim')
+ nunmap trigger
+enddef
+
+def Test_import_in_filetype()
+ # check that :import works when the buffer is locked
+ mkdir('ftplugin', 'p')
+ var export_lines =<< trim END
+ vim9script
+ export var That = 'yes'
+ END
+ writefile(export_lines, 'ftplugin/Xexport_ft.vim')
+
+ var import_lines =<< trim END
+ vim9script
+ import './Xexport_ft.vim' as ft
+ assert_equal('yes', ft.That)
+ g:did_load_mytpe = 1
+ END
+ writefile(import_lines, 'ftplugin/qf.vim')
+
+ var save_rtp = &rtp
+ &rtp = getcwd() .. ',' .. &rtp
+
+ filetype plugin on
+ copen
+ assert_equal(1, g:did_load_mytpe)
+
+ quit!
+ delete('Xexport_ft.vim')
+ delete('ftplugin', 'rf')
+ &rtp = save_rtp
+enddef
+
+def Test_use_import_in_mapping()
+ var lines =<< trim END
+ vim9script
+ export def Funcx()
+ g:result = 42
+ enddef
+ END
+ writefile(lines, 'XsomeExport.vim')
+ lines =<< trim END
+ vim9script
+ import './XsomeExport.vim' as some
+ var Funcy = some.Funcx
+ nnoremap <F3> :call <sid>Funcy()<cr>
+ END
+ writefile(lines, 'Xmapscript.vim')
+
+ source Xmapscript.vim
+ feedkeys("\<F3>", "xt")
+ assert_equal(42, g:result)
+
+ unlet g:result
+ delete('XsomeExport.vim')
+ delete('Xmapscript.vim')
+ nunmap <F3>
+enddef
+
+def Test_export_fails()
+ CheckScriptFailure(['export var some = 123'], 'E1042:')
+ CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
+ CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
+
+ assert_fails('export something', 'E1043:')
+enddef
+
+func Test_import_fails_without_script()
+ CheckRunVimInTerminal
+
+ " call indirectly to avoid compilation error for missing functions
+ call Run_Test_import_fails_on_command_line()
+endfunc
+
+def Run_Test_import_fails_on_command_line()
+ var export =<< trim END
+ vim9script
+ export def Foo(): number
+ return 0
+ enddef
+ END
+ writefile(export, 'XexportCmd.vim')
+
+ var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', {
+ rows: 6, wait_for_ruler: 0})
+ WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5)))
+
+ delete('XexportCmd.vim')
+ StopVimInTerminal(buf)
+enddef
+
+def Test_vim9_reload_noclear()
+ var lines =<< trim END
+ vim9script
+ export var exported = 'thexport'
+
+ export def TheFunc(x = 0)
+ enddef
+ END
+ writefile(lines, 'XExportReload')
+ lines =<< trim END
+ vim9script noclear
+ g:loadCount += 1
+ var s:reloaded = 'init'
+ import './XExportReload' as exp
+
+ def Again(): string
+ return 'again'
+ enddef
+
+ exp.TheFunc()
+
+ if exists('s:loaded') | finish | endif
+ var s:loaded = true
+
+ var s:notReloaded = 'yes'
+ s:reloaded = 'first'
+ def g:Values(): list<string>
+ return [s:reloaded, s:notReloaded, Again(), Once(), exp.exported]
+ enddef
+
+ def Once(): string
+ return 'once'
+ enddef
+ END
+ writefile(lines, 'XReloaded')
+ g:loadCount = 0
+ source XReloaded
+ assert_equal(1, g:loadCount)
+ assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values())
+ source XReloaded
+ assert_equal(2, g:loadCount)
+ assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
+ source XReloaded
+ assert_equal(3, g:loadCount)
+ assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
+
+ delete('XReloaded')
+ delete('XExportReload')
+ delfunc g:Values
+ unlet g:loadCount
+
+ lines =<< trim END
+ vim9script
+ def Inner()
+ enddef
+ END
+ lines->writefile('XreloadScript.vim')
+ source XreloadScript.vim
+
+ lines =<< trim END
+ vim9script
+ def Outer()
+ def Inner()
+ enddef
+ enddef
+ defcompile
+ END
+ lines->writefile('XreloadScript.vim')
+ source XreloadScript.vim
+
+ delete('XreloadScript.vim')
+enddef
+
+def Test_vim9_reload_import()
+ var lines =<< trim END
+ vim9script
+ const var = ''
+ var valone = 1234
+ def MyFunc(arg: string)
+ valone = 5678
+ enddef
+ END
+ var morelines =<< trim END
+ var valtwo = 222
+ export def GetValtwo(): number
+ return valtwo
+ enddef
+ END
+ writefile(lines + morelines, 'Xreload.vim')
+ source Xreload.vim
+ source Xreload.vim
+ source Xreload.vim
+
+ # cannot declare a var twice
+ lines =<< trim END
+ vim9script
+ var valone = 1234
+ var valone = 5678
+ END
+ writefile(lines, 'Xreload.vim')
+ assert_fails('source Xreload.vim', 'E1041:', '', 3, 'Xreload.vim')
+
+ delete('Xreload.vim')
+ delete('Ximport.vim')
+enddef
+
+" if a script is reloaded with a script-local variable that changed its type, a
+" compiled function using that variable must fail.
+def Test_script_reload_change_type()
+ var lines =<< trim END
+ vim9script noclear
+ var str = 'string'
+ def g:GetStr(): string
+ return str .. 'xxx'
+ enddef
+ END
+ writefile(lines, 'Xreload.vim')
+ source Xreload.vim
+ echo g:GetStr()
+
+ lines =<< trim END
+ vim9script noclear
+ var str = 1234
+ END
+ writefile(lines, 'Xreload.vim')
+ source Xreload.vim
+ assert_fails('echo g:GetStr()', 'E1150:')
+
+ delfunc g:GetStr
+ delete('Xreload.vim')
+enddef
+
+" Define CallFunc so that the test can be compiled
+command CallFunc echo 'nop'
+
+def Test_script_reload_from_function()
+ var lines =<< trim END
+ vim9script
+
+ if exists('g:loaded')
+ finish
+ endif
+ g:loaded = 1
+ delcommand CallFunc
+ command CallFunc Func()
+ def Func()
+ so XreloadFunc.vim
+ g:didTheFunc = 1
+ enddef
+ END
+ writefile(lines, 'XreloadFunc.vim')
+ source XreloadFunc.vim
+ CallFunc
+ assert_equal(1, g:didTheFunc)
+
+ delete('XreloadFunc.vim')
+ delcommand CallFunc
+ unlet g:loaded
+ unlet g:didTheFunc
+enddef
+
+def s:RetSome(): string
+ return 'some'
+enddef
+
+" Not exported function that is referenced needs to be accessed by the
+" script-local name.
+def Test_vim9_funcref()
+ var sortlines =<< trim END
+ vim9script
+ def Compare(i1: number, i2: number): number
+ return i2 - i1
+ enddef
+
+ export def FastSort(): list<number>
+ return range(5)->sort(Compare)
+ enddef
+
+ export def GetString(arg: string): string
+ return arg
+ enddef
+ END
+ writefile(sortlines, 'Xsort.vim')
+
+ var lines =<< trim END
+ vim9script
+ import './Xsort.vim'
+ def Test()
+ g:result = Xsort.FastSort()
+ enddef
+ Test()
+
+ # using a function imported with "as"
+ import './Xsort.vim' as anAlias
+ assert_equal('yes', anAlias.GetString('yes'))
+
+ # using the function from a compiled function
+ def TestMore(): string
+ var s = s:anAlias.GetString('foo')
+ return s .. anAlias.GetString('bar')
+ enddef
+ assert_equal('foobar', TestMore())
+
+ # error when using a function that isn't exported
+ assert_fails('anAlias.Compare(1, 2)', 'E1049:')
+ END
+ writefile(lines, 'Xscript.vim')
+
+ source Xscript.vim
+ assert_equal([4, 3, 2, 1, 0], g:result)
+
+ unlet g:result
+ delete('Xsort.vim')
+ delete('Xscript.vim')
+
+ var Funcref = function('s:RetSome')
+ assert_equal('some', Funcref())
+enddef
+
+" Check that when searching for "FilterFunc" it finds the import in the
+" script where FastFilter() is called from, both as a string and as a direct
+" function reference.
+def Test_vim9_funcref_other_script()
+ var filterLines =<< trim END
+ vim9script
+ export def FilterFunc(idx: number, val: number): bool
+ return idx % 2 == 1
+ enddef
+ export def FastFilter(): list<number>
+ return range(10)->filter('FilterFunc(v:key, v:val)')
+ enddef
+ export def FastFilterDirect(): list<number>
+ return range(10)->filter(FilterFunc)
+ enddef
+ END
+ writefile(filterLines, 'Xfilter.vim')
+
+ var lines =<< trim END
+ vim9script
+ import './Xfilter.vim' as filter
+ def Test()
+ var x: list<number> = filter.FastFilter()
+ enddef
+ Test()
+ def TestDirect()
+ var x: list<number> = filter.FastFilterDirect()
+ enddef
+ TestDirect()
+ END
+ CheckScriptSuccess(lines)
+ delete('Xfilter.vim')
+enddef
+
+def Test_import_absolute()
+ var import_lines = [
+ 'vim9script',
+ 'import "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim" as abs',
+ 'def UseExported()',
+ ' g:imported_abs = abs.exported',
+ ' abs.exported = 8888',
+ ' g:imported_after = abs.exported',
+ 'enddef',
+ 'UseExported()',
+ 'g:import_disassembled = execute("disass UseExported")',
+ ]
+ writefile(import_lines, 'Ximport_abs.vim')
+ writefile(s:export_script_lines, 'Xexport_abs.vim')
+
+ source Ximport_abs.vim
+
+ assert_equal(9876, g:imported_abs)
+ assert_equal(8888, g:imported_after)
+ assert_match('<SNR>\d\+_UseExported\_s*' ..
+ 'g:imported_abs = abs.exported\_s*' ..
+ '0 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
+ '1 STOREG g:imported_abs\_s*' ..
+ 'abs.exported = 8888\_s*' ..
+ '2 PUSHNR 8888\_s*' ..
+ '3 STORESCRIPT exported-2 in .*Xexport_abs.vim\_s*' ..
+ 'g:imported_after = abs.exported\_s*' ..
+ '4 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
+ '5 STOREG g:imported_after',
+ g:import_disassembled)
+
+ Undo_export_script_lines()
+ unlet g:imported_abs
+ unlet g:import_disassembled
+
+ delete('Ximport_abs.vim')
+ delete('Xexport_abs.vim')
+enddef
+
+def Test_import_rtp()
+ var import_lines = [
+ 'vim9script',
+ 'import "Xexport_rtp.vim" as rtp',
+ 'g:imported_rtp = rtp.exported',
+ ]
+ writefile(import_lines, 'Ximport_rtp.vim')
+ mkdir('import', 'p')
+ writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
+
+ var save_rtp = &rtp
+ &rtp = getcwd()
+ source Ximport_rtp.vim
+ &rtp = save_rtp
+
+ assert_equal(9876, g:imported_rtp)
+
+ Undo_export_script_lines()
+ unlet g:imported_rtp
+ delete('Ximport_rtp.vim')
+ delete('import', 'rf')
+enddef
+
+def Test_import_compile_error()
+ var export_lines = [
+ 'vim9script',
+ 'export def ExpFunc(): string',
+ ' return notDefined',
+ 'enddef',
+ ]
+ writefile(export_lines, 'Xexported.vim')
+
+ var import_lines = [
+ 'vim9script',
+ 'import "./Xexported.vim" as expo',
+ 'def ImpFunc()',
+ ' echo expo.ExpFunc()',
+ 'enddef',
+ 'defcompile',
+ ]
+ writefile(import_lines, 'Ximport.vim')
+
+ try
+ source Ximport.vim
+ catch /E1001/
+ # Error should be before the Xexported.vim file.
+ assert_match('E1001: Variable not found: notDefined', v:exception)
+ assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
+ endtry
+
+ delete('Xexported.vim')
+ delete('Ximport.vim')
+enddef
+
+def Test_func_overrules_import_fails()
+ var export_lines =<< trim END
+ vim9script
+ export def Func()
+ echo 'imported'
+ enddef
+ END
+ writefile(export_lines, 'XexportedFunc.vim')
+
+ var lines =<< trim END
+ vim9script
+ import './XexportedFunc.vim' as Func
+ def Func()
+ echo 'local to function'
+ enddef
+ END
+ CheckScriptFailure(lines, 'E1236:')
+
+ lines =<< trim END
+ vim9script
+ import './XexportedFunc.vim' as Func
+ def Outer()
+ def Func()
+ echo 'local to function'
+ enddef
+ enddef
+ defcompile
+ END
+ CheckScriptFailure(lines, 'E1236:')
+
+ delete('XexportedFunc.vim')
+enddef
+
+def Test_source_vim9_from_legacy()
+ var vim9_lines =<< trim END
+ vim9script
+ var local = 'local'
+ g:global = 'global'
+ export var exported = 'exported'
+ export def GetText(): string
+ return 'text'
+ enddef
+ END
+ writefile(vim9_lines, 'Xvim9_script.vim')
+
+ var legacy_lines =<< trim END
+ source Xvim9_script.vim
+
+ call assert_false(exists('local'))
+ call assert_false(exists('exported'))
+ call assert_false(exists('s:exported'))
+ call assert_equal('global', global)
+ call assert_equal('global', g:global)
+
+ "" imported variable becomes script-local
+ "import exported from './Xvim9_script.vim'
+ "call assert_equal('exported', s:exported)
+ "call assert_false(exists('exported'))
+
+ "" imported function becomes script-local
+ "import GetText from './Xvim9_script.vim'
+ "call assert_equal('text', s:GetText())
+ "call assert_false(exists('*GetText'))
+ END
+ writefile(legacy_lines, 'Xlegacy_script.vim')
+
+ source Xlegacy_script.vim
+ assert_equal('global', g:global)
+ unlet g:global
+
+ delete('Xlegacy_script.vim')
+ delete('Xvim9_script.vim')
+enddef
+
+def Test_cmdline_win()
+ # if the Vim syntax highlighting uses Vim9 constructs they can be used from
+ # the command line window.
+ mkdir('rtp/syntax', 'p')
+ var export_lines =<< trim END
+ vim9script
+ export var That = 'yes'
+ END
+ writefile(export_lines, 'rtp/syntax/Xexport.vim')
+ var import_lines =<< trim END
+ vim9script
+ import './Xexport.vim' as exp
+ echo exp.That
+ END
+ writefile(import_lines, 'rtp/syntax/vim.vim')
+ var save_rtp = &rtp
+ &rtp = getcwd() .. '/rtp' .. ',' .. &rtp
+ syntax on
+ augroup CmdWin
+ autocmd CmdwinEnter * g:got_there = 'yes'
+ augroup END
+ # this will open and also close the cmdline window
+ feedkeys('q:', 'xt')
+ assert_equal('yes', g:got_there)
+
+ augroup CmdWin
+ au!
+ augroup END
+ &rtp = save_rtp
+ delete('rtp', 'rf')
+enddef
+
+def Test_import_gone_when_sourced_twice()
+ var exportlines =<< trim END
+ vim9script
+ if exists('g:guard')
+ finish
+ endif
+ g:guard = 1
+ export var name = 'someName'
+ END
+ writefile(exportlines, 'XexportScript.vim')
+
+ var lines =<< trim END
+ vim9script
+ import './XexportScript.vim' as expo
+ def g:GetName(): string
+ return expo.name
+ enddef
+ END
+ writefile(lines, 'XscriptImport.vim')
+ so XscriptImport.vim
+ assert_equal('someName', g:GetName())
+
+ so XexportScript.vim
+ assert_fails('call g:GetName()', 'E1149:')
+
+ delfunc g:GetName
+ delete('XexportScript.vim')
+ delete('XscriptImport.vim')
+ unlet g:guard
+enddef
+
+
+" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index b6dcf3621..8c7f85f16 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -2,10 +2,9 @@
source check.vim
source term_util.vim
-source view_util.vim
source vim9.vim
-source shared.vim
source screendump.vim
+source shared.vim
def Test_vim9script_feature()
# example from the help, here the feature is always present
@@ -1142,552 +1141,6 @@ if has('channel')
endfunc
endif
-let s:export_script_lines =<< trim END
- vim9script
- var name: string = 'bob'
- def Concat(arg: string): string
- return name .. arg
- enddef
- g:result = Concat('bie')
- g:localname = name
-
- export const CONST = 1234
- export var exported = 9876
- export var exp_name = 'John'
- export def Exported(): string
- return 'Exported'
- enddef
- export def ExportedValue(): number
- return exported
- enddef
- export def ExportedInc()
- exported += 5
- enddef
- export final theList = [1]
-END
-
-def Undo_export_script_lines()
- unlet g:result
- unlet g:localname
-enddef
-
-def Test_vim9_import_export()
- writefile(s:export_script_lines, 'Xexport.vim')
- var import_script_lines =<< trim END
- vim9script
- var dir = './'
- var ext = ".vim"
- import dir .. 'Xexport' .. ext as expo
-
- g:exported1 = expo.exported
- expo.exported += 3
- g:exported2 = expo.exported
- g:exported3 = expo.ExportedValue()
-
- expo.ExportedInc()
- g:exported_i1 = expo.exported
- g:exported_i2 = expo.ExportedValue()
-
- expo.exported = 11
- g:exported_s1 = expo.exported
- g:exported_s2 = expo.ExportedValue()
-
- g:imported_func = expo.Exported()
-
- def GetExported(): string
- var local_dict = {ref: expo.Exported}
- return local_dict.ref()
- enddef
- g:funcref_result = GetExported()
-
- g:imported_name = expo.exp_name
- expo.exp_name ..= ' Doe'
- g:imported_name_appended = expo.exp_name
- g:exported_later = expo.exported
-
- expo.theList->add(2)
- assert_equal([1, 2], expo.theList)
- END
- writefile(import_script_lines, 'Ximport.vim')
- source Ximport.vim
-
- assert_equal('bobbie', g:result)
- assert_equal('bob', g:localname)
- assert_equal(9876, g:exported1)
- assert_equal(9879, g:exported2)
- assert_equal(9879, g:exported3)
-
- assert_equal(9884, g:exported_i1)
- assert_equal(9884, g:exported_i2)
-
- assert_equal(11, g:exported_s1)
- assert_equal(11, g:exported_s2)
- assert_equal(11, g:exported_later)
-
- assert_equal('Exported', g:imported_func)
- assert_equal('Exported', g:funcref_result)
- assert_equal('John', g:imported_name)
- assert_equal('John Doe', g:imported_name_appended)
- assert_false(exists('g:name'))
-
- Undo_export_script_lines()
- unlet g:exported1
- unlet g:exported2
- unlet g:exported3
- unlet g:exported_i1
- unlet g:exported_i2
- unlet g:exported_later
- unlet g:imported_func
- unlet g:imported_name g:imported_name_appended
- delete('Ximport.vim')
-
- # similar, with line breaks
- var import_line_break_script_lines =<< trim END
- vim9script
- import './Xexport.vim'
- as expo
- g:exported = expo.exported
- expo.exported += 7
- g:exported_added = expo.exported
- g:imported_func = expo.Exported()
- END
- writefile(import_line_break_script_lines, 'Ximport_lbr.vim')
- source Ximport_lbr.vim
-
- assert_equal(11, g:exported)
- assert_equal(18, g:exported_added)
- assert_equal('Exported', g:imported_func)
-
- # exported script not sourced again
- assert_false(exists('g:result'))
- unlet g:exported
- unlet g:exported_added
- unlet g:imported_func
- delete('Ximport_lbr.vim')
-
- var line_break_before_dot =<< trim END
- vim9script
- import './Xexport.vim' as expo
- g:exported = expo
- .exported
- END
- writefile(line_break_before_dot, 'Ximport_lbr_before_dot.vim')
- assert_fails('source Ximport_lbr_before_dot.vim', 'E1060:', '', 3)
- delete('Ximport_lbr_before_dot.vim')
-
- var line_break_after_dot =<< trim END
- vim9script
- import './Xexport.vim' as expo
- g:exported = expo.
- exported
- END
- writefile(line_break_after_dot, 'Ximport_lbr_after_dot.vim')
- assert_fails('source Ximport_lbr_after_dot.vim', 'E1074:', '', 3)
- delete('Ximport_lbr_after_dot.vim')
-
- var import_star_as_lines =<< trim END
- vim9script
- import './Xexport.vim' as Export
- def UseExport()
- g:exported_def = Export.exported
- enddef
- g:exported_script = Export.exported
- assert_equal(1, exists('Export.exported'))
- assert_equal(0, exists('Export.notexported'))
- UseExport()
- END
- writefile(import_star_as_lines, 'Ximport.vim')
- source Ximport.vim
-
- assert_equal(18, g:exported_def)
- assert_equal(18, g:exported_script)
- unlet g:exported_def
- unlet g:exported_script
-
- var import_star_as_lines_no_dot =<< trim END
- vim9script
- import './Xexport.vim' as Export
- def Func()
- var dummy = 1
- var imported = Export + dummy
- enddef
- defcompile
- END
- writefile(import_star_as_lines_no_dot, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1060:', '', 2, 'Func')
-
- var import_star_as_lines_dot_space =<< trim END
- vim9script
- import './Xexport.vim' as Export
- def Func()
- var imported = Export . exported
- enddef
- defcompile
- END
- writefile(import_star_as_lines_dot_space, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func')
-
- var import_func_duplicated =<< trim END
- vim9script
- import './Xexport.vim' as expo
- import './Xexport.vim' as expo
-
- ExportedInc()
- END
- writefile(import_func_duplicated, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1073:', '', 3, 'Ximport.vim')
-
- var import_star_as_duplicated =<< trim END
- vim9script
- import './Xexport.vim' as Export
- var some = 'other'
- import './Xexport.vim' as Export
- defcompile
- END
- writefile(import_star_as_duplicated, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim')
-
- var import_star_as_lines_script_no_dot =<< trim END
- vim9script
- import './Xexport.vim' as Export
- g:imported_script = Export exported
- END
- writefile(import_star_as_lines_script_no_dot, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1060: Expected dot after name: Export exported')
-
- var import_star_as_lines_script_space_after_dot =<< trim END
- vim9script
- import './Xexport.vim' as Export
- g:imported_script = Export. exported
- END
- writefile(import_star_as_lines_script_space_after_dot, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1074:')
-
- var import_star_as_lines_missing_name =<< trim END
- vim9script
- import './Xexport.vim' as Export
- def Func()
- var imported = Export.
- enddef
- defcompile
- END
- writefile(import_star_as_lines_missing_name, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1048:', '', 1, 'Func')
-
- var import_star_as_lbr_lines =<< trim END
- vim9script
- import './Xexport.vim'
- as Export
- def UseExport()
- g:exported = Export.exported
- enddef
- UseExport()
- END
- writefile(import_star_as_lbr_lines, 'Ximport.vim')
- source Ximport.vim
- assert_equal(18, g:exported)
- unlet g:exported
-
- # try to use something that exists but is not exported
- var import_not_exported_lines =<< trim END
- vim9script
- import './Xexport.vim' as expo
- echo expo.name
- END
- writefile(import_not_exported_lines, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1049:', '', 3, 'Ximport.vim')
-
- # try to import something that is already defined
- var import_already_defined =<< trim END
- vim9script
- var exported = 'something'
- import './Xexport.vim' as exported
- END
- writefile(import_already_defined, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim')
-
- # try changing an imported const
- var import_assign_to_const =<< trim END
- vim9script
- import './Xexport.vim' as expo
- def Assign()
- expo.CONST = 987
- enddef
- defcompile
- END
- writefile(import_assign_to_const, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign')
-
- # try changing an imported final
- var import_assign_to_final =<< trim END
- vim9script
- import './Xexport.vim' as expo
- def Assign()
- expo.theList = [2]
- enddef
- defcompile
- END
- writefile(import_assign_to_final, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign')
-
- var import_no_as_lines =<< trim END
- vim9script
- import './Xexport.vim' name
- END
- writefile(import_no_as_lines, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E488:', '', 2, 'Ximport.vim')
-
- var import_invalid_string_lines =<< trim END
- vim9script
- import Xexport.vim
- END
- writefile(import_invalid_string_lines, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim')
-
- var import_wrong_name_lines =<< trim END
- vim9script
- import './XnoExport.vim'
- END
- writefile(import_wrong_name_lines, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1053:', '', 2, 'Ximport.vim')
-
- var import_redefining_lines =<< trim END
- vim9script
- import './Xexport.vim' as exported
- var exported = 5
- END
- writefile(import_redefining_lines, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1213: Redefining imported item "exported"', '', 3)
-
- var import_assign_wrong_type_lines =<< trim END
- vim9script
- import './Xexport.vim' as expo
- expo.exported = 'xxx'
- END
- writefile(import_assign_wrong_type_lines, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E1012: Type mismatch; expected number but got string', '', 3)
-
- var import_assign_const_lines =<< trim END
- vim9script
- import './Xexport.vim' as expo
- expo.CONST = 4321
- END
- writefile(import_assign_const_lines, 'Ximport.vim')
- assert_fails('source Ximport.vim', 'E46: Cannot change read-only variable "CONST"', '', 3)
-
- delete('Ximport.vim')
- delete('Ximport3.vim')
- delete('Xexport.vim')
-
- # Check that in a Vim9 script 'cpo' is set to the Vim default.
- # Flags added or removed are also applied to the restored value.
- set cpo=abcd
- var lines =<< trim END
- vim9script
- g:cpo_in_vim9script = &cpo
- set cpo+=f
- set cpo-=c
- g:cpo_after_vim9script = &cpo
- END
- writefile(lines, 'Xvim9_script')
- source Xvim9_script
- assert_equal('fabd', &cpo)
- set cpo&vim
- assert_equal(&cpo, g:cpo_in_vim9script)
- var newcpo = substitute(&cpo, 'c', '', '') .. 'f'
- assert_equal(newcpo, g:cpo_after_vim9script)
-
- delete('Xvim9_script')
-enddef
-
-def Test_import_funcref()
- var lines =<< trim END
- vim9script
- export def F(): number
- return 42
- enddef
- export const G = F
- END
- writefile(lines, 'Xlib.vim')
-
- lines =<< trim END
- vim9script
- import './Xlib.vim' as lib
- const Foo = lib.G()
- assert_equal(42, Foo)
-
- def DoTest()
- const Goo = lib.G()
- assert_equal(42, Goo)
- enddef
- DoTest()
- END
- CheckScriptSuccess(lines)
-
- delete('Xlib.vim')
-enddef
-
-def Test_import_fails()
- writefile([], 'Xfoo.vim')
- var lines =<< trim END
- import './Xfoo.vim' as foo
- foo = 'bar'
- END
- CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use foo itself'])
- lines =<< trim END
- vim9script
- import './Xfoo.vim' as foo
- var that = foo
- END
- CheckScriptFailure(lines, 'E1060: Expected dot after name: foo')
-
- lines =<< trim END
- vim9script
- import './Xfoo.vim' as 9foo
- END
- CheckScriptFailure(lines, 'E1047:')
- lines =<< trim END
- vim9script
- import './Xfoo.vim' as the#foo
- END
- CheckScriptFailure(lines, 'E1047:')
- lines =<< trim END
- vim9script
- import './Xfoo.vim' as g:foo
- END
- CheckScriptFailure(lines, 'E1047:')
-
- delete('Xfoo.vim')
-
- lines =<< trim END
- vim9script
- def TheFunc()
- echo 'the func'
- enddef
- export var Ref = TheFunc
- END
- writefile([], 'Xthat.vim')
- lines =<< trim END
- import './Xthat.vim' as That
- That()
- END
- CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use That itself'])
-
- mkdir('Ximport')
-
- writefile(['vim9script'], 'Ximport/.vim')
- lines =<< trim END
- vim9script
- import './Ximport/.vim'
- END
- CheckScriptFailure(lines, 'E1261: Cannot import .vim without using "as"')
- lines =<< trim END
- vim9script
- import './Ximport/.vim' as vim
- END
- CheckScriptSuccess(lines)
-
- writefile(['vim9script'], 'Ximport/.vimrc')
- lines =<< trim END
- vim9script
- import './Ximport/.vimrc'
- END
- CheckScriptFailure(lines, 'E1257: Imported script must use "as" or end in .vim')
- lines =<< trim END
- vim9script
- import './Ximport/.vimrc' as vimrc
- END
- CheckScriptSuccess(lines)
-
- delete('Ximport', 'rf')
-enddef
-
-func g:Trigger()
- source Ximport.vim
- return "echo 'yes'\<CR>"
-endfunc
-
-def Test_import_export_expr_map()
- # check that :import and :export work when buffer is locked
- var export_lines =<< trim END
- vim9script
- export def That(): string
- return 'yes'
- enddef
- END
- writefile(export_lines, 'Xexport_that.vim')
-
- var import_lines =<< trim END
- vim9script
- import './Xexport_that.vim' as that
- assert_equal('yes', that.That())
- END
- writefile(import_lines, 'Ximport.vim')
-
- nnoremap <expr> trigger g:Trigger()
- feedkeys('trigger', "xt")
-
- delete('Xexport_that.vim')
- delete('Ximport.vim')
- nunmap trigger
-enddef
-
-def Test_import_in_filetype()
- # check that :import works when the buffer is locked
- mkdir('ftplugin', 'p')
- var export_lines =<< trim END
- vim9script
- export var That = 'yes'
- END
- writefile(export_lines, 'ftplugin/Xexport_ft.vim')
-
- var import_lines =<< trim END
- vim9script
- import './Xexport_ft.vim' as ft
- assert_equal('yes', ft.That)
- g:did_load_mytpe = 1
- END
- writefile(import_lines, 'ftplugin/qf.vim')
-
- var save_rtp = &rtp
- &rtp = getcwd() .. ',' .. &rtp
-
- filetype plugin on
- copen
- assert_equal(1, g:did_load_mytpe)
-
- quit!
- delete('Xexport_ft.vim')
- delete('ftplugin', 'rf')
- &rtp = save_rtp
-enddef
-
-def Test_use_import_in_mapping()
- var lines =<< trim END
- vim9script
- export def Funcx()
- g:result = 42
- enddef
- END
- writefile(lines, 'XsomeExport.vim')
- lines =<< trim END
- vim9script
- import './XsomeExport.vim' as some
- var Funcy = some.Funcx
- nnoremap <F3> :call <sid>Funcy()<cr>
- END
- writefile(lines, 'Xmapscript.vim')
-
- source Xmapscript.vim
- feedkeys("\<F3>", "xt")
- assert_equal(42, g:result)
-
- unlet g:result
- delete('XsomeExport.vim')
- delete('Xmapscript.vim')
- nunmap <F3>
-enddef
-
def Test_vim9script_mix()
var lines =<< trim END
if has(g:feature)
@@ -1712,200 +1165,11 @@ enddef
def Test_vim9script_fails()
CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
- CheckScriptFailure(['export var some = 123'], 'E1042:')
- CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
- CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
CheckScriptFailure(['vim9script', 'var str: string', 'str = 1234'], 'E1012:')
CheckScriptFailure(['vim9script', 'const str = "asdf"', 'str = "xxx"'], 'E46:')
assert_fails('vim9script', 'E1038:')
- assert_fails('export something', 'E1043:')
-enddef
-
-func Test_import_fails_without_script()
- CheckRunVimInTerminal
-
- " call indirectly to avoid compilation error for missing functions
- call Run_Test_import_fails_on_command_line()
-endfunc
-
-def Run_Test_import_fails_on_command_line()
- var export =<< trim END
- vim9script
- export def Foo(): number
- return 0
- enddef
- END
- writefile(export, 'XexportCmd.vim')
-
- var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', {
- rows: 6, wait_for_ruler: 0})
- WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5)))
-
- delete('XexportCmd.vim')
- StopVimInTerminal(buf)
-enddef
-
-def Test_vim9script_reload_noclear()
- var lines =<< trim END
- vim9script
- export var exported = 'thexport'
-
- export def TheFunc(x = 0)
- enddef
- END
- writefile(lines, 'XExportReload')
- lines =<< trim END
- vim9script noclear
- g:loadCount += 1
- var s:reloaded = 'init'
- import './XExportReload' as exp
-
- def Again(): string
- return 'again'
- enddef
-
- exp.TheFunc()
-
- if exists('s:loaded') | finish | endif
- var s:loaded = true
-
- var s:notReloaded = 'yes'
- s:reloaded = 'first'
- def g:Values(): list<string>
- return [s:reloaded, s:notReloaded, Again(), Once(), exp.exported]
- enddef
-
- def Once(): string
- return 'once'
- enddef
- END
- writefile(lines, 'XReloaded')
- g:loadCount = 0
- source XReloaded
- assert_equal(1, g:loadCount)
- assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values())
- source XReloaded
- assert_equal(2, g:loadCount)
- assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
- source XReloaded
- assert_equal(3, g:loadCount)
- assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
-
- delete('XReloaded')
- delete('XExportReload')
- delfunc g:Values
- unlet g:loadCount
-
- lines =<< trim END
- vim9script
- def Inner()
- enddef
- END
- lines->writefile('XreloadScript.vim')
- source XreloadScript.vim
-
- lines =<< trim END
- vim9script
- def Outer()
- def Inner()
- enddef
- enddef
- defcompile
- END
- lines->writefile('XreloadScript.vim')
- source XreloadScript.vim
-
- delete('XreloadScript.vim')
-enddef
-
-def Test_vim9script_reload_import()
- var lines =<< trim END
- vim9script
- const var = ''
- var valone = 1234
- def MyFunc(arg: string)
- valone = 5678
- enddef
- END
- var morelines =<< trim END
- var valtwo = 222
- export def GetValtwo(): number
- return valtwo
- enddef
- END
- writefile(lines + morelines, 'Xreload.vim')
- source Xreload.vim
- source Xreload.vim
- source Xreload.vim
-
- # cannot declare a var twice
- lines =<< trim END
- vim9script
- var valone = 1234
- var valone = 5678
- END
- writefile(lines, 'Xreload.vim')
- assert_fails('source Xreload.vim', 'E1041:', '', 3, 'Xreload.vim')
-
- delete('Xreload.vim')
- delete('Ximport.vim')
-enddef
-
-" if a script is reloaded with a script-local variable that changed its type, a
-" compiled function using that variable must fail.
-def Test_script_reload_change_type()
- var lines =<< trim END
- vim9script noclear
- var str = 'string'
- def g:GetStr(): string
- return str .. 'xxx'
- enddef
- END
- writefile(lines, 'Xreload.vim')
- source Xreload.vim
- echo g:GetStr()
-
- lines =<< trim END
- vim9script noclear
- var str = 1234
- END
- writefile(lines, 'Xreload.vim')
- source Xreload.vim
- assert_fails('echo g:GetStr()', 'E1150:')
-
- delfunc g:GetStr
- delete('Xreload.vim')
-enddef
-
-" Define CallFunc so that the test can be compiled
-command CallFunc echo 'nop'
-
-def Test_script_reload_from_function()
- var lines =<< trim END
- vim9script
-
- if exists('g:loaded')
- finish
- endif
- g:loaded = 1
- delcommand CallFunc
- command CallFunc Func()
- def Func()
- so XreloadFunc.vim
- g:didTheFunc = 1
- enddef
- END
- writefile(lines, 'XreloadFunc.vim')
- source XreloadFunc.vim
- CallFunc
- assert_equal(1, g:didTheFunc)
-
- delete('XreloadFunc.vim')
- delcommand CallFunc
- unlet g:loaded
- unlet g:didTheFunc
enddef
def Test_script_var_shadows_function()
@@ -1954,98 +1218,6 @@ def Test_vim9script_call_wrong_type()
CheckScriptFailure(lines, 'E1085:')
enddef
-def s:RetSome(): string
- return 'some'
-enddef
-
-" Not exported function that is referenced needs to be accessed by the
-" script-local name.
-def Test_vim9script_funcref()
- var sortlines =<< trim END
- vim9script
- def Compare(i1: number, i2: number): number
- return i2 - i1
- enddef
-
- export def FastSort(): list<number>
- return range(5)->sort(Compare)
- enddef
-
- export def GetString(arg: string): string
- return arg
- enddef
- END
- writefile(sortlines, 'Xsort.vim')
-
- var lines =<< trim END
- vim9script
- import './Xsort.vim'
- def Test()
- g:result = Xsort.FastSort()
- enddef
- Test()
-
- # using a function imported with "as"
- import './Xsort.vim' as anAlias
- assert_equal('yes', anAlias.GetString('yes'))
-
- # using the function from a compiled function
- def TestMore(): string
- var s = s:anAlias.GetString('foo')
- return s .. anAlias.GetString('bar')
- enddef
- assert_equal('foobar', TestMore())
-
- # error when using a function that isn't exported
- assert_fails('anAlias.Compare(1, 2)', 'E1049:')
- END
- writefile(lines, 'Xscript.vim')
-
- source Xscript.vim
- assert_equal([4, 3, 2, 1, 0], g:result)
-
- unlet g:result
- delete('Xsort.vim')
- delete('Xscript.vim')
-
- var Funcref = function('s:RetSome')
- assert_equal('some', Funcref())
-enddef
-
-" Check that when searching for "FilterFunc" it finds the import in the
-" script where FastFilter() is called from, both as a string and as a direct
-" function reference.
-def Test_vim9script_funcref_other_script()
- var filterLines =<< trim END
- vim9script
- export def FilterFunc(idx: number, val: number): bool
- return idx % 2 == 1
- enddef
- export def FastFilter(): list<number>
- return range(10)->filter('FilterFunc(v:key, v:val)')
- enddef
- export def FastFilterDirect(): list<number>
- return range(10)->filter(FilterFunc)
- enddef
- END
- writefile(filterLines, 'Xfilter.vim')
-
- var lines =<< trim END
- vim9script
- import './Xfilter.vim' as filter
- def Test()
- var x: list<number> = filter.FastFilter()
- enddef
- Test()
- def TestDirect()
- var x: list<number> = filter.FastFilterDirect()
- enddef
- TestDirect()
- END
- CheckScriptSuccess(lines)
- delete('Xfilter.vim')
-enddef
-
def Test_vim9script_reload_delfunc()
var first_lines =<< trim END
vim9script
@@ -2109,99 +1281,6 @@ def Test_vim9script_reload_delvar()
delete('XreloadVar.vim')
enddef
-def Test_import_absolute()
- var import_lines = [
- 'vim9script',
- 'import "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim" as abs',
- 'def UseExported()',
- ' g:imported_abs = abs.exported',
- ' abs.exported = 8888',
- ' g:imported_after = abs.exported',
- 'enddef',
- 'UseExported()',
- 'g:import_disassembled = execute("disass UseExported")',
- ]
- writefile(import_lines, 'Ximport_abs.vim')
- writefile(s:export_script_lines, 'Xexport_abs.vim')
-
- source Ximport_abs.vim
-
- assert_equal(9876, g:imported_abs)
- assert_equal(8888, g:imported_after)
- assert_match('<SNR>\d\+_UseExported\_s*' ..
- 'g:imported_abs = abs.exported\_s*' ..
- '0 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
- '1 STOREG g:imported_abs\_s*' ..
- 'abs.exported = 8888\_s*' ..
- '2 PUSHNR 8888\_s*' ..
- '3 STORESCRIPT exported-2 in .*Xexport_abs.vim\_s*' ..
- 'g:imported_after = abs.exported\_s*' ..
- '4 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
- '5 STOREG g:imported_after',
- g:import_disassembled)
-
- Undo_export_script_lines()
- unlet g:imported_abs
- unlet g:import_disassembled
-
- delete('Ximport_abs.vim')
- delete('Xexport_abs.vim')
-enddef
-
-def Test_import_rtp()
- var import_lines = [
- 'vim9script',
- 'import "Xexport_rtp.vim" as rtp',
- 'g:imported_rtp = rtp.exported',
- ]
- writefile(import_lines, 'Ximport_rtp.vim')
- mkdir('import', 'p')
- writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
-
- var save_rtp = &rtp
- &rtp = getcwd()
- source Ximport_rtp.vim
- &rtp = save_rtp
-
- assert_equal(9876, g:imported_rtp)
-
- Undo_export_script_lines()
- unlet g:imported_rtp
- delete('Ximport_rtp.vim')
- delete('import', 'rf')
-enddef
-
-def Test_import_compile_error()
- var export_lines = [
- 'vim9script',
- 'export def ExpFunc(): string',
- ' return notDefined',
- 'enddef',
- ]
- writefile(export_lines, 'Xexported.vim')
-
- var import_lines = [
- 'vim9script',
- 'import "./Xexported.vim" as expo',
- 'def ImpFunc()',
- ' echo expo.ExpFunc()',
- 'enddef',
- 'defcompile',
- ]
- writefile(import_lines, 'Ximport.vim')
-
- try
- source Ximport.vim
- catch /E1001/
- # Error should be before the Xexported.vim file.
- assert_match('E1001: Variable not found: notDefined', v:exception)
- assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
- endtry
-
- delete('Xexported.vim')
- delete('Ximport.vim')
-enddef
-
def Test_func_redefine_error()
var lines = [
'vim9script',
@@ -2225,39 +1304,6 @@ def Test_func_redefine_error()
delete('Xtestscript.vim')
enddef
-def Test_func_overrules_import_fails()
- var export_lines =<< trim END
- vim9script
- export def Func()
- echo 'imported'
- enddef
- END
- writefile(export_lines, 'XexportedFunc.vim')
-
- var lines =<< trim END
- vim9script
- import './XexportedFunc.vim' as Func
- def Func()
- echo 'local to function'
- enddef
- END
- CheckScriptFailure(lines, 'E1236:')
-
- lines =<< trim END
- vim9script
- import './XexportedFunc.vim' as Func
- def Outer()
- def Func()
- echo 'local to function'
- enddef
- enddef
- defcompile
- END
- CheckScriptFailure(lines, 'E1236:')
-
- delete('XexportedFunc.vim')
-enddef
-
def Test_func_redefine_fails()
var lines =<< trim END
vim9script
@@ -3877,47 +2923,6 @@ def Test_forward_declaration()
delete('Xforward')
enddef
-def Test_source_vim9_from_legacy()
- var vim9_lines =<< trim END
- vim9script
- var local = 'local'
- g:global = 'global'
- export var exported = 'exported'
- export def GetText(): string
- return 'text'
- enddef
- END
- writefile(vim9_lines, 'Xvim9_script.vim')
-
- var legacy_lines =<< trim END
- source Xvim9_script.vim
-
- call assert_false(exists('local'))
- call assert_false(exists('exported'))
- call assert_false(exists('s:exported'))
- call assert_equal('global', global)
- call assert_equal('global', g:global)
-
- "" imported variable becomes script-local
- "import exported from './Xvim9_script.vim'
- "call assert_equal('exported', s:exported)
- "call assert_false(exists('exported'))
-
- "" imported function becomes script-local
- "import GetText from './Xvim9_script.vim'
- "call assert_equal('text', s:GetText())
- "call assert_false(exists('*GetText'))
- END
- writefile(legacy_lines, 'Xlegacy_script.vim')
-
- source Xlegacy_script.vim
- assert_equal('global', g:global)
- unlet g:global
-
- delete('Xlegacy_script.vim')
- delete('Xvim9_script.vim')
-enddef
-
def Test_declare_script_in_func()
var lines =<< trim END
vim9script
@@ -4194,38 +3199,6 @@ def Test_error_in_autoload_script()
delete(dir, 'rf')
enddef
-def Test_cmdline_win()
- # if the Vim syntax highlighting uses Vim9 constructs they can be used from
- # the command line window.
- mkdir('rtp/syntax', 'p')
- var export_lines =<< trim END
- vim9script
- export var That = 'yes'
- END
- writefile(export_lines, 'rtp/syntax/Xexport.vim')
- var import_lines =<< trim END
- vim9script
- import './Xexport.vim' as exp
- echo exp.That
- END
- writefile(import_lines, 'rtp/syntax/vim.vim')
- var save_rtp = &rtp
- &rtp = getcwd() .. '/rtp' .. ',' .. &rtp
- syntax on
- augroup CmdWin
- autocmd CmdwinEnter * g:got_there = 'yes'
- augroup END
- # this will open and also close the cmdline window
- feedkeys('q:', 'xt')
- assert_equal('yes', g:got_there)
-
- augroup CmdWin
- au!
- augroup END
- &rtp = save_rtp
- delete('rtp', 'rf')
-enddef
-
def Test_invalid_sid()
assert_fails('func <SNR>1234_func', 'E123:')
@@ -4552,37 +3525,6 @@ def Test_script_var_gone_when_sourced_twice()
unlet g:guard
enddef
-"def Test_import_gone_when_sourced_twice()
-" var exportlines =<< trim END
-" vim9script
-" if exists('g:guard')
-" finish
-" endif
-" g:guard = 1
-" export var name = 'someName'
-" END
-" writefile(exportlines, 'XexportScript.vim')
-"
-" var lines =<< trim END
-" vim9script
-" import name from './XexportScript.vim'
-" def g:GetName(): string
-" return name
-" enddef
-" END
-" writefile(lines, 'XscriptImport.vim')
-" so XscriptImport.vim
-" assert_equal('someName', g:GetName())
-"
-" so XexportScript.vim
-" assert_fails('call g:GetName()', 'E1149:')
-"
-" delfunc g:GetName
-" delete('XexportScript.vim')
-" delete('XscriptImport.vim')
-" unlet g:guard
-"enddef
-
def Test_unsupported_commands()
var lines =<< trim END
ka
diff --git a/src/version.c b/src/version.c
index 44d849ef5..e86bd1033 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4036,
+/**/
4035,
/**/
4034,