summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 02:10:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 02:10:58 +0000
commitbee19c22d569e54513a9c591441c7f411811dc81 (patch)
treeb990d2df9fddb8194bfe49e9205005a0d952bc1f /src
parentAdding upstream version 2:9.1.0199. (diff)
downloadvim-bee19c22d569e54513a9c591441c7f411811dc81.tar.xz
vim-bee19c22d569e54513a9c591441c7f411811dc81.zip
Adding upstream version 2:9.1.0374.upstream/2%9.1.0374
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src')
-rw-r--r--src/Make_mvc.mak55
-rw-r--r--src/Makefile10
-rwxr-xr-xsrc/auto/configure8
-rw-r--r--src/autocmd.c422
-rw-r--r--src/buffer.c6
-rw-r--r--src/change.c3
-rw-r--r--src/charset.c41
-rw-r--r--src/clientserver.c8
-rw-r--r--src/configure.ac6
-rw-r--r--src/dict.c6
-rw-r--r--src/dosinst.c2
-rw-r--r--src/drawline.c74
-rw-r--r--src/edit.c95
-rw-r--r--src/errors.h46
-rw-r--r--src/eval.c164
-rw-r--r--src/evalfunc.c35
-rw-r--r--src/evalvars.c141
-rw-r--r--src/ex_cmds.c2
-rw-r--r--src/ex_cmds.h5
-rw-r--r--src/ex_cmds2.c25
-rw-r--r--src/ex_docmd.c339
-rw-r--r--src/fileio.c8
-rw-r--r--src/filepath.c1
-rw-r--r--src/getchar.c175
-rw-r--r--src/globals.h23
-rw-r--r--src/gui_gtk_x11.c3
-rw-r--r--src/gui_motif.c3
-rw-r--r--src/highlight.c295
-rw-r--r--src/indent.c4
-rw-r--r--src/insexpand.c2
-rw-r--r--src/main.c6
-rw-r--r--src/map.c3
-rw-r--r--src/match.c4
-rw-r--r--src/mbyte.c15
-rw-r--r--src/memline.c3
-rw-r--r--src/message.c43
-rw-r--r--src/misc1.c17
-rw-r--r--src/misc2.c42
-rw-r--r--src/mouse.c2
-rw-r--r--src/move.c900
-rw-r--r--src/normal.c110
-rw-r--r--src/ops.c113
-rw-r--r--src/option.c68
-rw-r--r--src/optiondefs.h3
-rw-r--r--src/optionstr.c2
-rw-r--r--src/os_unix.c15
-rw-r--r--src/os_unix.h18
-rw-r--r--src/po/Make_mvc.mak2
-rw-r--r--src/po/check.vim9
-rw-r--r--src/po/ru.cp1251.po127
-rw-r--r--src/po/ru.po127
-rw-r--r--src/po/sr.po88
-rw-r--r--src/popupwin.c2
-rw-r--r--src/proto/charset.pro1
-rw-r--r--src/proto/eval.pro6
-rw-r--r--src/proto/evalvars.pro1
-rw-r--r--src/proto/mbyte.pro1
-rw-r--r--src/proto/misc2.pro4
-rw-r--r--src/proto/move.pro5
-rw-r--r--src/proto/normal.pro3
-rw-r--r--src/proto/scriptfile.pro1
-rw-r--r--src/proto/vim9class.pro1
-rw-r--r--src/proto/vim9instr.pro2
-rw-r--r--src/proto/window.pro1
-rw-r--r--src/quickfix.c4
-rw-r--r--src/regexp_bt.c2
-rw-r--r--src/regexp_nfa.c4
-rw-r--r--src/screen.c16
-rw-r--r--src/scriptfile.c62
-rw-r--r--src/session.c2
-rw-r--r--src/structs.h40
-rw-r--r--src/tag.c22
-rw-r--r--src/term.c2
-rw-r--r--src/termdefs.h6
-rw-r--r--src/testdir/Make_all.mak5
-rw-r--r--src/testdir/Makefile2
-rw-r--r--src/testdir/dumps/Test_ambiwidth_hl_dump_1.dump6
-rw-r--r--src/testdir/dumps/Test_ambiwidth_hl_dump_2.dump6
-rw-r--r--src/testdir/dumps/Test_display_visual_block_scroll.dump10
-rw-r--r--src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_1.dump16
-rw-r--r--src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_2.dump16
-rw-r--r--src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_3.dump16
-rw-r--r--src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_4.dump16
-rw-r--r--src/testdir/dumps/Test_props_with_text_truncated_just_before_after_1.dump8
-rw-r--r--src/testdir/dumps/Test_props_with_text_truncated_just_before_after_2.dump8
-rw-r--r--src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_1.dump6
-rw-r--r--src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_2.dump6
-rw-r--r--src/testdir/dumps/Test_smooth_long_6.dump2
-rw-r--r--src/testdir/dumps/Test_smooth_long_7.dump2
-rw-r--r--src/testdir/test_autocmd.vim351
-rw-r--r--src/testdir/test_buffer.vim23
-rw-r--r--src/testdir/test_cmdline.vim23
-rw-r--r--src/testdir/test_cmdmods.vim6
-rw-r--r--src/testdir/test_codestyle.vim8
-rw-r--r--src/testdir/test_compiler.vim4
-rw-r--r--src/testdir/test_conceal.vim1
-rw-r--r--src/testdir/test_diffmode.vim62
-rw-r--r--src/testdir/test_digraph.vim4
-rw-r--r--src/testdir/test_edit.vim156
-rw-r--r--src/testdir/test_expr.vim16
-rw-r--r--src/testdir/test_filechanged.vim34
-rw-r--r--src/testdir/test_filetype.vim106
-rw-r--r--src/testdir/test_functions.vim37
-rw-r--r--src/testdir/test_highlight.vim9
-rw-r--r--src/testdir/test_history.vim2
-rw-r--r--src/testdir/test_ins_complete.vim24
-rw-r--r--src/testdir/test_let.vim132
-rw-r--r--src/testdir/test_listdict.vim6
-rw-r--r--src/testdir/test_mapping.vim67
-rw-r--r--src/testdir/test_match.vim2
-rw-r--r--src/testdir/test_mksession.vim4
-rw-r--r--src/testdir/test_normal.vim93
-rw-r--r--src/testdir/test_put.vim17
-rw-r--r--src/testdir/test_recover.vim2
-rw-r--r--src/testdir/test_regexp_latin.vim14
-rw-r--r--src/testdir/test_regexp_utf8.vim2
-rw-r--r--src/testdir/test_registers.vim69
-rw-r--r--src/testdir/test_remote.vim45
-rw-r--r--src/testdir/test_scroll_opt.vim116
-rw-r--r--src/testdir/test_sound.vim2
-rw-r--r--src/testdir/test_tabpage.vim8
-rw-r--r--src/testdir/test_taglist.vim5
-rw-r--r--src/testdir/test_terminal3.vim20
-rw-r--r--src/testdir/test_textformat.vim9
-rw-r--r--src/testdir/test_textprop.vim79
-rw-r--r--src/testdir/test_utf8.vim121
-rw-r--r--src/testdir/test_vim9_assign.vim106
-rw-r--r--src/testdir/test_vim9_builtin.vim2232
-rw-r--r--src/testdir/test_vim9_class.vim236
-rw-r--r--src/testdir/test_vim9_disassemble.vim30
-rw-r--r--src/testdir/test_vim9_enum.vim1537
-rw-r--r--src/testdir/test_vim9_func.vim31
-rw-r--r--src/testdir/test_vim9_import.vim243
-rw-r--r--src/testdir/test_vim9_script.vim130
-rw-r--r--src/testdir/test_visual.vim2
-rw-r--r--src/testdir/test_winfixbuf.vim415
-rw-r--r--src/testdir/test_xdg.vim295
-rw-r--r--src/testdir/vim9.vim208
-rw-r--r--src/testing.c11
-rw-r--r--src/textformat.c6
-rw-r--r--src/textprop.c8
-rw-r--r--src/typval.c16
-rw-r--r--src/userfunc.c53
-rw-r--r--src/version.c363
-rw-r--r--src/version.h17
-rw-r--r--src/vim.h17
-rw-r--r--src/vim9.h10
-rw-r--r--src/vim9class.c550
-rw-r--r--src/vim9cmds.c4
-rw-r--r--src/vim9compile.c758
-rw-r--r--src/vim9execute.c33
-rw-r--r--src/vim9expr.c21
-rw-r--r--src/vim9instr.c23
-rw-r--r--src/vim9script.c25
-rw-r--r--src/vim9type.c1272
-rw-r--r--src/window.c10
156 files changed, 10360 insertions, 4018 deletions
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index 4db2298..4d03a72 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -157,10 +157,55 @@
# you can set DEFINES on the command line, e.g.,
# nmake -f Make_mvc.mvc "DEFINES=-DEMACS_TAGS"
+RM= del /f /q
+PS= powershell.exe
+
+PSFLAGS= -NoLogo -NoProfile -Command
+
+!IF ![$(PS) $(PSFLAGS) try{Out-File -FilePath '.\major.tmp' -InputObject \
+ \"MAJOR=$$(((Select-String -Pattern 'VIM_VERSION_MAJOR\s+\d{1,2}' \
+ -Path '.\version.h').Line[-2..-1^]-join '').Trim())\"} \
+ catch{exit 1}]
+! INCLUDE .\major.tmp
+! IF [$(RM) .\major.tmp]
+! ENDIF
+!ELSE
+# Change this value for the new version
+MAJOR= 9
+!ENDIF
+
+!IF ![$(PS) $(PSFLAGS) try{Out-File -FilePath '.\minor.tmp' -InputObject \
+ \"MINOR=$$(((Select-String -Pattern 'VIM_VERSION_MINOR\s+\d{1,2}' \
+ -Path '.\version.h').Line[-2..-1^]-join '').Trim())\"} \
+ catch{exit 1}]
+! INCLUDE .\minor.tmp
+! IF [$(RM) .\minor.tmp]
+! ENDIF
+!ELSE
+# Change this value for the new version
+MINOR= 1
+!ENDIF
+
+!IF ![$(PS) $(PSFLAGS) try{Out-File -FilePath '.\patchlvl.tmp' -InputObject \
+ \"PATCHLEVEL=$$([decimal^]((Get-Content -Path '.\version.c' \
+ -TotalCount ((Select-String -Pattern 'static int included_patches' \
+ -Path '.\version.c').LineNumber+3))[-1^]).Trim().TrimEnd(','))\"} \
+ catch{exit 1}]
+! INCLUDE .\patchlvl.tmp
+! IF [$(RM) .\patchlvl.tmp]
+! ENDIF
+!ENDIF
+
+
# Build on Windows NT/XP
TARGETOS = WINNT
+!IFDEF PATCHLEVEL
+RCFLAGS= -DVIM_VERSION_PATCHLEVEL=$(PATCHLEVEL)
+!ENDIF
+
+
!if "$(VIMDLL)" == "yes"
GUI = yes
!endif
@@ -591,7 +636,7 @@ OPTFLAG = $(OPTFLAG) /GL
! endif
CFLAGS = $(CFLAGS) $(OPTFLAG) -DNDEBUG $(CPUARG)
-RCFLAGS = -DNDEBUG
+RCFLAGS = $(RCFLAGS) -DNDEBUG
! ifdef USE_MSVCRT
CFLAGS = $(CFLAGS) /MD
LIBC = msvcrt.lib
@@ -607,7 +652,7 @@ VIM = vimd
DEBUGINFO = /ZI
! endif
CFLAGS = $(CFLAGS) -D_DEBUG -DDEBUG /Od
-RCFLAGS = -D_DEBUG -DDEBUG
+RCFLAGS = $(RCFLAGS) -D_DEBUG -DDEBUG
# The /fixed:no is needed for Quantify.
LIBC = /fixed:no
! ifdef USE_MSVCRT
@@ -621,7 +666,7 @@ LIBC = $(LIBC) libcmtd.lib
!endif # DEBUG
# Visual Studio 2005 has 'deprecated' many of the standard CRT functions
-CFLAGS_DEPR = /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE
+CFLAGS_DEPR = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
CFLAGS = $(CFLAGS) $(CFLAGS_DEPR)
!include Make_all.mak
@@ -1276,6 +1321,10 @@ $(OUTDIR):
CFLAGS_INST = /nologo /O2 -DNDEBUG -DWIN32 -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) $(CFLAGS_DEPR)
+!IFDEF PATCHLEVEL
+CFLAGS_INST= $(CFLAGS_INST) -DVIM_VERSION_PATCHLEVEL=$(PATCHLEVEL)
+!ENDIF
+
install.exe: dosinst.c dosinst.h version.h
$(CC) $(CFLAGS_INST) dosinst.c kernel32.lib shell32.lib \
user32.lib ole32.lib advapi32.lib uuid.lib \
diff --git a/src/Makefile b/src/Makefile
index 33903d3..29f63dc 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2341,6 +2341,7 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(VIMTARGET) $(DEST_RT) \
$(DEST_SYN) $(DEST_SYN)/modula2 $(DEST_SYN)/modula2/opt $(DEST_SYN)/shared \
$(DEST_IND) $(DEST_FTP) \
$(DEST_AUTO) $(DEST_AUTO)/dist $(DEST_AUTO)/xml $(DEST_AUTO)/zig \
+ $(DEST_AUTO)/rust $(DEST_AUTO)/cargo \
$(DEST_IMPORT) $(DEST_IMPORT)/dist \
$(DEST_PLUG) $(DEST_TUTOR) $(DEST_SPELL) $(DEST_COMP)
-$(SHELL) ./installman.sh install $(DEST_MAN) "" $(INSTALLMANARGS)
@@ -2428,6 +2429,10 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(VIMTARGET) $(DEST_RT) \
cd $(DEST_AUTO)/xml; chmod $(HELPMOD) *.vim
cd $(AUTOSOURCE)/zig; $(INSTALL_DATA) *.vim $(DEST_AUTO)/zig
cd $(DEST_AUTO)/zig; chmod $(HELPMOD) *.vim
+ cd $(AUTOSOURCE)/cargo; $(INSTALL_DATA) *.vim $(DEST_AUTO)/cargo
+ cd $(DEST_AUTO)/cargo; chmod $(HELPMOD) *.vim
+ cd $(AUTOSOURCE)/rust; $(INSTALL_DATA) *.vim $(DEST_AUTO)/rust
+ cd $(DEST_AUTO)/rust; chmod $(HELPMOD) *.vim
# install the standard import files
cd $(IMPORTSOURCE)/dist; $(INSTALL_DATA) *.vim $(DEST_IMPORT)/dist
cd $(DEST_IMPORT)/dist; chmod $(HELPMOD) *.vim
@@ -2669,6 +2674,7 @@ $(DESTDIR)$(exec_prefix) $(DEST_BIN) \
$(DEST_LANG) $(DEST_KMAP) $(DEST_COMP) $(DEST_MACRO) \
$(DEST_PACK) $(DEST_TOOLS) $(DEST_TUTOR) $(DEST_SPELL) \
$(DEST_AUTO) $(DEST_AUTO)/dist $(DEST_AUTO)/xml $(DEST_AUTO)/zig \
+ $(DEST_AUTO)/cargo $(DEST_AUTO)/rust \
$(DEST_IMPORT) $(DEST_IMPORT)/dist $(DEST_PLUG):
$(MKDIR_P) $@
-chmod $(DIRMOD) $@
@@ -2859,10 +2865,10 @@ uninstall_runtime:
-rmdir $(DEST_SYN) $(DEST_IND)
-rm -rf $(DEST_FTP)/*.vim $(DEST_FTP)/README.txt $(DEST_FTP)/logtalk.dict
-rm -f $(DEST_AUTO)/*.vim $(DEST_AUTO)/README.txt
- -rm -f $(DEST_AUTO)/dist/*.vim $(DEST_AUTO)/xml/*.vim $(DEST_AUTO)/zig/*.vim
+ -rm -f $(DEST_AUTO)/dist/*.vim $(DEST_AUTO)/xml/*.vim $(DEST_AUTO)/zig/*.vim $(DEST_AUTO)/cargo/*.vim $(DEST_AUTO)/rust/*.vim
-rm -f $(DEST_IMPORT)/dist/*.vim
-rm -f $(DEST_PLUG)/*.vim $(DEST_PLUG)/README.txt
- -rmdir $(DEST_FTP) $(DEST_AUTO)/dist $(DEST_AUTO)/xml $(DEST_AUTO)/zig $(DEST_AUTO)
+ -rmdir $(DEST_FTP) $(DEST_AUTO)/dist $(DEST_AUTO)/xml $(DEST_AUTO)/zig $(DEST_AUTO)/cargo $(DEST_AUTO)/rust $(DEST_AUTO)
-rmdir $(DEST_IMPORT)/dist $(DEST_IMPORT)
-rmdir $(DEST_PLUG) $(DEST_RT)
# This will fail when other Vim versions are installed, no worries.
diff --git a/src/auto/configure b/src/auto/configure
index 9712104..0e0cf8e 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -15965,16 +15965,16 @@ printf "%s\n" "yes" >&6; }
printf "%s\n" "no" >&6; }
fi
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if msgfmt supports --no-convert" >&5
-printf %s "checking if msgfmt supports --no-convert... " >&6; }
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MSGFMT supports --no-convert" >&5
+printf %s "checking if $MSGFMT supports --no-convert... " >&6; }
if "$MSGFMT" --help | grep -q -- '--no-convert' >/dev/null; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
- MSGFMTCMD="OLD_PO_FILE_INPUT=yes msgfmt --no-convert -v"
+ MSGFMTCMD="OLD_PO_FILE_INPUT=yes $MSGFMT --no-convert -v"
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
- MSGFMTCMD="OLD_PO_FILE_INPUT=yes msgfmt -v"
+ MSGFMTCMD="OLD_PO_FILE_INPUT=yes $MSGFMT -v"
fi
fi
diff --git a/src/autocmd.c b/src/autocmd.c
index 8e43b34..bce57cb 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -74,152 +74,166 @@ typedef struct AutoPat
char last; // last pattern for apply_autocmds()
} AutoPat;
-static struct event_name
-{
- char *name; // event name
- event_T event; // event number
-} event_names[] =
-{
- {"BufAdd", EVENT_BUFADD},
- {"BufCreate", EVENT_BUFADD},
- {"BufDelete", EVENT_BUFDELETE},
- {"BufEnter", EVENT_BUFENTER},
- {"BufFilePost", EVENT_BUFFILEPOST},
- {"BufFilePre", EVENT_BUFFILEPRE},
- {"BufHidden", EVENT_BUFHIDDEN},
- {"BufLeave", EVENT_BUFLEAVE},
- {"BufNew", EVENT_BUFNEW},
- {"BufNewFile", EVENT_BUFNEWFILE},
- {"BufRead", EVENT_BUFREADPOST},
- {"BufReadCmd", EVENT_BUFREADCMD},
- {"BufReadPost", EVENT_BUFREADPOST},
- {"BufReadPre", EVENT_BUFREADPRE},
- {"BufUnload", EVENT_BUFUNLOAD},
- {"BufWinEnter", EVENT_BUFWINENTER},
- {"BufWinLeave", EVENT_BUFWINLEAVE},
- {"BufWipeout", EVENT_BUFWIPEOUT},
- {"BufWrite", EVENT_BUFWRITEPRE},
- {"BufWritePost", EVENT_BUFWRITEPOST},
- {"BufWritePre", EVENT_BUFWRITEPRE},
- {"BufWriteCmd", EVENT_BUFWRITECMD},
- {"CmdlineChanged", EVENT_CMDLINECHANGED},
- {"CmdlineEnter", EVENT_CMDLINEENTER},
- {"CmdlineLeave", EVENT_CMDLINELEAVE},
- {"CmdwinEnter", EVENT_CMDWINENTER},
- {"CmdwinLeave", EVENT_CMDWINLEAVE},
- {"CmdUndefined", EVENT_CMDUNDEFINED},
- {"ColorScheme", EVENT_COLORSCHEME},
- {"ColorSchemePre", EVENT_COLORSCHEMEPRE},
- {"CompleteChanged", EVENT_COMPLETECHANGED},
- {"CompleteDone", EVENT_COMPLETEDONE},
- {"CompleteDonePre", EVENT_COMPLETEDONEPRE},
- {"CursorHold", EVENT_CURSORHOLD},
- {"CursorHoldI", EVENT_CURSORHOLDI},
- {"CursorMoved", EVENT_CURSORMOVED},
- {"CursorMovedI", EVENT_CURSORMOVEDI},
- {"DiffUpdated", EVENT_DIFFUPDATED},
- {"DirChanged", EVENT_DIRCHANGED},
- {"DirChangedPre", EVENT_DIRCHANGEDPRE},
- {"EncodingChanged", EVENT_ENCODINGCHANGED},
- {"ExitPre", EVENT_EXITPRE},
- {"FileEncoding", EVENT_ENCODINGCHANGED},
- {"FileAppendPost", EVENT_FILEAPPENDPOST},
- {"FileAppendPre", EVENT_FILEAPPENDPRE},
- {"FileAppendCmd", EVENT_FILEAPPENDCMD},
- {"FileChangedShell",EVENT_FILECHANGEDSHELL},
- {"FileChangedShellPost",EVENT_FILECHANGEDSHELLPOST},
- {"FileChangedRO", EVENT_FILECHANGEDRO},
- {"FileReadPost", EVENT_FILEREADPOST},
- {"FileReadPre", EVENT_FILEREADPRE},
- {"FileReadCmd", EVENT_FILEREADCMD},
- {"FileType", EVENT_FILETYPE},
- {"FileWritePost", EVENT_FILEWRITEPOST},
- {"FileWritePre", EVENT_FILEWRITEPRE},
- {"FileWriteCmd", EVENT_FILEWRITECMD},
- {"FilterReadPost", EVENT_FILTERREADPOST},
- {"FilterReadPre", EVENT_FILTERREADPRE},
- {"FilterWritePost", EVENT_FILTERWRITEPOST},
- {"FilterWritePre", EVENT_FILTERWRITEPRE},
- {"FocusGained", EVENT_FOCUSGAINED},
- {"FocusLost", EVENT_FOCUSLOST},
- {"FuncUndefined", EVENT_FUNCUNDEFINED},
- {"GUIEnter", EVENT_GUIENTER},
- {"GUIFailed", EVENT_GUIFAILED},
- {"InsertChange", EVENT_INSERTCHANGE},
- {"InsertEnter", EVENT_INSERTENTER},
- {"InsertLeave", EVENT_INSERTLEAVE},
- {"InsertLeavePre", EVENT_INSERTLEAVEPRE},
- {"InsertCharPre", EVENT_INSERTCHARPRE},
- {"MenuPopup", EVENT_MENUPOPUP},
- {"ModeChanged", EVENT_MODECHANGED},
- {"OptionSet", EVENT_OPTIONSET},
- {"QuickFixCmdPost", EVENT_QUICKFIXCMDPOST},
- {"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE},
- {"QuitPre", EVENT_QUITPRE},
- {"RemoteReply", EVENT_REMOTEREPLY},
- {"SafeState", EVENT_SAFESTATE},
- {"SafeStateAgain", EVENT_SAFESTATEAGAIN},
- {"SessionLoadPost", EVENT_SESSIONLOADPOST},
- {"ShellCmdPost", EVENT_SHELLCMDPOST},
- {"ShellFilterPost", EVENT_SHELLFILTERPOST},
- {"SigUSR1", EVENT_SIGUSR1},
- {"SourceCmd", EVENT_SOURCECMD},
- {"SourcePre", EVENT_SOURCEPRE},
- {"SourcePost", EVENT_SOURCEPOST},
- {"SpellFileMissing",EVENT_SPELLFILEMISSING},
- {"StdinReadPost", EVENT_STDINREADPOST},
- {"StdinReadPre", EVENT_STDINREADPRE},
- {"SwapExists", EVENT_SWAPEXISTS},
- {"Syntax", EVENT_SYNTAX},
- {"TabNew", EVENT_TABNEW},
- {"TabClosed", EVENT_TABCLOSED},
- {"TabEnter", EVENT_TABENTER},
- {"TabLeave", EVENT_TABLEAVE},
- {"TermChanged", EVENT_TERMCHANGED},
- {"TerminalOpen", EVENT_TERMINALOPEN},
- {"TerminalWinOpen", EVENT_TERMINALWINOPEN},
- {"TermResponse", EVENT_TERMRESPONSE},
- {"TermResponseAll", EVENT_TERMRESPONSEALL},
- {"TextChanged", EVENT_TEXTCHANGED},
- {"TextChangedI", EVENT_TEXTCHANGEDI},
- {"TextChangedP", EVENT_TEXTCHANGEDP},
- {"TextChangedT", EVENT_TEXTCHANGEDT},
- {"User", EVENT_USER},
- {"VimEnter", EVENT_VIMENTER},
- {"VimLeave", EVENT_VIMLEAVE},
- {"VimLeavePre", EVENT_VIMLEAVEPRE},
- {"WinNewPre", EVENT_WINNEWPRE},
- {"WinNew", EVENT_WINNEW},
- {"WinClosed", EVENT_WINCLOSED},
- {"WinEnter", EVENT_WINENTER},
- {"WinLeave", EVENT_WINLEAVE},
- {"WinResized", EVENT_WINRESIZED},
- {"WinScrolled", EVENT_WINSCROLLED},
- {"VimResized", EVENT_VIMRESIZED},
- {"TextYankPost", EVENT_TEXTYANKPOST},
- {"VimSuspend", EVENT_VIMSUSPEND},
- {"VimResume", EVENT_VIMRESUME},
- {NULL, (event_T)0}
+//
+// special cases:
+// BufNewFile and BufRead are searched for ALOT (especially at startup)
+// so we pre-determine their index into the event_tab[] table for fast access.
+// Keep these values in sync with event_tab[]!
+#define BUFNEWFILE_INDEX 9
+#define BUFREAD_INDEX 10
+
+// must be sorted by the 'value' field because it is used by bsearch()!
+static keyvalue_T event_tab[] = {
+ KEYVALUE_ENTRY(EVENT_BUFADD, "BufAdd"),
+ KEYVALUE_ENTRY(EVENT_BUFADD, "BufCreate"),
+ KEYVALUE_ENTRY(EVENT_BUFDELETE, "BufDelete"),
+ KEYVALUE_ENTRY(EVENT_BUFENTER, "BufEnter"),
+ KEYVALUE_ENTRY(EVENT_BUFFILEPOST, "BufFilePost"),
+ KEYVALUE_ENTRY(EVENT_BUFFILEPRE, "BufFilePre"),
+ KEYVALUE_ENTRY(EVENT_BUFHIDDEN, "BufHidden"),
+ KEYVALUE_ENTRY(EVENT_BUFLEAVE, "BufLeave"),
+ KEYVALUE_ENTRY(EVENT_BUFNEW, "BufNew"),
+ KEYVALUE_ENTRY(EVENT_BUFNEWFILE, "BufNewFile"), // BUFNEWFILE_INDEX
+ KEYVALUE_ENTRY(EVENT_BUFREADPOST, "BufRead"), // BUFREAD_INDEX
+ KEYVALUE_ENTRY(EVENT_BUFREADCMD, "BufReadCmd"),
+ KEYVALUE_ENTRY(EVENT_BUFREADPOST, "BufReadPost"),
+ KEYVALUE_ENTRY(EVENT_BUFREADPRE, "BufReadPre"),
+ KEYVALUE_ENTRY(EVENT_BUFUNLOAD, "BufUnload"),
+ KEYVALUE_ENTRY(EVENT_BUFWINENTER, "BufWinEnter"),
+ KEYVALUE_ENTRY(EVENT_BUFWINLEAVE, "BufWinLeave"),
+ KEYVALUE_ENTRY(EVENT_BUFWIPEOUT, "BufWipeout"),
+ KEYVALUE_ENTRY(EVENT_BUFWRITEPRE, "BufWrite"),
+ KEYVALUE_ENTRY(EVENT_BUFWRITECMD, "BufWriteCmd"),
+ KEYVALUE_ENTRY(EVENT_BUFWRITEPOST, "BufWritePost"),
+ KEYVALUE_ENTRY(EVENT_BUFWRITEPRE, "BufWritePre"),
+ KEYVALUE_ENTRY(EVENT_CMDLINECHANGED, "CmdlineChanged"),
+ KEYVALUE_ENTRY(EVENT_CMDLINEENTER, "CmdlineEnter"),
+ KEYVALUE_ENTRY(EVENT_CMDLINELEAVE, "CmdlineLeave"),
+ KEYVALUE_ENTRY(EVENT_CMDUNDEFINED, "CmdUndefined"),
+ KEYVALUE_ENTRY(EVENT_CMDWINENTER, "CmdwinEnter"),
+ KEYVALUE_ENTRY(EVENT_CMDWINLEAVE, "CmdwinLeave"),
+ KEYVALUE_ENTRY(EVENT_COLORSCHEME, "ColorScheme"),
+ KEYVALUE_ENTRY(EVENT_COLORSCHEMEPRE, "ColorSchemePre"),
+ KEYVALUE_ENTRY(EVENT_COMPLETECHANGED, "CompleteChanged"),
+ KEYVALUE_ENTRY(EVENT_COMPLETEDONE, "CompleteDone"),
+ KEYVALUE_ENTRY(EVENT_COMPLETEDONEPRE, "CompleteDonePre"),
+ KEYVALUE_ENTRY(EVENT_CURSORHOLD, "CursorHold"),
+ KEYVALUE_ENTRY(EVENT_CURSORHOLDI, "CursorHoldI"),
+ KEYVALUE_ENTRY(EVENT_CURSORMOVED, "CursorMoved"),
+ KEYVALUE_ENTRY(EVENT_CURSORMOVEDI, "CursorMovedI"),
+ KEYVALUE_ENTRY(EVENT_DIFFUPDATED, "DiffUpdated"),
+ KEYVALUE_ENTRY(EVENT_DIRCHANGED, "DirChanged"),
+ KEYVALUE_ENTRY(EVENT_DIRCHANGEDPRE, "DirChangedPre"),
+ KEYVALUE_ENTRY(EVENT_ENCODINGCHANGED, "EncodingChanged"),
+ KEYVALUE_ENTRY(EVENT_EXITPRE, "ExitPre"),
+ KEYVALUE_ENTRY(EVENT_FILEAPPENDCMD, "FileAppendCmd"),
+ KEYVALUE_ENTRY(EVENT_FILEAPPENDPOST, "FileAppendPost"),
+ KEYVALUE_ENTRY(EVENT_FILEAPPENDPRE, "FileAppendPre"),
+ KEYVALUE_ENTRY(EVENT_FILECHANGEDRO, "FileChangedRO"),
+ KEYVALUE_ENTRY(EVENT_FILECHANGEDSHELL, "FileChangedShell"),
+ KEYVALUE_ENTRY(EVENT_FILECHANGEDSHELLPOST, "FileChangedShellPost"),
+ KEYVALUE_ENTRY(EVENT_ENCODINGCHANGED, "FileEncoding"),
+ KEYVALUE_ENTRY(EVENT_FILEREADCMD, "FileReadCmd"),
+ KEYVALUE_ENTRY(EVENT_FILEREADPOST, "FileReadPost"),
+ KEYVALUE_ENTRY(EVENT_FILEREADPRE, "FileReadPre"),
+ KEYVALUE_ENTRY(EVENT_FILETYPE, "FileType"),
+ KEYVALUE_ENTRY(EVENT_FILEWRITECMD, "FileWriteCmd"),
+ KEYVALUE_ENTRY(EVENT_FILEWRITEPOST, "FileWritePost"),
+ KEYVALUE_ENTRY(EVENT_FILEWRITEPRE, "FileWritePre"),
+ KEYVALUE_ENTRY(EVENT_FILTERREADPOST, "FilterReadPost"),
+ KEYVALUE_ENTRY(EVENT_FILTERREADPRE, "FilterReadPre"),
+ KEYVALUE_ENTRY(EVENT_FILTERWRITEPOST, "FilterWritePost"),
+ KEYVALUE_ENTRY(EVENT_FILTERWRITEPRE, "FilterWritePre"),
+ KEYVALUE_ENTRY(EVENT_FOCUSGAINED, "FocusGained"),
+ KEYVALUE_ENTRY(EVENT_FOCUSLOST, "FocusLost"),
+ KEYVALUE_ENTRY(EVENT_FUNCUNDEFINED, "FuncUndefined"),
+ KEYVALUE_ENTRY(EVENT_GUIENTER, "GUIEnter"),
+ KEYVALUE_ENTRY(EVENT_GUIFAILED, "GUIFailed"),
+ KEYVALUE_ENTRY(EVENT_INSERTCHANGE, "InsertChange"),
+ KEYVALUE_ENTRY(EVENT_INSERTCHARPRE, "InsertCharPre"),
+ KEYVALUE_ENTRY(EVENT_INSERTENTER, "InsertEnter"),
+ KEYVALUE_ENTRY(EVENT_INSERTLEAVE, "InsertLeave"),
+ KEYVALUE_ENTRY(EVENT_INSERTLEAVEPRE, "InsertLeavePre"),
+ KEYVALUE_ENTRY(EVENT_MENUPOPUP, "MenuPopup"),
+ KEYVALUE_ENTRY(EVENT_MODECHANGED, "ModeChanged"),
+ KEYVALUE_ENTRY(EVENT_OPTIONSET, "OptionSet"),
+ KEYVALUE_ENTRY(EVENT_QUICKFIXCMDPOST, "QuickFixCmdPost"),
+ KEYVALUE_ENTRY(EVENT_QUICKFIXCMDPRE, "QuickFixCmdPre"),
+ KEYVALUE_ENTRY(EVENT_QUITPRE, "QuitPre"),
+ KEYVALUE_ENTRY(EVENT_REMOTEREPLY, "RemoteReply"),
+ KEYVALUE_ENTRY(EVENT_SAFESTATE, "SafeState"),
+ KEYVALUE_ENTRY(EVENT_SAFESTATEAGAIN, "SafeStateAgain"),
+ KEYVALUE_ENTRY(EVENT_SESSIONLOADPOST, "SessionLoadPost"),
+ KEYVALUE_ENTRY(EVENT_SESSIONWRITEPOST, "SessionWritePost"),
+ KEYVALUE_ENTRY(EVENT_SHELLCMDPOST, "ShellCmdPost"),
+ KEYVALUE_ENTRY(EVENT_SHELLFILTERPOST, "ShellFilterPost"),
+ KEYVALUE_ENTRY(EVENT_SIGUSR1, "SigUSR1"),
+ KEYVALUE_ENTRY(EVENT_SOURCECMD, "SourceCmd"),
+ KEYVALUE_ENTRY(EVENT_SOURCEPOST, "SourcePost"),
+ KEYVALUE_ENTRY(EVENT_SOURCEPRE, "SourcePre"),
+ KEYVALUE_ENTRY(EVENT_SPELLFILEMISSING, "SpellFileMissing"),
+ KEYVALUE_ENTRY(EVENT_STDINREADPOST, "StdinReadPost"),
+ KEYVALUE_ENTRY(EVENT_STDINREADPRE, "StdinReadPre"),
+ KEYVALUE_ENTRY(EVENT_SWAPEXISTS, "SwapExists"),
+ KEYVALUE_ENTRY(EVENT_SYNTAX, "Syntax"),
+ KEYVALUE_ENTRY(EVENT_TABCLOSED, "TabClosed"),
+ KEYVALUE_ENTRY(EVENT_TABENTER, "TabEnter"),
+ KEYVALUE_ENTRY(EVENT_TABLEAVE, "TabLeave"),
+ KEYVALUE_ENTRY(EVENT_TABNEW, "TabNew"),
+ KEYVALUE_ENTRY(EVENT_TERMCHANGED, "TermChanged"),
+ KEYVALUE_ENTRY(EVENT_TERMINALOPEN, "TerminalOpen"),
+ KEYVALUE_ENTRY(EVENT_TERMINALWINOPEN, "TerminalWinOpen"),
+ KEYVALUE_ENTRY(EVENT_TERMRESPONSE, "TermResponse"),
+ KEYVALUE_ENTRY(EVENT_TERMRESPONSEALL, "TermResponseAll"),
+ KEYVALUE_ENTRY(EVENT_TEXTCHANGED, "TextChanged"),
+ KEYVALUE_ENTRY(EVENT_TEXTCHANGEDI, "TextChangedI"),
+ KEYVALUE_ENTRY(EVENT_TEXTCHANGEDP, "TextChangedP"),
+ KEYVALUE_ENTRY(EVENT_TEXTCHANGEDT, "TextChangedT"),
+ KEYVALUE_ENTRY(EVENT_TEXTYANKPOST, "TextYankPost"),
+ KEYVALUE_ENTRY(EVENT_USER, "User"),
+ KEYVALUE_ENTRY(EVENT_VIMENTER, "VimEnter"),
+ KEYVALUE_ENTRY(EVENT_VIMLEAVE, "VimLeave"),
+ KEYVALUE_ENTRY(EVENT_VIMLEAVEPRE, "VimLeavePre"),
+ KEYVALUE_ENTRY(EVENT_VIMRESIZED, "VimResized"),
+ KEYVALUE_ENTRY(EVENT_VIMRESUME, "VimResume"),
+ KEYVALUE_ENTRY(EVENT_VIMSUSPEND, "VimSuspend"),
+ KEYVALUE_ENTRY(EVENT_WINCLOSED, "WinClosed"),
+ KEYVALUE_ENTRY(EVENT_WINENTER, "WinEnter"),
+ KEYVALUE_ENTRY(EVENT_WINLEAVE, "WinLeave"),
+ KEYVALUE_ENTRY(EVENT_WINNEW, "WinNew"),
+ KEYVALUE_ENTRY(EVENT_WINNEWPRE, "WinNewPre"),
+ KEYVALUE_ENTRY(EVENT_WINRESIZED, "WinResized"),
+ KEYVALUE_ENTRY(EVENT_WINSCROLLED, "WinScrolled")
};
-static AutoPat *first_autopat[NUM_EVENTS] =
-{
+static AutoPat *first_autopat[NUM_EVENTS] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ NULL, NULL, NULL, NULL, NULL, NULL
};
-static AutoPat *last_autopat[NUM_EVENTS] =
-{
+static AutoPat *last_autopat[NUM_EVENTS] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ NULL, NULL, NULL, NULL, NULL, NULL
};
#define AUGROUP_DEFAULT (-1) // default autocmd group
@@ -265,6 +279,7 @@ static int current_augroup = AUGROUP_DEFAULT;
static int au_need_clean = FALSE; // need to delete marked patterns
+static event_T event_name2nr(char_u *start, char_u **end);
static char_u *event_nr2name(event_T event);
static int au_get_grouparg(char_u **argp);
static int do_autocmd_event(event_T event, char_u *pat, int once, int nested, char_u *cmd, int forceit, int group, int flags);
@@ -680,24 +695,35 @@ is_aucmd_win(win_T *win)
event_name2nr(char_u *start, char_u **end)
{
char_u *p;
- int i;
- int len;
+ keyvalue_T target;
+ keyvalue_T *entry;
+ static keyvalue_T *bufnewfile = &event_tab[BUFNEWFILE_INDEX];
+ static keyvalue_T *bufread = &event_tab[BUFREAD_INDEX];
// the event name ends with end of line, '|', a blank or a comma
for (p = start; *p && !VIM_ISWHITE(*p) && *p != ',' && *p != '|'; ++p)
;
- for (i = 0; event_names[i].name != NULL; ++i)
- {
- len = (int)STRLEN(event_names[i].name);
- if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
- break;
- }
+
+ target.key = 0;
+ target.value = (char *)start;
+ target.length = (size_t)(p - start);
+
+ // special cases:
+ // BufNewFile and BufRead are searched for ALOT (especially at startup)
+ // so we check for them first.
+ if (cmp_keyvalue_value_ni(&target, bufnewfile) == 0)
+ entry = bufnewfile;
+ else
+ if (cmp_keyvalue_value_ni(&target, bufread) == 0)
+ entry = bufread;
+ else
+ entry = (keyvalue_T *)bsearch(&target, &event_tab, ARRAY_LENGTH(event_tab), sizeof(event_tab[0]), cmp_keyvalue_value_ni);
+
if (*p == ',')
++p;
*end = p;
- if (event_names[i].name == NULL)
- return NUM_EVENTS;
- return event_names[i].event;
+
+ return (entry == NULL) ? NUM_EVENTS : (event_T)entry->key;
}
/*
@@ -707,11 +733,52 @@ event_name2nr(char_u *start, char_u **end)
event_nr2name(event_T event)
{
int i;
+#define CACHE_SIZE 12
+ static int cache_tab[CACHE_SIZE];
+ static int cache_last_index = -1;
+
+ if (cache_last_index < 0)
+ {
+ for (i = 0; i < (int)ARRAY_LENGTH(cache_tab); ++i)
+ cache_tab[i] = -1;
+ cache_last_index = ARRAY_LENGTH(cache_tab) - 1;
+ }
- for (i = 0; event_names[i].name != NULL; ++i)
- if (event_names[i].event == event)
- return (char_u *)event_names[i].name;
- return (char_u *)"Unknown";
+ // first look in the cache
+ // the cache is circular. to search it we start at the most recent entry
+ // and go backwards wrapping around when we get to index 0.
+ for (i = cache_last_index; cache_tab[i] >= 0; )
+ {
+ if ((event_T)event_tab[cache_tab[i]].key == event)
+ return (char_u *)event_tab[cache_tab[i]].value;
+
+ if (i == 0)
+ i = ARRAY_LENGTH(cache_tab) - 1;
+ else
+ --i;
+
+ // are we back at the start?
+ if (i == cache_last_index)
+ break;
+ }
+
+ // look in the event table itself
+ for (i = 0; i < (int)ARRAY_LENGTH(event_tab); ++i)
+ {
+ if ((event_T)event_tab[i].key == event)
+ {
+ // store the found entry in the next position in the cache,
+ // wrapping around when we get to the maximum index.
+ if (cache_last_index == ARRAY_LENGTH(cache_tab) - 1)
+ cache_last_index = 0;
+ else
+ ++cache_last_index;
+ cache_tab[cache_last_index] = i;
+ break;
+ }
+ }
+
+ return (i == (int)ARRAY_LENGTH(event_tab)) ? (char_u *)"Unknown" : (char_u *)event_tab[i].value;
}
/*
@@ -805,12 +872,14 @@ au_event_disable(char *what)
{
char_u *new_ei;
char_u *save_ei;
+ size_t p_ei_len;
- save_ei = vim_strsave(p_ei);
+ p_ei_len = STRLEN(p_ei);
+ save_ei = vim_strnsave(p_ei, p_ei_len);
if (save_ei == NULL)
return NULL;
- new_ei = vim_strnsave(p_ei, STRLEN(p_ei) + STRLEN(what));
+ new_ei = vim_strnsave(p_ei, p_ei_len + STRLEN(what));
if (new_ei == NULL)
{
vim_free(save_ei);
@@ -1591,6 +1660,11 @@ aucmd_prepbuf(
win_init_popup_win(auc_win, buf);
+ // Make sure tp_localdir and globaldir are NULL to avoid a
+ // chdir() in win_enter_ext().
+ // win_init_popup_win() has already set w_localdir to NULL.
+ aco->tp_localdir = curtab->tp_localdir;
+ curtab->tp_localdir = NULL;
aco->globaldir = globaldir;
globaldir = NULL;
@@ -1704,6 +1778,12 @@ win_found:
vars_clear(&awp->w_vars->dv_hashtab); // free all w: variables
hash_init(&awp->w_vars->dv_hashtab); // re-use the hashtab
#endif
+ // If :lcd has been used in the autocommand window, correct current
+ // directory before restoring tp_localdir and globaldir.
+ if (awp->w_localdir != NULL)
+ win_fix_current_dir();
+ vim_free(curtab->tp_localdir);
+ curtab->tp_localdir = aco->tp_localdir;
vim_free(globaldir);
globaldir = aco->globaldir;
@@ -2257,7 +2337,7 @@ apply_autocmds_group(
saveRedobuff(&save_redo);
did_save_redobuff = TRUE;
}
- did_filetype = keep_filetype;
+ curbuf->b_did_filetype = curbuf->b_keep_filetype;
}
/*
@@ -2269,7 +2349,7 @@ apply_autocmds_group(
// Remember that FileType was triggered. Used for did_filetype().
if (event == EVENT_FILETYPE)
- did_filetype = TRUE;
+ curbuf->b_did_filetype = TRUE;
tail = gettail(fname);
@@ -2378,7 +2458,7 @@ apply_autocmds_group(
restore_search_patterns();
if (did_save_redobuff)
restoreRedobuff(&save_redo);
- did_filetype = FALSE;
+ curbuf->b_did_filetype = FALSE;
while (au_pending_free_buf != NULL)
{
buf_T *b = au_pending_free_buf->b_next;
@@ -2420,7 +2500,7 @@ BYPASS_AU:
aubuflocal_remove(buf);
if (retval == OK && event == EVENT_FILETYPE)
- au_did_filetype = TRUE;
+ curbuf->b_au_did_filetype = TRUE;
return retval;
}
@@ -2773,6 +2853,8 @@ set_context_in_autocmd(
char_u *
get_event_name(expand_T *xp UNUSED, int idx)
{
+ int i;
+
if (idx < augroups.ga_len) // First list group names, if wanted
{
if (!include_groups || AUGROUP_NAME(idx) == NULL
@@ -2780,7 +2862,12 @@ get_event_name(expand_T *xp UNUSED, int idx)
return (char_u *)""; // skip deleted entries
return AUGROUP_NAME(idx); // return a name
}
- return (char_u *)event_names[idx - augroups.ga_len].name;
+
+ i = idx - augroups.ga_len;
+ if (i < 0 || i >= (int)ARRAY_LENGTH(event_tab))
+ return NULL;
+
+ return (char_u *)event_tab[i].value;
}
/*
@@ -2790,7 +2877,10 @@ get_event_name(expand_T *xp UNUSED, int idx)
char_u *
get_event_name_no_group(expand_T *xp UNUSED, int idx)
{
- return (char_u *)event_names[idx].name;
+ if (idx < 0 || idx >= (int)ARRAY_LENGTH(event_tab))
+ return NULL;
+
+ return (char_u *)event_tab[idx].value;
}
@@ -3250,8 +3340,6 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv)
// return only the autocmds for the specified event
if (dict_has_key(argvars[0].vval.v_dict, "event"))
{
- int i;
-
name = dict_get_string(argvars[0].vval.v_dict, "event", TRUE);
if (name == NULL)
return;
@@ -3260,16 +3348,20 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv)
event_arg = NUM_EVENTS;
else
{
- for (i = 0; event_names[i].name != NULL; i++)
- if (STRICMP(event_names[i].name, name) == 0)
- break;
- if (event_names[i].name == NULL)
+ keyvalue_T target;
+ keyvalue_T *entry;
+
+ target.key = 0;
+ target.value = (char *)name;
+ target.length = (int)STRLEN(target.value);
+ entry = (keyvalue_T *)bsearch(&target, &event_tab, ARRAY_LENGTH(event_tab), sizeof(event_tab[0]), cmp_keyvalue_value_ni);
+ if (entry == NULL)
{
semsg(_(e_no_such_event_str), name);
vim_free(name);
return;
}
- event_arg = event_names[i].event;
+ event_arg = (event_T)entry->key;
}
vim_free(name);
}
@@ -3314,7 +3406,10 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv)
event_dict = dict_alloc();
if (event_dict == NULL
|| list_append_dict(event_list, event_dict) == FAIL)
+ {
+ vim_free(pat);
return;
+ }
if (dict_add_string(event_dict, "event", event_name) == FAIL
|| dict_add_string(event_dict, "group",
@@ -3329,7 +3424,10 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv)
|| dict_add_bool(event_dict, "once", ac->once) == FAIL
|| dict_add_bool(event_dict, "nested",
ac->nested) == FAIL)
+ {
+ vim_free(pat);
return;
+ }
}
}
}
diff --git a/src/buffer.c b/src/buffer.c
index 243593a..58e9718 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -225,7 +225,7 @@ open_buffer(
// The autocommands in readfile() may change the buffer, but only AFTER
// reading the file.
set_bufref(&old_curbuf, curbuf);
- modified_was_set = FALSE;
+ curbuf->b_modified_was_set = FALSE;
// mark cursor position as being invalid
curwin->w_valid = 0;
@@ -322,7 +322,7 @@ open_buffer(
// the changed flag. Unless in readonly mode: "ls | gview -".
// When interrupted and 'cpoptions' contains 'i' set changed flag.
if ((got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
- || modified_was_set // ":set modified" used in autocmd
+ || curbuf->b_modified_was_set // autocmd did ":set modified"
#ifdef FEAT_EVAL
|| (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
#endif
@@ -1944,7 +1944,7 @@ enter_buffer(buf_T *buf)
// ":ball" used in an autocommand. If there already is a filetype we
// might prefer to keep it.
if (*curbuf->b_p_ft == NUL)
- did_filetype = FALSE;
+ curbuf->b_did_filetype = FALSE;
open_buffer(FALSE, NULL, 0);
}
diff --git a/src/change.c b/src/change.c
index daf4fae..dacc06f 100644
--- a/src/change.c
+++ b/src/change.c
@@ -574,8 +574,7 @@ changed_common(
&& wp->w_topline < lnume
&& win_linetabsize(wp, wp->w_topline,
ml_get(wp->w_topline), (colnr_T)MAXCOL)
- <= wp->w_skipcol + sms_marker_overlap(wp,
- win_col_off(wp) - win_col_off2(wp)))))
+ <= wp->w_skipcol + sms_marker_overlap(wp, -1))))
wp->w_skipcol = 0;
// Check if a change in the buffer has invalidated the cached
diff --git a/src/charset.c b/src/charset.c
index 5ae90da..470698f 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -798,6 +798,45 @@ linetabsize(win_T *wp, linenr_T lnum)
ml_get_buf(wp->w_buffer, lnum, FALSE), (colnr_T)MAXCOL);
}
+/*
+ * Like linetabsize(), but excludes 'above'/'after'/'right'/'below' aligned
+ * virtual text, while keeping inline virtual text.
+ */
+ int
+linetabsize_no_outer(win_T *wp, linenr_T lnum)
+{
+#ifndef FEAT_PROP_POPUP
+ return linetabsize(wp, lnum);
+#else
+ chartabsize_T cts;
+ char_u *line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+
+ init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
+
+ if (cts.cts_text_prop_count)
+ {
+ int write_idx = 0;
+ for (int read_idx = 0; read_idx < cts.cts_text_prop_count; read_idx++)
+ {
+ textprop_T *tp = &cts.cts_text_props[read_idx];
+ if (tp->tp_col != MAXCOL)
+ {
+ if (read_idx != write_idx)
+ cts.cts_text_props[write_idx] = *tp;
+ write_idx++;
+ }
+ }
+ cts.cts_text_prop_count = write_idx;
+ if (cts.cts_text_prop_count == 0)
+ VIM_CLEAR(cts.cts_text_props);
+ }
+
+ win_linetabsize_cts(&cts, (colnr_T)MAXCOL);
+ clear_chartabsize_arg(&cts);
+ return (int)cts.cts_vcol;
+#endif
+}
+
void
win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
{
@@ -1318,7 +1357,7 @@ win_lbr_chartabsize(
cts->cts_bri_size = get_breakindent_win(wp, line);
head_mid += cts->cts_bri_size;
}
- if (head_mid > 0 && wcol + size > wp->w_width)
+ if (head_mid > 0)
{
// Calculate effective window width.
int prev_rem = wp->w_width - wcol;
diff --git a/src/clientserver.c b/src/clientserver.c
index 340add3..b19cd44 100644
--- a/src/clientserver.c
+++ b/src/clientserver.c
@@ -608,7 +608,7 @@ build_drop_cmd(
// Call inputsave() so that a prompt for an encryption key works.
ga_concat(&ga, (char_u *)
- "<CR>:if exists('*inputsave')|call inputsave()|endif|");
+ "<CR><C-\\><C-N>:if exists('*inputsave')|call inputsave()|endif|");
if (tabs)
ga_concat(&ga, (char_u *)"tab ");
ga_concat(&ga, (char_u *)"drop");
@@ -652,7 +652,13 @@ build_drop_cmd(
// endif
// endif
ga_concat(&ga, (char_u *)":if !exists('+acd')||!&acd|if haslocaldir()|");
+#ifdef MSWIN
+ // in case :set shellslash is set, need to normalize the directory separators
+ // '/' is not valid in a filename so replacing '/' by '\\' should be safe
+ ga_concat(&ga, (char_u *)"cd -|lcd -|elseif getcwd()->tr('/','\\') ==# '");
+#else
ga_concat(&ga, (char_u *)"cd -|lcd -|elseif getcwd() ==# '");
+#endif
ga_concat(&ga, cdp);
ga_concat(&ga, (char_u *)"'|cd -|endif|endif<CR>");
vim_free(cdp);
diff --git a/src/configure.ac b/src/configure.ac
index 6311269..f6e54b3 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -4523,13 +4523,13 @@ if test "$enable_nls" = "yes"; then
AC_MSG_RESULT([no])
fi
AC_SUBST(MSGFMT_DESKTOP)
- AC_MSG_CHECKING([if msgfmt supports --no-convert])
+ AC_MSG_CHECKING([if $MSGFMT supports --no-convert])
if "$MSGFMT" --help | grep -q -- '--no-convert' >/dev/null; then
AC_MSG_RESULT([yes])
- MSGFMTCMD="OLD_PO_FILE_INPUT=yes msgfmt --no-convert -v"
+ MSGFMTCMD="OLD_PO_FILE_INPUT=yes $MSGFMT --no-convert -v"
else
AC_MSG_RESULT([no])
- MSGFMTCMD="OLD_PO_FILE_INPUT=yes msgfmt -v"
+ MSGFMTCMD="OLD_PO_FILE_INPUT=yes $MSGFMT -v"
fi
AC_SUBST(MSGFMTCMD)
fi
diff --git a/src/dict.c b/src/dict.c
index 508d00c..c78995d 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -1300,12 +1300,18 @@ dict_extend_func(
action = tv_get_string_chk(&argvars[2]);
if (action == NULL)
+ {
+ if (is_new)
+ dict_unref(d1);
return;
+ }
for (i = 0; i < 3; ++i)
if (STRCMP(action, av[i]) == 0)
break;
if (i == 3)
{
+ if (is_new)
+ dict_unref(d1);
semsg(_(e_invalid_argument_str), action);
return;
}
diff --git a/src/dosinst.c b/src/dosinst.c
index 35625a7..116cc8f 100644
--- a/src/dosinst.c
+++ b/src/dosinst.c
@@ -1663,7 +1663,7 @@ install_registry(void)
uninstall_string,
icon_string,
version_string,
- "Bram Moolenaar et al.");
+ "The Vim Project");
if (ERROR_SUCCESS != lRet)
return FAIL;
diff --git a/src/drawline.c b/src/drawline.c
index a8de449..81577be 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -2072,26 +2072,34 @@ win_line(
// not on the next char yet, don't start another prop
--bcol;
# endif
- int display_text_first = FALSE;
-
// Add any text property that starts in this column.
- // With 'nowrap' and not in the first screen line only "below"
- // text prop can show.
- while (text_prop_next < text_prop_count
- && (text_props[text_prop_next].tp_col == MAXCOL
- ? ((*ptr == NUL
- && (wp->w_p_wrap
- || wlv.row == startrow
- || (text_props[text_prop_next].tp_flags
- & TP_FLAG_ALIGN_BELOW)))
- || (bcol == 0
- && (text_props[text_prop_next].tp_flags
- & TP_FLAG_ALIGN_ABOVE)))
- : bcol >= text_props[text_prop_next].tp_col - 1))
+ while (text_prop_next < text_prop_count)
{
- if (text_props[text_prop_next].tp_col == MAXCOL
- || bcol <= text_props[text_prop_next].tp_col - 1
- + text_props[text_prop_next].tp_len)
+ int active;
+ textprop_T *tp = &text_props[text_prop_next];
+ if (tp->tp_col == MAXCOL)
+ {
+ if (bcol == 0 && (tp->tp_flags & TP_FLAG_ALIGN_ABOVE))
+ active = TRUE;
+ else if (*ptr != NUL)
+ break;
+ else
+ {
+ // With 'nowrap' and not in the first screen line only "below"
+ // text prop can show.
+ active = wp->w_p_wrap
+ || wlv.row == startrow
+ || (tp->tp_flags & TP_FLAG_ALIGN_BELOW);
+ }
+ }
+ else
+ {
+ if (bcol < tp->tp_col - 1)
+ break;
+ active = bcol <= tp->tp_col - 1 + tp->tp_len;
+ }
+
+ if (active)
text_prop_idxs[text_props_active++] = text_prop_next;
++text_prop_next;
}
@@ -2109,8 +2117,7 @@ win_line(
text_prop_id = 0;
reset_extra_attr = FALSE;
}
- if (text_props_active > 0 && wlv.n_extra == 0
- && !display_text_first)
+ if (text_props_active > 0 && wlv.n_extra == 0)
{
int used_tpi = -1;
int used_attr = 0;
@@ -2157,8 +2164,6 @@ win_line(
// skip this prop, first display the '$' after
// the line or display an empty line
text_prop_follows = TRUE;
- if (used_tpi < 0)
- display_text_first = TRUE;
continue;
}
@@ -2172,7 +2177,6 @@ win_line(
text_prop_flags = pt->pt_flags;
text_prop_id = tp->tp_id;
used_tpi = tpi;
- display_text_first = FALSE;
}
}
if (text_prop_id < 0 && used_tpi >= 0
@@ -2327,17 +2331,29 @@ win_line(
}
}
else if (text_prop_next < text_prop_count
- && text_props[text_prop_next].tp_col == MAXCOL
&& ((*ptr != NUL && ptr[mb_ptr2len(ptr)] == NUL)
- || (!wp->w_p_wrap
- && wlv.col == wp->w_width - 1
- && (text_props[text_prop_next].tp_flags
- & TP_FLAG_ALIGN_BELOW))))
+ || (!wp->w_p_wrap && wlv.col == wp->w_width - 1)))
+ {
// When at last-but-one character and a text property
// follows after it, we may need to flush the line after
// displaying that character.
// Or when not wrapping and at the rightmost column.
- text_prop_follows = TRUE;
+
+ int only_below_follows = !wp->w_p_wrap && wlv.col == wp->w_width - 1;
+ // TODO: Store "after"/"right"/"below" text properties in order
+ // in the buffer so only `text_props[text_prop_count - 1]`
+ // needs to be checked for following "below" virtual text
+ for (int i = text_prop_next; i < text_prop_count; ++i)
+ {
+ if (text_props[i].tp_col == MAXCOL
+ && (!only_below_follows
+ || (text_props[i].tp_flags & TP_FLAG_ALIGN_BELOW)))
+ {
+ text_prop_follows = TRUE;
+ break;
+ }
+ }
+ }
}
if (wlv.start_extra_for_textprop)
diff --git a/src/edit.c b/src/edit.c
index 69ec255..075b39b 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -845,9 +845,10 @@ doESCkey:
did_cursorhold = FALSE;
// ins_redraw() triggers TextChangedI only when no characters
- // are in the typeahead buffer, so only reset curbuf->b_last_changedtick
+ // are in the typeahead buffer, so reset curbuf->b_last_changedtick only
// if the TextChangedI was not blocked by char_avail() (e.g. using :norm!)
- if (!char_avail())
+ // and the TextChangedI autocommand has been triggered.
+ if (!char_avail() && curbuf->b_last_changedtick_i == CHANGEDTICK(curbuf))
curbuf->b_last_changedtick = CHANGEDTICK(curbuf);
return (c == Ctrl_O);
}
@@ -3958,10 +3959,9 @@ ins_del(void)
* Delete one character for ins_bs().
*/
static void
-ins_bs_one(colnr_T *vcolp)
+ins_bs_one(void)
{
dec_cursor();
- getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL);
if (State & REPLACE_FLAG)
{
// Don't delete characters before the insert point when in
@@ -4211,44 +4211,69 @@ ins_bs(
&& (!*inserted_space_p
|| arrow_used))))))
{
- int ts;
- colnr_T vcol;
+ colnr_T vcol = 0;
colnr_T want_vcol;
- colnr_T start_vcol;
+ char_u *line;
+ char_u *ptr;
+ char_u *cursor_ptr;
+ char_u *space_ptr;
+ colnr_T space_vcol = 0;
+ int prev_space = FALSE;
+ colnr_T want_col;
*inserted_space_p = FALSE;
- // Compute the virtual column where we want to be. Since
- // 'showbreak' may get in the way, need to get the last column of
- // the previous character.
- getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
- start_vcol = vcol;
- dec_cursor();
- getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
- inc_cursor();
-#ifdef FEAT_VARTABS
- if (p_sta && in_indent)
+
+ space_ptr = ptr = line = ml_get_curline();
+ cursor_ptr = line + curwin->w_cursor.col;
+
+ // Compute virtual column of cursor position, and find the last
+ // whitespace before cursor that is preceded by non-whitespace.
+ // Use chartabsize() so that virtual text and wrapping are ignored.
+ while (ptr < cursor_ptr)
{
- ts = (int)get_sw_value(curbuf);
- want_vcol = (want_vcol / ts) * ts;
+ int cur_space = VIM_ISWHITE(*ptr);
+
+ if (!prev_space && cur_space)
+ {
+ space_ptr = ptr;
+ space_vcol = vcol;
+ }
+ vcol += chartabsize(ptr, vcol);
+ MB_PTR_ADV(ptr);
+ prev_space = cur_space;
}
+
+ // Compute the virtual column where we want to be.
+ want_vcol = vcol > 0 ? vcol - 1 : 0;
+ if (p_sta && in_indent)
+ want_vcol -= want_vcol % (int)get_sw_value(curbuf);
else
+#ifdef FEAT_VARTABS
want_vcol = tabstop_start(want_vcol, get_sts_value(),
curbuf->b_p_vsts_array);
#else
- if (p_sta && in_indent)
- ts = (int)get_sw_value(curbuf);
- else
- ts = (int)get_sts_value();
- want_vcol = (want_vcol / ts) * ts;
+ want_vcol -= want_vcol % (int)get_sts_value();
#endif
- // delete characters until we are at or before want_vcol
- while (vcol > want_vcol && curwin->w_cursor.col > 0
- && (cc = *(ml_get_cursor() - 1), VIM_ISWHITE(cc)))
- ins_bs_one(&vcol);
+ // Find the position to stop backspacing.
+ // Use chartabsize() so that virtual text and wrapping are ignored.
+ while (TRUE)
+ {
+ int size = chartabsize(space_ptr, space_vcol);
- // insert extra spaces until we are at want_vcol
- while (vcol < want_vcol)
+ if (space_vcol + size > want_vcol)
+ break;
+ space_vcol += size;
+ MB_PTR_ADV(space_ptr);
+ }
+ want_col = space_ptr - line;
+
+ // Delete characters until we are at or before want_col.
+ while (curwin->w_cursor.col > want_col)
+ ins_bs_one();
+
+ // Insert extra spaces until we are at want_vcol.
+ for (; space_vcol < want_vcol; space_vcol++)
{
// Remember the first char we inserted
if (curwin->w_cursor.lnum == Insstart_orig.lnum
@@ -4263,13 +4288,7 @@ ins_bs(
if ((State & REPLACE_FLAG))
replace_push(NUL);
}
- getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
}
-
- // If we are now back where we started delete one character. Can
- // happen when using 'sts' and 'linebreak'.
- if (vcol >= start_vcol)
- ins_bs_one(&vcol);
}
/*
@@ -4783,7 +4802,7 @@ ins_pageup(void)
}
tpos = curwin->w_cursor;
- if (onepage(BACKWARD, 1L) == OK)
+ if (pagescroll(BACKWARD, 1L, FALSE) == OK)
{
start_arrow(&tpos);
can_cindent = TRUE;
@@ -4840,7 +4859,7 @@ ins_pagedown(void)
}
tpos = curwin->w_cursor;
- if (onepage(FORWARD, 1L) == OK)
+ if (pagescroll(FORWARD, 1L, FALSE) == OK)
{
start_arrow(&tpos);
can_cindent = TRUE;
diff --git a/src/errors.h b/src/errors.h
index 5dccc63..4387a29 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -2268,7 +2268,7 @@ EXTERN char e_nfa_regexp_while_converting_from_postfix_to_nfa_too_many_stats_lef
EXTERN char e_nfa_regexp_not_enough_space_to_store_whole_nfa[]
INIT(= N_("E876: (NFA regexp) Not enough space to store the whole NFA"));
EXTERN char e_nfa_regexp_invalid_character_class_nr[]
- INIT(= "E877: (NFA regexp) Invalid character class: %d");
+ INIT(= N_("E877: (NFA regexp) Invalid character class: %d"));
EXTERN char e_nfa_regexp_could_not_allocate_memory_for_branch_traversal[]
INIT(= N_("E878: (NFA regexp) Could not allocate memory for branch traversal!"));
#ifdef FEAT_SYN_HL
@@ -3412,9 +3412,9 @@ EXTERN char e_invalid_class_variable_declaration_str[]
EXTERN char e_invalid_type_for_object_variable_str[]
INIT(= N_("E1330: Invalid type for object variable: %s"));
EXTERN char e_public_must_be_followed_by_var_static_final_or_const[]
- INIT(= N_("E1331: Public must be followed by \"var\" or \"static\" or \"final\" or \"const\""));
+ INIT(= N_("E1331: public must be followed by \"var\" or \"static\" or \"final\" or \"const\""));
EXTERN char e_public_variable_name_cannot_start_with_underscore_str[]
- INIT(= N_("E1332: Public variable name cannot start with underscore: %s"));
+ INIT(= N_("E1332: public variable name cannot start with underscore: %s"));
EXTERN char e_cannot_access_protected_variable_str[]
INIT(= N_("E1333: Cannot access protected variable \"%s\" in class \"%s\""));
// E1334 unused
@@ -3532,9 +3532,9 @@ EXTERN char e_class_method_str_accessible_only_using_class_str[]
EXTERN char e_object_method_str_accessible_only_using_object_str[]
INIT(= N_("E1386: Object method \"%s\" accessible only using class \"%s\" object"));
EXTERN char e_public_variable_not_supported_in_interface[]
- INIT(= N_("E1387: Public variable not supported in an interface"));
+ INIT(= N_("E1387: public variable not supported in an interface"));
EXTERN char e_public_keyword_not_supported_for_method[]
- INIT(= N_("E1388: Public keyword not supported for a method"));
+ INIT(= N_("E1388: public keyword not supported for a method"));
EXTERN char e_missing_name_after_implements[]
INIT(= N_("E1389: Missing name after implements"));
EXTERN char e_cannot_use_an_object_variable_except_with_the_new_method_str[]
@@ -3585,8 +3585,40 @@ EXTERN char e_builtin_object_method_str_not_supported[]
INIT(= N_("E1412: Builtin object method \"%s\" not supported"));
EXTERN char e_builtin_class_method_not_supported[]
INIT(= N_("E1413: Builtin class method not supported"));
-#endif
-// E1415 - E1499 unused (reserved for Vim9 class support)
+EXTERN char e_enum_can_only_be_defined_in_vim9_script[]
+ INIT(= N_("E1414: Enum can only be defined in Vim9 script"));
+EXTERN char e_enum_name_must_start_with_uppercase_letter_str[]
+ INIT(= N_("E1415: Enum name must start with an uppercase letter: %s"));
+EXTERN char e_enum_cannot_extend_class[]
+ INIT(= N_("E1416: Enum cannot extend a class or enum"));
+EXTERN char e_abstract_cannot_be_used_in_enum[]
+ INIT(= N_("E1417: Abstract cannot be used in an Enum"));
+EXTERN char e_invalid_enum_value_declaration_str[]
+ INIT(= N_("E1418: Invalid enum value declaration: %s"));
+EXTERN char e_not_valid_command_in_enum_str[]
+ INIT(= N_("E1419: Not a valid command in an Enum: %s"));
+EXTERN char e_missing_endenum[]
+ INIT(= N_("E1420: Missing :endenum"));
+EXTERN char e_using_enum_as_value_str[]
+ INIT(= N_("E1421: Enum \"%s\" cannot be used as a value"));
+EXTERN char e_enum_value_str_not_found_in_enum_str[]
+ INIT(= N_("E1422: Enum value \"%s\" not found in enum \"%s\""));
+EXTERN char e_enumvalue_str_cannot_be_modified[]
+ INIT(= N_("E1423: Enum value \"%s.%s\" cannot be modified"));
+EXTERN char e_using_enum_str_as_number[]
+ INIT(= N_("E1424: Using an Enum \"%s\" as a Number"));
+EXTERN char e_using_enum_str_as_string[]
+ INIT(= N_("E1425: Using an Enum \"%s\" as a String"));
+EXTERN char e_enum_str_ordinal_cannot_be_modified[]
+ INIT(= N_("E1426: Enum \"%s\" ordinal value cannot be modified"));
+EXTERN char e_enum_str_name_cannot_be_modified[]
+ INIT(= N_("E1427: Enum \"%s\" name cannot be modified"));
+EXTERN char e_duplicate_enum_str[]
+ INIT(= N_("E1428: Duplicate enum value: %s"));
+EXTERN char e_class_can_only_be_used_in_script[]
+ INIT(= N_("E1429: Class can only be used in a script"));
+#endif
+// E1429 - E1499 unused (reserved for Vim9 class support)
EXTERN char e_cannot_mix_positional_and_non_positional_str[]
INIT(= N_("E1500: Cannot mix positional and non-positional arguments: %s"));
EXTERN char e_fmt_arg_nr_unused_str[]
diff --git a/src/eval.c b/src/eval.c
index 69b8374..51ee604 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -549,6 +549,7 @@ skip_expr_concatenate(
((char_u **)gap->ga_data)[gap->ga_len - 1];
((char_u **)gap->ga_data)[gap->ga_len - 1] = NULL;
ga_clear_strings(gap);
+ ga_clear(freegap);
}
else
{
@@ -574,16 +575,16 @@ skip_expr_concatenate(
/*
* Convert "tv" to a string.
- * When "convert" is TRUE convert a List into a sequence of lines.
+ * When "join_list" is TRUE convert a List into a sequence of lines.
* Returns an allocated string (NULL when out of memory).
*/
char_u *
-typval2string(typval_T *tv, int convert)
+typval2string(typval_T *tv, int join_list)
{
garray_T ga;
char_u *retval;
- if (convert && tv->v_type == VAR_LIST)
+ if (join_list && tv->v_type == VAR_LIST)
{
ga_init2(&ga, sizeof(char), 80);
if (tv->vval.v_list != NULL)
@@ -595,6 +596,16 @@ typval2string(typval_T *tv, int convert)
ga_append(&ga, NUL);
retval = (char_u *)ga.ga_data;
}
+ else if (tv->v_type == VAR_LIST || tv->v_type == VAR_DICT)
+ {
+ char_u *tofree;
+ char_u numbuf[NUMBUFLEN];
+
+ retval = tv2string(tv, &tofree, numbuf, 0);
+ // Make a copy if we have a value but it's not in allocated memory.
+ if (retval != NULL && tofree == NULL)
+ retval = vim_strsave(retval);
+ }
else
retval = vim_strsave(tv_get_string(tv));
return retval;
@@ -603,13 +614,13 @@ typval2string(typval_T *tv, int convert)
/*
* Top level evaluation function, returning a string. Does not handle line
* breaks.
- * When "convert" is TRUE convert a List into a sequence of lines.
+ * When "join_list" is TRUE convert a List into a sequence of lines.
* Return pointer to allocated memory, or NULL for failure.
*/
char_u *
eval_to_string_eap(
char_u *arg,
- int convert,
+ int join_list,
exarg_T *eap,
int use_simple_function)
{
@@ -627,7 +638,7 @@ eval_to_string_eap(
retval = NULL;
else
{
- retval = typval2string(&tv, convert);
+ retval = typval2string(&tv, join_list);
clear_tv(&tv);
}
clear_evalarg(&evalarg, NULL);
@@ -638,10 +649,10 @@ eval_to_string_eap(
char_u *
eval_to_string(
char_u *arg,
- int convert,
+ int join_list,
int use_simple_function)
{
- return eval_to_string_eap(arg, convert, NULL, use_simple_function);
+ return eval_to_string_eap(arg, join_list, NULL, use_simple_function);
}
/*
@@ -1119,7 +1130,18 @@ get_lval_check_access(
if (*p == '[' || *p == '.')
break;
if ((flags & GLV_READ_ONLY) == 0)
- msg = e_variable_is_not_writable_str;
+ {
+ if (IS_ENUM(cl))
+ {
+ if (om->ocm_type->tt_type == VAR_OBJECT)
+ semsg(_(e_enumvalue_str_cannot_be_modified),
+ cl->class_name, om->ocm_name);
+ else
+ msg = e_variable_is_not_writable_str;
+ }
+ else
+ msg = e_variable_is_not_writable_str;
+ }
break;
case VIM_ACCESS_ALL:
break;
@@ -1135,6 +1157,91 @@ get_lval_check_access(
}
/*
+ * Get lval information for a variable imported from script "imp_sid". On
+ * success, updates "lp" with the variable name, type, script ID and typval.
+ * The variable name starts at or after "p".
+ * If "rettv" is not NULL it points to the value to be assigned. This used to
+ * match the rhs and lhs types.
+ * Returns a pointer to the character after the variable name if the imported
+ * variable is valid and writable.
+ * Returns NULL if the variable is not exported or typval is not found or the
+ * rhs type doesn't match the lhs type or the variable is not writable.
+ */
+ static char_u *
+get_lval_imported(
+ lval_T *lp,
+ typval_T *rettv,
+ scid_T imp_sid,
+ char_u *p,
+ dictitem_T **dip,
+ int fne_flags,
+ int vim9script)
+{
+ ufunc_T *ufunc;
+ type_T *type = NULL;
+ int cc;
+ int rc = FAIL;
+
+ p = skipwhite(p);
+
+ import_check_sourced_sid(&imp_sid);
+ lp->ll_sid = imp_sid;
+ lp->ll_name = p;
+ p = find_name_end(lp->ll_name, NULL, NULL, fne_flags);
+ lp->ll_name_end = p;
+
+ // check the item is exported
+ cc = *p;
+ *p = NUL;
+ if (find_exported(imp_sid, lp->ll_name, &ufunc, &type, NULL, NULL,
+ TRUE) == -1)
+ goto failed;
+
+ if (vim9script && type != NULL)
+ {
+ where_T where = WHERE_INIT;
+
+ // In a vim9 script, do type check and make sure the variable is
+ // writable.
+ if (check_typval_type(type, rettv, where) == FAIL)
+ goto failed;
+ }
+
+ // Get the typval for the exported item
+ hashtab_T *ht = &SCRIPT_VARS(imp_sid);
+ if (ht == NULL)
+ goto failed;
+
+ dictitem_T *di = find_var_in_ht(ht, 0, lp->ll_name, TRUE);
+ if (di == NULL)
+ // script is autoloaded. So variable will be found later
+ goto success;
+
+ *dip = di;
+
+ // Check whether the variable is writable.
+ svar_T *sv = find_typval_in_script(&di->di_tv, imp_sid, FALSE);
+ if (sv != NULL && sv->sv_const != 0)
+ {
+ semsg(_(e_cannot_change_readonly_variable_str), lp->ll_name);
+ goto failed;
+ }
+
+ // check whether variable is locked
+ if (value_check_lock(di->di_tv.v_lock, lp->ll_name, FALSE))
+ goto failed;
+
+ lp->ll_tv = &di->di_tv;
+
+success:
+ rc = OK;
+
+failed:
+ *p = cc;
+ return rc == OK ? p : NULL;
+}
+
+/*
* Get an lval: variable, Dict item or List item that can be assigned a value
* to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
* "name.key", "name.key[expr]" etc.
@@ -1166,7 +1273,7 @@ get_lval(
char_u *p;
char_u *expr_start, *expr_end;
int cc;
- dictitem_T *v;
+ dictitem_T *v = NULL;
typval_T var1;
typval_T var2;
int empty1 = FALSE;
@@ -1300,28 +1407,13 @@ get_lval(
if (*p == '.')
{
imported_T *import = find_imported(lp->ll_name, p - lp->ll_name, TRUE);
-
if (import != NULL)
{
- ufunc_T *ufunc;
- type_T *type;
-
- import_check_sourced_sid(&import->imp_sid);
- lp->ll_sid = import->imp_sid;
- lp->ll_name = skipwhite(p + 1);
- p = find_name_end(lp->ll_name, NULL, NULL, fne_flags);
- lp->ll_name_end = p;
-
- // check the item is exported
- cc = *p;
- *p = NUL;
- if (find_exported(import->imp_sid, lp->ll_name, &ufunc, &type,
- NULL, NULL, TRUE) == -1)
- {
- *p = cc;
+ p++; // skip '.'
+ p = get_lval_imported(lp, rettv, import->imp_sid, p, &v,
+ fne_flags, vim9script);
+ if (p == NULL)
return NULL;
- }
- *p = cc;
}
}
@@ -1341,7 +1433,7 @@ get_lval(
lp->ll_tv = lval_root->lr_tv;
v = NULL;
}
- else
+ else if (lp->ll_tv == NULL)
{
cc = *p;
*p = NUL;
@@ -6310,9 +6402,15 @@ echo_string_core(
case VAR_CLASS:
{
class_T *cl = tv->vval.v_class;
- size_t len = 6 + (cl == NULL ? 9 : STRLEN(cl->class_name)) + 1;
+ char *s = "class";
+ if (IS_INTERFACE(cl))
+ s = "interface";
+ else if (IS_ENUM(cl))
+ s = "enum";
+ size_t len = STRLEN(s) + 1 +
+ (cl == NULL ? 9 : STRLEN(cl->class_name)) + 1;
r = *tofree = alloc(len);
- vim_snprintf((char *)r, len, "class %s",
+ vim_snprintf((char *)r, len, "%s %s", s,
cl == NULL ? "[unknown]" : (char *)cl->class_name);
}
break;
@@ -6806,7 +6904,7 @@ find_name_end(
int br_nest = 0;
char_u *p;
int len;
- int allow_curly = (flags & FNE_ALLOW_CURLY) || !in_vim9script();
+ int allow_curly = !in_vim9script();
if (expr_start != NULL)
{
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 14650ca..2064982 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -3920,7 +3920,7 @@ f_deepcopy(typval_T *argvars, typval_T *rettv)
static void
f_did_filetype(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
{
- rettv->vval.v_number = did_filetype;
+ rettv->vval.v_number = curbuf->b_did_filetype;
}
/*
@@ -6129,6 +6129,13 @@ f_has(typval_T *argvars, typval_T *rettv)
0
#endif
},
+ {"dialog_con_gui",
+#if defined(FEAT_CON_DIALOG) && defined(FEAT_GUI_DIALOG)
+ 1
+#else
+ 0
+#endif
+ },
{"dialog_gui",
#ifdef FEAT_GUI_DIALOG
1
@@ -11486,15 +11493,31 @@ f_type(typval_T *argvars, typval_T *rettv)
case VAR_CHANNEL: n = VAR_TYPE_CHANNEL; break;
case VAR_BLOB: n = VAR_TYPE_BLOB; break;
case VAR_INSTR: n = VAR_TYPE_INSTR; break;
- case VAR_CLASS: n = VAR_TYPE_CLASS; break;
- case VAR_OBJECT: n = VAR_TYPE_OBJECT; break;
case VAR_TYPEALIAS: n = VAR_TYPE_TYPEALIAS; break;
+ case VAR_CLASS:
+ {
+ class_T *cl = argvars[0].vval.v_class;
+ if (IS_ENUM(cl))
+ n = VAR_TYPE_ENUM;
+ else
+ n = VAR_TYPE_CLASS;
+ break;
+ }
+ case VAR_OBJECT:
+ {
+ class_T *cl = argvars[0].vval.v_object->obj_class;
+ if (IS_ENUM(cl))
+ n = VAR_TYPE_ENUMVALUE;
+ else
+ n = VAR_TYPE_OBJECT;
+ break;
+ }
case VAR_UNKNOWN:
case VAR_ANY:
case VAR_VOID:
- internal_error_no_abort("f_type(UNKNOWN)");
- n = -1;
- break;
+ internal_error_no_abort("f_type(UNKNOWN)");
+ n = -1;
+ break;
}
rettv->vval.v_number = n;
}
diff --git a/src/evalvars.c b/src/evalvars.c
index de9d5b2..6facbeb 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -159,6 +159,8 @@ static struct vimvar
{VV_NAME("maxcol", VAR_NUMBER), NULL, VV_RO},
{VV_NAME("python3_version", VAR_NUMBER), NULL, VV_RO},
{VV_NAME("t_typealias", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_enum", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("t_enumvalue", VAR_NUMBER), NULL, VV_RO},
};
// shorthand
@@ -262,6 +264,8 @@ evalvars_init(void)
set_vim_var_nr(VV_TYPE_CLASS, VAR_TYPE_CLASS);
set_vim_var_nr(VV_TYPE_OBJECT, VAR_TYPE_OBJECT);
set_vim_var_nr(VV_TYPE_TYPEALIAS, VAR_TYPE_TYPEALIAS);
+ set_vim_var_nr(VV_TYPE_ENUM, VAR_TYPE_ENUM);
+ set_vim_var_nr(VV_TYPE_ENUMVALUE, VAR_TYPE_ENUMVALUE);
set_vim_var_nr(VV_ECHOSPACE, sc_col - 1);
@@ -658,7 +662,7 @@ eval_one_expr_in_str(char_u *p, garray_T *gap, int evaluate)
if (evaluate)
{
*block_end = NUL;
- expr_val = eval_to_string(block_start, TRUE, FALSE);
+ expr_val = eval_to_string(block_start, FALSE, FALSE);
*block_end = '}';
if (expr_val == NULL)
return NULL;
@@ -775,8 +779,17 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
int eval_failed = FALSE;
cctx_T *cctx = vim9compile ? eap->cookie : NULL;
int count = 0;
+ int heredoc_in_string = FALSE;
+ char_u *line_arg = NULL;
+ char_u *nl_ptr = vim_strchr(cmd, '\n');
- if (eap->ea_getline == NULL)
+ if (nl_ptr != NULL)
+ {
+ heredoc_in_string = TRUE;
+ line_arg = nl_ptr + 1;
+ *nl_ptr = NUL;
+ }
+ else if (eap->ea_getline == NULL)
{
emsg(_(e_cannot_use_heredoc_here));
return NULL;
@@ -855,12 +868,38 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
int mi = 0;
int ti = 0;
- vim_free(theline);
- theline = eap->ea_getline(NUL, eap->cookie, 0, FALSE);
- if (theline == NULL)
+ if (heredoc_in_string)
{
- semsg(_(e_missing_end_marker_str), marker);
- break;
+ char_u *next_line;
+
+ // heredoc in a string separated by newlines. Get the next line
+ // from the string.
+
+ if (*line_arg == NUL)
+ {
+ semsg(_(e_missing_end_marker_str), marker);
+ break;
+ }
+
+ theline = line_arg;
+ next_line = vim_strchr(theline, '\n');
+ if (next_line == NULL)
+ line_arg += STRLEN(line_arg);
+ else
+ {
+ *next_line = NUL;
+ line_arg = next_line + 1;
+ }
+ }
+ else
+ {
+ vim_free(theline);
+ theline = eap->ea_getline(NUL, eap->cookie, 0, FALSE);
+ if (theline == NULL)
+ {
+ semsg(_(e_missing_end_marker_str), marker);
+ break;
+ }
}
// with "trim": skip the indent matching the :let line to find the
@@ -907,6 +946,8 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
}
else
{
+ int free_str = FALSE;
+
if (evalstr && !eap->skip)
{
str = eval_all_expr_in_str(str);
@@ -916,15 +957,20 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
eval_failed = TRUE;
continue;
}
- vim_free(theline);
- theline = str;
+ free_str = TRUE;
}
if (list_append_string(l, str, -1) == FAIL)
break;
+ if (free_str)
+ vim_free(str);
}
}
- vim_free(theline);
+ if (heredoc_in_string)
+ // Next command follows the heredoc in the string.
+ eap->nextcmd = line_arg;
+ else
+ vim_free(theline);
vim_free(text_indent);
if (vim9compile && cctx->ctx_skip != SKIP_YES && !eval_failed)
@@ -3294,12 +3340,31 @@ find_var(char_u *name, hashtab_T **htp, int no_autoload)
}
}
+ // and finally try
+ return find_var_autoload_prefix(name, 0, htp, NULL);
+}
+
+/*
+ * Find variable "name" with sn_autoload_prefix.
+ * Return a pointer to it if found, NULL if not found.
+ * When "sid" > 0, use it otherwise use "current_sctx.sc_sid".
+ * When "htp" is not NULL set "htp" to the hashtab_T used.
+ * When "namep" is not NULL set "namep" to the generated name, and
+ * then the caller gets ownership and is responsible for freeing the name.
+ */
+ dictitem_T *
+find_var_autoload_prefix(char_u *name, int sid, hashtab_T **htp,
+ char_u **namep)
+{
+ hashtab_T *ht;
+ dictitem_T *ret = NULL;
// When using "vim9script autoload" script-local items are prefixed but can
// be used with s:name.
- if (SCRIPT_ID_VALID(current_sctx.sc_sid)
+ int check_sid = sid > 0 ? sid : current_sctx.sc_sid;
+ if (SCRIPT_ID_VALID(check_sid)
&& (in_vim9script() || (name[0] == 's' && name[1] == ':')))
{
- scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
+ scriptitem_T *si = SCRIPT_ITEM(check_sid);
if (si->sn_autoload_prefix != NULL)
{
@@ -3309,20 +3374,26 @@ find_var(char_u *name, hashtab_T **htp, int no_autoload)
if (auto_name != NULL)
{
+ int free_auto_name = TRUE;
ht = &globvarht;
ret = find_var_in_ht(ht, 'g', auto_name, TRUE);
- vim_free(auto_name);
if (ret != NULL)
{
if (htp != NULL)
*htp = ht;
- return ret;
+ if (namep != NULL)
+ {
+ free_auto_name = FALSE;
+ *namep = auto_name;
+ }
}
+ if (free_auto_name)
+ vim_free(auto_name);
}
}
}
- return NULL;
+ return ret;
}
/*
@@ -3462,7 +3533,11 @@ lookup_scriptitem(
hi = hash_find(ht, p);
res = HASHITEM_EMPTY(hi) ? FAIL : OK;
- // if not script-local, then perhaps imported
+ // if not script-local, then perhaps autoload-exported
+ if (res == FAIL && find_var_autoload_prefix(p, 0, NULL, NULL) != NULL)
+ res = OK;
+
+ // if not script-local or autoload, then perhaps imported
if (res == FAIL && find_imported(p, 0, FALSE) != NULL)
res = OK;
if (p != buffer)
@@ -3858,23 +3933,40 @@ set_var_const(
if (sid != 0)
{
+ varname = NULL;
if (SCRIPT_ID_VALID(sid))
- ht = &SCRIPT_VARS(sid);
- varname = name;
+ {
+ char_u *auto_name = NULL;
+ if (find_var_autoload_prefix(name, sid, &ht, &auto_name) != NULL)
+ {
+ var_in_autoload = TRUE;
+ varname = auto_name;
+ name_tofree = varname;
+ }
+ else
+ ht = &SCRIPT_VARS(sid);
+ }
+ if (varname == NULL)
+ varname = name;
}
else
{
- scriptitem_T *si;
+ scriptitem_T *si;
+ char_u *auto_name = NULL;
- if (in_vim9script() && is_export
- && SCRIPT_ID_VALID(current_sctx.sc_sid)
- && (si = SCRIPT_ITEM(current_sctx.sc_sid))
- ->sn_autoload_prefix != NULL)
+ if (in_vim9script()
+ && SCRIPT_ID_VALID(current_sctx.sc_sid)
+ && (si = SCRIPT_ITEM(current_sctx.sc_sid))
+ ->sn_autoload_prefix != NULL
+ && (is_export
+ || find_var_autoload_prefix(name, 0, NULL, &auto_name)
+ != NULL))
{
// In a vim9 autoload script an exported variable is put in the
// global namespace with the autoload prefix.
var_in_autoload = TRUE;
- varname = concat_str(si->sn_autoload_prefix, name);
+ varname = auto_name != NULL ? auto_name
+ : concat_str(si->sn_autoload_prefix, name);
if (varname == NULL)
goto failed;
name_tofree = varname;
@@ -4143,6 +4235,7 @@ failed:
* - Whether the variable is read-only
* - Whether the variable value is locked
* - Whether the variable is locked
+ * NOTE: "name" is only used for error messages.
*/
int
var_check_permission(dictitem_T *di, char_u *name)
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 864f89d..2a5d842 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -2961,7 +2961,7 @@ do_ecmd(
// Since we are starting to edit a file, consider the filetype to be
// unset. Helps for when an autocommand changes files and expects syntax
// highlighting to work in the other file.
- did_filetype = FALSE;
+ curbuf->b_did_filetype = FALSE;
/*
* other_file oldbuf
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index bd26e81..70e5770 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -99,13 +99,14 @@ typedef struct exarg exarg_T;
*/
#ifdef DO_DECLARE_EXCMD
# define EXCMD(a, b, c, d, e) \
- {(char_u *)b, c, (long_u)(d), e}
+ {(char_u *)b, STRLEN_LITERAL(b), c, (long_u)(d), e}
typedef void (*ex_func_T) (exarg_T *eap);
static struct cmdname
{
char_u *cmd_name; // name of the command
+ size_t cmd_namelen; // length of the command name
ex_func_T cmd_func; // function for this command
long_u cmd_argt; // flags declared above
cmd_addr_T cmd_addr_type; // flag for address type
@@ -595,7 +596,7 @@ EXCMD(CMD_endwhile, "endwhile", ex_endwhile,
EXCMD(CMD_enew, "enew", ex_edit,
EX_BANG|EX_TRLBAR,
ADDR_NONE),
-EXCMD(CMD_enum, "enum", ex_enum,
+EXCMD(CMD_enum, "enum", ex_class,
EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT,
ADDR_NONE),
EXCMD(CMD_eval, "eval", ex_eval,
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 4a6f519..ce30b8d 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -163,7 +163,7 @@ dialog_changed(
char_u buff[DIALOG_MSG_SIZE];
int ret;
buf_T *buf2;
- exarg_T ea;
+ exarg_T ea;
dialog_msg(buff, _("Save changes to \"%s\"?"), buf->b_fname);
if (checkall)
@@ -177,14 +177,31 @@ dialog_changed(
if (ret == VIM_YES)
{
+ int empty_bufname;
+
#ifdef FEAT_BROWSE
// May get file name, when there is none
browse_save_fname(buf);
#endif
- if (buf->b_fname != NULL && check_overwrite(&ea, buf,
- buf->b_fname, buf->b_ffname, FALSE) == OK)
+ empty_bufname = buf->b_fname == NULL ? TRUE : FALSE;
+ if (empty_bufname)
+ buf_set_name(buf->b_fnum, (char_u *)"Untitled");
+
+ if (check_overwrite(&ea, buf, buf->b_fname, buf->b_ffname, FALSE) == OK)
+ {
// didn't hit Cancel
- (void)buf_write_all(buf, FALSE);
+ if (buf_write_all(buf, FALSE) == OK)
+ return;
+ }
+
+ // restore to empty when write failed
+ if (empty_bufname)
+ {
+ VIM_CLEAR(buf->b_fname);
+ VIM_CLEAR(buf->b_ffname);
+ VIM_CLEAR(buf->b_sfname);
+ unchanged(buf, TRUE, FALSE);
+ }
}
else if (ret == VIM_NO)
{
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 19b1d85..a588f26 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -19,6 +19,10 @@ static int ex_pressedreturn = FALSE;
# define ex_hardcopy ex_ni
#endif
+#if defined(FEAT_EVAL) || defined(PROTO)
+static int cmp_cmdmod_info(const void *a, const void *b);
+#endif
+
#ifdef FEAT_EVAL
static char_u *do_one_cmd(char_u **, int, cstack_T *, char_u *(*fgetline)(int, void *, int, getline_opt_T), void *cookie);
#else
@@ -82,7 +86,7 @@ static void correct_range(exarg_T *eap);
#ifdef FEAT_QUICKFIX
static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep);
#endif
-static char_u *repl_cmdline(exarg_T *eap, char_u *src, int srclen, char_u *repl, char_u **cmdlinep);
+static char_u *repl_cmdline(exarg_T *eap, char_u *src, size_t srclen, char_u *repl, char_u **cmdlinep);
static void ex_highlight(exarg_T *eap);
static void ex_colorscheme(exarg_T *eap);
static void ex_cquit(exarg_T *eap);
@@ -461,6 +465,40 @@ restore_dbg_stuff(struct dbg_stuff *dsp)
#endif
/*
+ * Check if ffname differs from fnum.
+ * fnum is a buffer number. 0 == current buffer, 1-or-more must be a valid buffer ID.
+ * ffname is a full path to where a buffer lives on-disk or would live on-disk.
+ *
+ */
+ static int
+is_other_file(int fnum, char_u *ffname)
+{
+ if (fnum != 0)
+ {
+ if (fnum == curbuf->b_fnum)
+ return FALSE;
+
+ return TRUE;
+ }
+
+ if (ffname == NULL)
+ return TRUE;
+
+ if (*ffname == NUL)
+ return FALSE;
+
+ // TODO: Need a reliable way to know whether a buffer is meant to live on-disk
+ // !curbuf->b_dev_valid is not always available (example: missing on Windows)
+ if (curbuf->b_sfname != NULL
+ && *curbuf->b_sfname != NUL)
+ // This occurs with unsaved buffers. In which case `ffname`
+ // actually corresponds to curbuf->b_sfname
+ return fnamecmp(ffname, curbuf->b_sfname) != 0;
+
+ return otherfile(ffname);
+}
+
+/*
* do_exmode(): Repeatedly get commands for the "Ex" mode, until the ":vi"
* command is given.
*/
@@ -2911,7 +2949,7 @@ parse_command_modifiers(
switch (*p)
{
- // When adding an entry, also modify cmdmods[].
+ // When adding an entry, also modify cmdmod_info_tab[].
case 'a': if (!checkforcmd_noparen(&eap->cmd, "aboveleft", 3))
break;
cmod->cmod_split |= WSP_ABOVE;
@@ -3921,7 +3959,7 @@ find_ex_command(
if (eap->cmdidx == CMD_mode || eap->cmdidx == CMD_Print)
eap->cmdidx = CMD_SIZE;
else if ((cmdnames[eap->cmdidx].cmd_argt & EX_WHOLE)
- && len < (int)STRLEN(cmdnames[eap->cmdidx].cmd_name))
+ && len < (int)cmdnames[eap->cmdidx].cmd_namelen)
{
semsg(_(e_command_cannot_be_shortened_str), eap->cmd);
eap->cmdidx = CMD_SIZE;
@@ -3970,12 +4008,14 @@ find_ex_command(
}
#if defined(FEAT_EVAL) || defined(PROTO)
-static struct cmdmod
+typedef struct
{
char *name;
int minlen;
int has_count; // :123verbose :3tab
-} cmdmods[] = {
+} cmdmod_info_T;
+
+static cmdmod_info_T cmdmod_info_tab[] = {
{"aboveleft", 3, FALSE},
{"belowright", 3, FALSE},
{"botright", 2, FALSE},
@@ -4001,8 +4041,18 @@ static struct cmdmod
{"unsilent", 3, FALSE},
{"verbose", 4, TRUE},
{"vertical", 4, FALSE},
- {"vim9cmd", 4, FALSE},
-};
+ {"vim9cmd", 4, FALSE}
+}; // cmdmod_info_tab
+
+// compare two cmdmod_info_T structs by case sensitive name with length
+ static int
+cmp_cmdmod_info(const void *a, const void *b)
+{
+ cmdmod_info_T *cm1 = (cmdmod_info_T *)a;
+ cmdmod_info_T *cm2 = (cmdmod_info_T *)b;
+
+ return STRNCMP(cm1->name, cm2->name, cm2->minlen);
+}
/*
* Return length of a command modifier (including optional count).
@@ -4011,20 +4061,36 @@ static struct cmdmod
int
modifier_len(char_u *cmd)
{
- int i, j;
char_u *p = cmd;
+ cmdmod_info_T target;
+ cmdmod_info_T *entry;
if (VIM_ISDIGIT(*cmd))
p = skipwhite(skipdigits(cmd + 1));
- for (i = 0; i < (int)ARRAY_LENGTH(cmdmods); ++i)
+
+ // only lowercase characters can match
+ if (!ASCII_ISLOWER(*p))
+ return 0;
+
+ target.name = (char *)p;
+ target.minlen = 0; // not used, see cmp_cmdmod_info()
+ target.has_count = FALSE;
+
+ entry = (cmdmod_info_T *)bsearch(&target, &cmdmod_info_tab, ARRAY_LENGTH(cmdmod_info_tab), sizeof(cmdmod_info_tab[0]), cmp_cmdmod_info);
+ if (entry != NULL)
{
- for (j = 0; p[j] != NUL; ++j)
- if (p[j] != cmdmods[i].name[j])
+ int i;
+
+ for (i = entry->minlen; p[i] != NUL; ++i)
+ {
+ if (p[i] != entry->name[i])
break;
- if (!ASCII_ISALPHA(p[j]) && j >= cmdmods[i].minlen
- && (p == cmd || cmdmods[i].has_count))
- return j + (int)(p - cmd);
+ }
+
+ if (!ASCII_ISALPHA(p[i]) && i >= entry->minlen && (p == cmd || entry->has_count))
+ return i + (int)(p - cmd);
}
+
return 0;
}
@@ -4038,18 +4104,33 @@ cmd_exists(char_u *name)
{
exarg_T ea;
int full = FALSE;
- int i;
- int j;
char_u *p;
- // Check command modifiers.
- for (i = 0; i < (int)ARRAY_LENGTH(cmdmods); ++i)
+ // only lowercase characters can match
+ if (ASCII_ISLOWER(*name))
{
- for (j = 0; name[j] != NUL; ++j)
- if (name[j] != cmdmods[i].name[j])
- break;
- if (name[j] == NUL && j >= cmdmods[i].minlen)
- return (cmdmods[i].name[j] == NUL ? 2 : 1);
+ cmdmod_info_T target;
+ cmdmod_info_T *entry;
+
+ target.name = (char *)name;
+ target.minlen = 0; // not used, see cmp_cmdmod_info()
+ target.has_count = FALSE;
+
+ // Check command modifiers.
+ entry = (cmdmod_info_T *)bsearch(&target, &cmdmod_info_tab, ARRAY_LENGTH(cmdmod_info_tab), sizeof(cmdmod_info_tab[0]), cmp_cmdmod_info);
+ if (entry != NULL)
+ {
+ int i;
+
+ for (i = entry->minlen; name[i] != NUL; ++i)
+ {
+ if (name[i] != entry->name[i])
+ break;
+ }
+
+ if (name[i] == NUL && i >= entry->minlen)
+ return (entry->name[i] == NUL ? 2 : 1);
+ }
}
// Check built-in commands and user defined commands.
@@ -4963,12 +5044,14 @@ replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep)
}
else
{
- new_cmdline = alloc(STRLEN(program) + STRLEN(p) + 2);
+ size_t program_len = STRLEN(program);
+
+ new_cmdline = alloc(program_len + STRLEN(p) + 2);
if (new_cmdline == NULL)
return NULL; // out of memory
STRCPY(new_cmdline, program);
- STRCAT(new_cmdline, " ");
- STRCAT(new_cmdline, p);
+ STRCPY(new_cmdline + program_len, " ");
+ STRCPY(new_cmdline + program_len + 1, p);
}
msg_make(p);
@@ -5118,7 +5201,7 @@ expand_filename(
}
}
- p = repl_cmdline(eap, p, srclen, repl, cmdlinep);
+ p = repl_cmdline(eap, p, (size_t)srclen, repl, cmdlinep);
vim_free(repl);
if (p == NULL)
return FAIL;
@@ -5189,7 +5272,7 @@ expand_filename(
}
if (p != NULL)
{
- (void)repl_cmdline(eap, eap->arg, (int)STRLEN(eap->arg),
+ (void)repl_cmdline(eap, eap->arg, STRLEN(eap->arg),
p, cmdlinep);
if (n == 2) // p came from ExpandOne()
vim_free(p);
@@ -5212,23 +5295,26 @@ expand_filename(
repl_cmdline(
exarg_T *eap,
char_u *src,
- int srclen,
+ size_t srclen,
char_u *repl,
char_u **cmdlinep)
{
- int len;
- int i;
+ size_t repllen;
+ size_t taillen;
+ size_t i;
char_u *new_cmdline;
+ size_t new_cmdlinelen;
/*
* The new command line is build in new_cmdline[].
* First allocate it.
* Careful: a "+cmd" argument may have been NUL terminated.
*/
- len = (int)STRLEN(repl);
- i = (int)(src - *cmdlinep) + (int)STRLEN(src + srclen) + len + 3;
+ repllen = STRLEN(repl);
+ taillen = STRLEN(src + srclen);
+ i = (src - *cmdlinep) + repllen + taillen + 3;
if (eap->nextcmd != NULL)
- i += (int)STRLEN(eap->nextcmd);// add space for next command
+ i += STRLEN(eap->nextcmd); // add space for next command
if ((new_cmdline = alloc(i)) == NULL)
return NULL; // out of memory!
@@ -5238,19 +5324,19 @@ repl_cmdline(
* Copy what came after the expanded part.
* Copy the next commands, if there are any.
*/
- i = (int)(src - *cmdlinep); // length of part before match
- mch_memmove(new_cmdline, *cmdlinep, (size_t)i);
+ new_cmdlinelen = src - *cmdlinep; // length of part before replacement
+ mch_memmove(new_cmdline, *cmdlinep, new_cmdlinelen);
- mch_memmove(new_cmdline + i, repl, (size_t)len);
- i += len; // remember the end of the string
- STRCPY(new_cmdline + i, src + srclen);
- src = new_cmdline + i; // remember where to continue
+ mch_memmove(new_cmdline + new_cmdlinelen, repl, repllen);
+ new_cmdlinelen += repllen; // remember the end of the string
+ STRCPY(new_cmdline + new_cmdlinelen, src + srclen);
+ src = new_cmdline + new_cmdlinelen; // remember where to continue
if (eap->nextcmd != NULL) // append next command
{
- i = (int)STRLEN(new_cmdline) + 1;
- STRCPY(new_cmdline + i, eap->nextcmd);
- eap->nextcmd = new_cmdline + i;
+ new_cmdlinelen += taillen + 1;
+ STRCPY(new_cmdline + new_cmdlinelen, eap->nextcmd);
+ eap->nextcmd = new_cmdline + new_cmdlinelen;
}
eap->cmd = new_cmdline + (eap->cmd - *cmdlinep);
eap->arg = new_cmdline + (eap->arg - *cmdlinep);
@@ -5421,9 +5507,10 @@ get_bad_name(expand_T *xp UNUSED, int idx)
"drop",
};
- if (idx < (int)ARRAY_LENGTH(p_bad_values))
- return (char_u*)p_bad_values[idx];
- return NULL;
+ if (idx < 0 || idx >= (int)ARRAY_LENGTH(p_bad_values))
+ return NULL;
+
+ return (char_u*)p_bad_values[idx];
}
/*
@@ -5537,9 +5624,10 @@ get_argopt_name(expand_T *xp UNUSED, int idx)
"edit",
};
- if (idx < (int)ARRAY_LENGTH(p_opt_values))
- return (char_u*)p_opt_values[idx];
- return NULL;
+ if (idx < 0 || idx >= (int)ARRAY_LENGTH(p_opt_values))
+ return NULL;
+
+ return (char_u*)p_opt_values[idx];
}
/*
@@ -6317,11 +6405,19 @@ get_tabpage_arg(exarg_T *eap)
else
{
tab_number = eap->line2;
- if (!unaccept_arg0 && *skipwhite(*eap->cmdlinep) == '-')
+ if (!unaccept_arg0)
{
- --tab_number;
- if (tab_number < unaccept_arg0)
- eap->errmsg = _(e_invalid_range);
+ char_u *cmdp = eap->cmd;
+
+ while (--cmdp > *eap->cmdlinep
+ && (VIM_ISWHITE(*cmdp) || VIM_ISDIGIT(*cmdp)))
+ ;
+ if (*cmdp == '-')
+ {
+ --tab_number;
+ if (tab_number < unaccept_arg0)
+ eap->errmsg = _(e_invalid_range);
+ }
}
}
}
@@ -7248,12 +7344,15 @@ ex_open(exarg_T *eap)
static void
ex_edit(exarg_T *eap)
{
+ char_u *ffname = eap->cmdidx == CMD_enew ? NULL : eap->arg;
+
// Exclude commands which keep the window's current buffer
if (
eap->cmdidx != CMD_badd
&& eap->cmdidx != CMD_balt
// All other commands must obey 'winfixbuf' / ! rules
- && !check_can_set_curbuf_forceit(eap->forceit))
+ && (is_other_file(0, ffname) && !check_can_set_curbuf_forceit(eap->forceit))
+ )
return;
do_exedit(eap, NULL);
@@ -9237,6 +9336,27 @@ ex_tag_cmd(exarg_T *eap, char_u *name)
eap->forceit, TRUE);
}
+enum {
+ SPEC_PERC = 0,
+ SPEC_HASH,
+ SPEC_CWORD, // cursor word
+ SPEC_CCWORD, // cursor WORD
+ SPEC_CEXPR, // expr under cursor
+ SPEC_CFILE, // cursor path name
+ SPEC_SFILE, // ":so" file name
+ SPEC_SLNUM, // ":so" file line number
+ SPEC_STACK, // call stack
+ SPEC_SCRIPT, // script file name
+ SPEC_AFILE, // autocommand file name
+ SPEC_ABUF, // autocommand buffer number
+ SPEC_AMATCH, // autocommand match name
+ SPEC_SFLNUM, // script file line number
+ SPEC_SID // script ID: <SNR>123_
+#ifdef FEAT_CLIENTSERVER
+ , SPEC_CLIENT
+#endif
+};
+
/*
* Check "str" for starting with a special cmdline variable.
* If found return one of the SPEC_ values and set "*usedlen" to the length of
@@ -9245,54 +9365,54 @@ ex_tag_cmd(exarg_T *eap, char_u *name)
int
find_cmdline_var(char_u *src, int *usedlen)
{
- int len;
- int i;
- static char *(spec_str[]) = {
- "%",
-#define SPEC_PERC 0
- "#",
-#define SPEC_HASH (SPEC_PERC + 1)
- "<cword>", // cursor word
-#define SPEC_CWORD (SPEC_HASH + 1)
- "<cWORD>", // cursor WORD
-#define SPEC_CCWORD (SPEC_CWORD + 1)
- "<cexpr>", // expr under cursor
-#define SPEC_CEXPR (SPEC_CCWORD + 1)
- "<cfile>", // cursor path name
-#define SPEC_CFILE (SPEC_CEXPR + 1)
- "<sfile>", // ":so" file name
-#define SPEC_SFILE (SPEC_CFILE + 1)
- "<slnum>", // ":so" file line number
-#define SPEC_SLNUM (SPEC_SFILE + 1)
- "<stack>", // call stack
-#define SPEC_STACK (SPEC_SLNUM + 1)
- "<script>", // script file name
-#define SPEC_SCRIPT (SPEC_STACK + 1)
- "<afile>", // autocommand file name
-#define SPEC_AFILE (SPEC_SCRIPT + 1)
- "<abuf>", // autocommand buffer number
-#define SPEC_ABUF (SPEC_AFILE + 1)
- "<amatch>", // autocommand match name
-#define SPEC_AMATCH (SPEC_ABUF + 1)
- "<sflnum>", // script file line number
-#define SPEC_SFLNUM (SPEC_AMATCH + 1)
- "<SID>", // script ID: <SNR>123_
-#define SPEC_SID (SPEC_SFLNUM + 1)
+ // must be sorted by the 'value' field because it is used by bsearch()!
+ static keyvalue_T spec_str_tab[] = {
+ KEYVALUE_ENTRY(SPEC_SID, "SID>"), // script ID: <SNR>123_
+ KEYVALUE_ENTRY(SPEC_ABUF, "abuf>"), // autocommand buffer number
+ KEYVALUE_ENTRY(SPEC_AFILE, "afile>"), // autocommand file name
+ KEYVALUE_ENTRY(SPEC_AMATCH, "amatch>"), // autocommand match name
+ KEYVALUE_ENTRY(SPEC_CCWORD, "cWORD>"), // cursor WORD
+ KEYVALUE_ENTRY(SPEC_CEXPR, "cexpr>"), // expr under cursor
+ KEYVALUE_ENTRY(SPEC_CFILE, "cfile>"), // cursor path name
#ifdef FEAT_CLIENTSERVER
- "<client>"
-# define SPEC_CLIENT (SPEC_SID + 1)
-#endif
+ KEYVALUE_ENTRY(SPEC_CLIENT, "client>"),
+#endif
+ KEYVALUE_ENTRY(SPEC_CWORD, "cword>"), // cursor word
+ KEYVALUE_ENTRY(SPEC_SCRIPT, "script>"), // script file name
+ KEYVALUE_ENTRY(SPEC_SFILE, "sfile>"), // ":so" file name
+ KEYVALUE_ENTRY(SPEC_SFLNUM, "sflnum>"), // script file line number
+ KEYVALUE_ENTRY(SPEC_SLNUM, "slnum>"), // ":so" file line number
+ KEYVALUE_ENTRY(SPEC_STACK, "stack>") // call stack
};
+ keyvalue_T target;
+ keyvalue_T *entry;
- for (i = 0; i < (int)ARRAY_LENGTH(spec_str); ++i)
+ switch (*src)
{
- len = (int)STRLEN(spec_str[i]);
- if (STRNCMP(src, spec_str[i], len) == 0)
- {
- *usedlen = len;
- return i;
- }
+ case '%':
+ *usedlen = 1;
+ return SPEC_PERC;
+
+ case '#':
+ *usedlen = 1;
+ return SPEC_HASH;
+
+ case '<':
+ target.key = 0;
+ target.value = (char *)src + 1; // skip over '<'
+ target.length = 0; // not used, see cmp_keyvalue_value_n()
+
+ entry = (keyvalue_T *)bsearch(&target, &spec_str_tab, ARRAY_LENGTH(spec_str_tab), sizeof(spec_str_tab[0]), cmp_keyvalue_value_n);
+ if (entry == NULL)
+ return -1;
+
+ *usedlen = entry->length + 1;
+ return entry->key;
+
+ default:
+ break;
}
+
return -1;
}
@@ -9655,14 +9775,17 @@ eval_vars(
expand_sfile(char_u *arg)
{
char *errormsg;
- int len;
char_u *result;
+ size_t resultlen;
char_u *newres;
+ size_t len;
char_u *repl;
+ size_t repllen;
int srclen;
char_u *p;
- result = vim_strsave(arg);
+ resultlen = STRLEN(arg);
+ result = vim_strnsave(arg, resultlen);
if (result == NULL)
return NULL;
@@ -9686,18 +9809,20 @@ expand_sfile(char_u *arg)
p += srclen;
continue;
}
- len = (int)STRLEN(result) - srclen + (int)STRLEN(repl) + 1;
- newres = alloc(len);
+ repllen = STRLEN(repl);
+ resultlen += repllen - srclen;
+ newres = alloc(resultlen + 1);
if (newres == NULL)
{
vim_free(repl);
vim_free(result);
return NULL;
}
- mch_memmove(newres, result, (size_t)(p - result));
- STRCPY(newres + (p - result), repl);
- len = (int)STRLEN(newres);
- STRCAT(newres, p + srclen);
+ len = p - result;
+ mch_memmove(newres, result, len);
+ STRCPY(newres + len, repl);
+ len += repllen;
+ STRCPY(newres + len, p + srclen);
vim_free(repl);
vim_free(result);
result = newres;
@@ -9853,7 +9978,7 @@ ex_filetype(exarg_T *eap)
static void
ex_setfiletype(exarg_T *eap)
{
- if (did_filetype)
+ if (curbuf->b_did_filetype)
return;
char_u *arg = eap->arg;
@@ -9862,7 +9987,7 @@ ex_setfiletype(exarg_T *eap)
set_option_value_give_err((char_u *)"filetype", 0L, arg, OPT_LOCAL);
if (arg != eap->arg)
- did_filetype = FALSE;
+ curbuf->b_did_filetype = FALSE;
}
static void
diff --git a/src/fileio.c b/src/fileio.c
index 53bfbea..07e05fc 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -225,7 +225,7 @@ readfile(
int may_need_lseek = FALSE;
#endif
- au_did_filetype = FALSE; // reset before triggering any autocommands
+ curbuf->b_au_did_filetype = FALSE; // reset before triggering any autocommands
curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read
@@ -2696,7 +2696,7 @@ failed:
{
apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname,
FALSE, curbuf, eap);
- if (!au_did_filetype && *curbuf->b_p_ft != NUL)
+ if (!curbuf->b_au_did_filetype && *curbuf->b_p_ft != NUL)
/*
* EVENT_FILETYPE was not triggered but the buffer already has a
* filetype. Trigger EVENT_FILETYPE using the existing filetype.
@@ -4492,7 +4492,7 @@ buf_reload(buf_T *buf, int orig_mode, int reload_options)
int old_msg_silent = msg_silent;
curbuf->b_flags |= BF_CHECK_RO; // check for RO again
- keep_filetype = TRUE; // don't detect 'filetype'
+ curbuf->b_keep_filetype = TRUE; // don't detect 'filetype'
if (shortmess(SHM_FILEINFO))
msg_silent = 1;
@@ -4549,7 +4549,7 @@ buf_reload(buf_T *buf, int orig_mode, int reload_options)
curwin->w_cursor = old_cursor;
check_cursor();
update_topline();
- keep_filetype = FALSE;
+ curbuf->b_keep_filetype = FALSE;
#ifdef FEAT_FOLDING
{
win_T *wp;
diff --git a/src/filepath.c b/src/filepath.c
index cbf2da4..3bf8a2d 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -2110,6 +2110,7 @@ f_resolve(typval_T *argvars, typval_T *rettv)
if (buf == NULL)
{
vim_free(p);
+ vim_free(remain);
goto fail;
}
diff --git a/src/getchar.c b/src/getchar.c
index 49a24f0..1c544da 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -81,7 +81,7 @@ static int KeyNoremap = 0; // remapping flags
static char_u typebuf_init[TYPELEN_INIT]; // initial typebuf.tb_buf
static char_u noremapbuf_init[TYPELEN_INIT]; // initial typebuf.tb_noremap
-static int last_recorded_len = 0; // number of last recorded chars
+static size_t last_recorded_len = 0; // number of last recorded chars
#ifdef FEAT_EVAL
mapblock_T *last_used_map = NULL;
@@ -163,7 +163,7 @@ get_recorded(void)
* (possibly mapped) characters that stopped the recording.
*/
len = STRLEN(p);
- if ((int)len >= last_recorded_len)
+ if (len >= last_recorded_len)
{
len -= last_recorded_len;
p[len] = NUL;
@@ -1282,50 +1282,104 @@ del_typebuf(int len, int offset)
}
/*
+ * State for adding bytes to a recording or 'showcmd'.
+ */
+typedef struct
+{
+ char_u buf[MB_MAXBYTES * 3 + 4];
+ int prev_c;
+ size_t buflen;
+ unsigned pending_special;
+ unsigned pending_mbyte;
+} gotchars_state_T;
+
+/*
+ * Add a single byte to a recording or 'showcmd'.
+ * Return TRUE if a full key has been received, FALSE otherwise.
+ */
+ static int
+gotchars_add_byte(gotchars_state_T *state, char_u byte)
+{
+ int c = state->buf[state->buflen++] = byte;
+ int retval = FALSE;
+ int in_special = state->pending_special > 0;
+ int in_mbyte = state->pending_mbyte > 0;
+
+ if (in_special)
+ state->pending_special--;
+ else if (c == K_SPECIAL
+#ifdef FEAT_GUI
+ || c == CSI
+#endif
+ )
+ // When receiving a special key sequence, store it until we have all
+ // the bytes and we can decide what to do with it.
+ state->pending_special = 2;
+
+ if (state->pending_special > 0)
+ goto ret_false;
+
+ if (in_mbyte)
+ state->pending_mbyte--;
+ else
+ {
+ if (in_special)
+ {
+ if (state->prev_c == KS_MODIFIER)
+ // When receiving a modifier, wait for the modified key.
+ goto ret_false;
+ c = TO_SPECIAL(state->prev_c, c);
+ if (c == K_FOCUSGAINED || c == K_FOCUSLOST)
+ // Drop K_FOCUSGAINED and K_FOCUSLOST, they are not useful
+ // in a recording.
+ state->buflen = 0;
+ }
+ // When receiving a multibyte character, store it until we have all
+ // the bytes, so that it won't be split between two buffer blocks,
+ // and delete_buff_tail() will work properly.
+ state->pending_mbyte = MB_BYTE2LEN_CHECK(c) - 1;
+ }
+
+ if (state->pending_mbyte > 0)
+ goto ret_false;
+
+ retval = TRUE;
+ret_false:
+ state->prev_c = c;
+ return retval;
+}
+
+/*
* Write typed characters to script file.
- * If recording is on put the character in the recordbuffer.
+ * If recording is on put the character in the record buffer.
*/
static void
gotchars(char_u *chars, int len)
{
char_u *s = chars;
- int i;
- static char_u buf[4];
- static int buflen = 0;
+ size_t i;
int todo = len;
+ static gotchars_state_T state;
- while (todo--)
+ while (todo-- > 0)
{
- buf[buflen++] = *s++;
-
- // When receiving a special key sequence, store it until we have all
- // the bytes and we can decide what to do with it.
- if (buflen == 1 && buf[0] == K_SPECIAL)
- continue;
- if (buflen == 2)
+ if (!gotchars_add_byte(&state, *s++))
continue;
- if (buflen == 3 && buf[1] == KS_EXTRA
- && (buf[2] == KE_FOCUSGAINED || buf[2] == KE_FOCUSLOST))
- {
- // Drop K_FOCUSGAINED and K_FOCUSLOST, they are not useful in a
- // recording.
- buflen = 0;
- continue;
- }
// Handle one byte at a time; no translation to be done.
- for (i = 0; i < buflen; ++i)
- updatescript(buf[i]);
+ for (i = 0; i < state.buflen; ++i)
+ updatescript(state.buf[i]);
if (reg_recording != 0)
{
- buf[buflen] = NUL;
- add_buff(&recordbuff, buf, (long)buflen);
+ state.buf[state.buflen] = NUL;
+ add_buff(&recordbuff, state.buf, (long)state.buflen);
// remember how many chars were last recorded
- last_recorded_len += buflen;
+ last_recorded_len += state.buflen;
}
- buflen = 0;
+ state.buflen = 0;
}
+
may_sync_undo();
#ifdef FEAT_EVAL
@@ -1713,6 +1767,67 @@ merge_modifyOtherKeys(int c_arg, int *modifiers)
}
/*
+ * Add a single byte to 'showcmd' for a partially matched mapping.
+ * Call add_to_showcmd() if a full key has been received.
+ */
+ static void
+add_byte_to_showcmd(char_u byte)
+{
+ static gotchars_state_T state;
+ char_u *ptr;
+ int modifiers = 0;
+ int c = NUL;
+
+ if (!p_sc || msg_silent != 0)
+ return;
+
+ if (!gotchars_add_byte(&state, byte))
+ return;
+
+ state.buf[state.buflen] = NUL;
+ state.buflen = 0;
+
+ ptr = state.buf;
+ if (ptr[0] == K_SPECIAL && ptr[1] == KS_MODIFIER && ptr[2] != NUL)
+ {
+ modifiers = ptr[2];
+ ptr += 3;
+ }
+
+ if (*ptr != NUL)
+ {
+ char_u *mb_ptr = mb_unescape(&ptr);
+
+ c = mb_ptr != NULL ? (*mb_ptr2char)(mb_ptr) : *ptr++;
+ if (c <= 0x7f)
+ {
+ // Merge modifiers into the key to make the result more readable.
+ int modifiers_after = modifiers;
+ int mod_c = merge_modifyOtherKeys(c, &modifiers_after);
+
+ if (modifiers_after == 0)
+ {
+ modifiers = 0;
+ c = mod_c;
+ }
+ }
+ }
+
+ // TODO: is there a more readable and yet compact representation of
+ // modifiers and special keys?
+ if (modifiers != 0)
+ {
+ add_to_showcmd(K_SPECIAL);
+ add_to_showcmd(KS_MODIFIER);
+ add_to_showcmd(modifiers);
+ }
+ if (c != NUL)
+ add_to_showcmd(c);
+ while (*ptr != NUL)
+ add_to_showcmd(*ptr++);
+}
+
+/*
* Get the next input character.
* Can return a special key or a multi-byte character.
* Can return NUL when called recursively, use safe_vgetc() if that's not
@@ -1751,7 +1866,7 @@ vgetc(void)
else
{
// number of characters recorded from the last vgetc() call
- static int last_vgetc_recorded_len = 0;
+ static size_t last_vgetc_recorded_len = 0;
mod_mask = 0;
vgetc_mod_mask = 0;
@@ -3544,7 +3659,7 @@ vgetorpeek(int advance)
if (typebuf.tb_len > SHOWCMD_COLS)
showcmd_idx = typebuf.tb_len - SHOWCMD_COLS;
while (showcmd_idx < typebuf.tb_len)
- (void)add_to_showcmd(
+ add_byte_to_showcmd(
typebuf.tb_buf[typebuf.tb_off + showcmd_idx++]);
curwin->w_wcol = old_wcol;
curwin->w_wrow = old_wrow;
diff --git a/src/globals.h b/src/globals.h
index f04f19d..2c00e5f 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -540,7 +540,10 @@ EXTERN int garbage_collect_at_exit INIT(= FALSE);
#define t_class (static_types[84])
#define t_const_class (static_types[85])
-EXTERN type_T static_types[86]
+#define t_typealias (static_types[86])
+#define t_const_typealias (static_types[87])
+
+EXTERN type_T static_types[88]
#ifdef DO_INIT
= {
// 0: t_unknown
@@ -714,6 +717,10 @@ EXTERN type_T static_types[86]
// 84: t_class
{VAR_CLASS, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
{VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
+
+ // 86: t_typealias
+ {VAR_TYPEALIAS, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
+ {VAR_TYPEALIAS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
}
#endif
;
@@ -796,20 +803,6 @@ EXTERN int autocmd_no_enter INIT(= FALSE); // Buf/WinEnter autocmds disabled
EXTERN int autocmd_no_leave INIT(= FALSE); // Buf/WinLeave autocmds disabled
EXTERN int tabpage_move_disallowed INIT(= FALSE); // moving tabpages around disallowed
-EXTERN int modified_was_set; // did ":set modified"
-EXTERN int did_filetype INIT(= FALSE); // FileType event found
-EXTERN int keep_filetype INIT(= FALSE); // value for did_filetype when
- // starting to execute
- // autocommands
-
-// Set by the apply_autocmds_group function if the given event is equal to
-// EVENT_FILETYPE. Used by the readfile function in order to determine if
-// EVENT_BUFREADPOST triggered the EVENT_FILETYPE.
-//
-// Relying on this value requires one to reset it prior calling
-// apply_autocmds_group.
-EXTERN int au_did_filetype INIT(= FALSE);
-
// When deleting the current buffer, another one must be loaded. If we know
// which one is preferred, au_new_curbuf is set to it
EXTERN bufref_T au_new_curbuf INIT3(NULL, 0, 0);
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index d4a8b93..4d201fc 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -2152,6 +2152,9 @@ scroll_event(GtkWidget *widget,
FALSE, vim_modifiers);
}
}
+ else if (event->direction == GDK_SCROLL_SMOOTH && display_type == DT_X11)
+ // for X11 we deal with unsmooth events, and so ignore the smooth ones
+ ;
else
#undef DT_X11
#undef DT_WAYLAND
diff --git a/src/gui_motif.c b/src/gui_motif.c
index 630082e..ed721b5 100644
--- a/src/gui_motif.c
+++ b/src/gui_motif.c
@@ -2732,7 +2732,10 @@ gui_mch_dialog(
// Motif.
label = XmStringCreateLtoR((char *)message, STRING_TAG);
if (label == NULL)
+ {
+ vim_free(buttons);
return -1;
+ }
w = XtVaCreateManagedWidget("dialogMessage",
xmLabelGadgetClass, form,
XmNlabelString, label,
diff --git a/src/highlight.c b/src/highlight.c
index 9b3b072..9aa149f 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -24,19 +24,110 @@
* The "term", "cterm" and "gui" arguments can be any combination of the
* following names, separated by commas (but no spaces!).
*/
-static char *(hl_name_table[]) =
- {"bold", "standout", "underline",
- "undercurl", "underdouble", "underdotted", "underdashed",
- "italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"};
-static int hl_attr_table[] =
- {HL_BOLD, HL_STANDOUT, HL_UNDERLINE,
- HL_UNDERCURL, HL_UNDERDOUBLE, HL_UNDERDOTTED, HL_UNDERDASHED,
- HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0};
+// must be sorted by the 'value' field because it is used by bsearch()!
+// note: inverse and reverse use the same key
+static keyvalue_T highlight_tab[] = {
+ KEYVALUE_ENTRY(HL_BOLD, "bold"), // index 0
+ KEYVALUE_ENTRY(HL_INVERSE, "inverse"), // index 1
+ KEYVALUE_ENTRY(HL_ITALIC, "italic"), // index 2
+ KEYVALUE_ENTRY(HL_NOCOMBINE, "nocombine"), // index 3
+ KEYVALUE_ENTRY(HL_NORMAL, "NONE"), // index 4
+ KEYVALUE_ENTRY(HL_INVERSE, "reverse"), // index 5
+ KEYVALUE_ENTRY(HL_STANDOUT, "standout"), // index 6
+ KEYVALUE_ENTRY(HL_STRIKETHROUGH, "strikethrough"), // index 7
+ KEYVALUE_ENTRY(HL_UNDERCURL, "undercurl"), // index 8
+ KEYVALUE_ENTRY(HL_UNDERDASHED, "underdashed"), // index 9
+ KEYVALUE_ENTRY(HL_UNDERDOTTED, "underdotted"), // index 10
+ KEYVALUE_ENTRY(HL_UNDERDOUBLE, "underdouble"), // index 11
+ KEYVALUE_ENTRY(HL_UNDERLINE, "underline") // index 12
+};
+
+// this table is used to display highlight names in the "correct" sequence.
+// keep this in sync with highlight_tab[].
+static keyvalue_T *highlight_index_tab[] = {
+ &highlight_tab[0], // HL_BOLD
+ &highlight_tab[6], // HL_STANDOUT
+ &highlight_tab[12], // HL_UNDERLINE
+ &highlight_tab[8], // HL_UNDERCURL
+ &highlight_tab[11], // HL_UNDERDOUBLE
+ &highlight_tab[10], // HL_UNDERDOTTED
+ &highlight_tab[9], // HL_UNDERDASHED
+ &highlight_tab[2], // HL_ITALIC
+ &highlight_tab[5], // HL_REVERSE
+ &highlight_tab[1], // HL_INVERSE
+ &highlight_tab[3], // HL_NOCOMBINE
+ &highlight_tab[7], // HL_STRIKETHROUGH
+ &highlight_tab[4] // HL_NORMAL
+};
+
// length of all attribute names, plus commas, together (and a bit more)
#define MAX_ATTR_LEN 120
#define ATTR_COMBINE(attr_a, attr_b) ((((attr_b) & HL_NOCOMBINE) ? (attr_b) : (attr_a)) | (attr_b))
+enum {
+ BLACK = 0,
+ DARKBLUE,
+ DARKGREEN,
+ DARKCYAN,
+ DARKRED,
+ DARKMAGENTA,
+ BROWN,
+ DARKYELLOW,
+ GRAY,
+ GREY,
+ LIGHTGRAY,
+ LIGHTGREY,
+ DARKGRAY,
+ DARKGREY,
+ BLUE,
+ LIGHTBLUE,
+ GREEN,
+ LIGHTGREEN,
+ CYAN,
+ LIGHTCYAN,
+ RED,
+ LIGHTRED,
+ MAGENTA,
+ LIGHTMAGENTA,
+ YELLOW,
+ LIGHTYELLOW,
+ WHITE,
+ NONE
+};
+
+// must be sorted by the 'value' field because it is used by bsearch()!
+static keyvalue_T color_name_tab[] = {
+ KEYVALUE_ENTRY(BLACK, "Black"),
+ KEYVALUE_ENTRY(BLUE, "Blue"),
+ KEYVALUE_ENTRY(BROWN, "Brown"),
+ KEYVALUE_ENTRY(CYAN, "Cyan"),
+ KEYVALUE_ENTRY(DARKBLUE, "DarkBlue"),
+ KEYVALUE_ENTRY(DARKCYAN, "DarkCyan"),
+ KEYVALUE_ENTRY(DARKGRAY, "DarkGray"),
+ KEYVALUE_ENTRY(DARKGREEN, "DarkGreen"),
+ KEYVALUE_ENTRY(DARKGREY, "DarkGrey"),
+ KEYVALUE_ENTRY(DARKMAGENTA, "DarkMagenta"),
+ KEYVALUE_ENTRY(DARKRED, "DarkRed"),
+ KEYVALUE_ENTRY(DARKYELLOW, "DarkYellow"),
+ KEYVALUE_ENTRY(GRAY, "Gray"),
+ KEYVALUE_ENTRY(GREEN, "Green"),
+ KEYVALUE_ENTRY(GREY, "Grey"),
+ KEYVALUE_ENTRY(LIGHTBLUE, "LightBlue"),
+ KEYVALUE_ENTRY(LIGHTCYAN, "LightCyan"),
+ KEYVALUE_ENTRY(LIGHTGRAY, "LightGray"),
+ KEYVALUE_ENTRY(LIGHTGREEN, "LightGreen"),
+ KEYVALUE_ENTRY(LIGHTGREY, "LightGrey"),
+ KEYVALUE_ENTRY(LIGHTMAGENTA, "LightMagenta"),
+ KEYVALUE_ENTRY(LIGHTRED, "LightRed"),
+ KEYVALUE_ENTRY(LIGHTYELLOW, "LightYellow"),
+ KEYVALUE_ENTRY(MAGENTA, "Magenta"),
+ KEYVALUE_ENTRY(NONE, "NONE"),
+ KEYVALUE_ENTRY(RED, "Red"),
+ KEYVALUE_ENTRY(WHITE, "White"),
+ KEYVALUE_ENTRY(YELLOW, "Yellow")
+};
+
/*
* Structure that stores information about a highlight group.
* The ID of a highlight group is also called group ID. It is the index in
@@ -518,22 +609,6 @@ load_colors(char_u *name)
return retval;
}
-static char *(color_names[28]) = {
- "Black", "DarkBlue", "DarkGreen", "DarkCyan",
- "DarkRed", "DarkMagenta", "Brown", "DarkYellow",
- "Gray", "Grey", "LightGray", "LightGrey",
- "DarkGray", "DarkGrey",
- "Blue", "LightBlue", "Green", "LightGreen",
- "Cyan", "LightCyan", "Red", "LightRed", "Magenta",
- "LightMagenta", "Yellow", "LightYellow", "White", "NONE"};
- // indices:
- // 0, 1, 2, 3,
- // 4, 5, 6, 7,
- // 8, 9, 10, 11,
- // 12, 13,
- // 14, 15, 16, 17,
- // 18, 19, 20, 21, 22,
- // 23, 24, 25, 26, 27
static int color_numbers_16[28] = {0, 1, 2, 3,
4, 5, 6, 6,
7, 7, 7, 7,
@@ -568,7 +643,7 @@ static int color_numbers_8[28] = {0, 4, 2, 6,
/*
* Lookup the "cterm" value to be used for color with index "idx" in
- * color_names[].
+ * color_name_tab[].
* "boldp" will be set to TRUE or FALSE for a foreground color when using 8
* colors, otherwise it will be unchanged.
*/
@@ -785,29 +860,26 @@ highlight_reset_all(void)
highlight_set_termgui_attr(int idx, char_u *key, char_u *arg, int init)
{
int attr;
- int off;
- long i;
- int len;
+ size_t off;
+ keyvalue_T target;
+ keyvalue_T *entry;
attr = 0;
off = 0;
+ target.key = 0;
+ target.length = 0; // not used, see cmp_keyvalue_value_ni()
while (arg[off] != NUL)
{
- for (i = ARRAY_LENGTH(hl_attr_table); --i >= 0; )
- {
- len = (int)STRLEN(hl_name_table[i]);
- if (STRNICMP(arg + off, hl_name_table[i], len) == 0)
- {
- attr |= hl_attr_table[i];
- off += len;
- break;
- }
- }
- if (i < 0)
+ target.value = (char *)arg + off;
+ entry = (keyvalue_T *)bsearch(&target, &highlight_tab, ARRAY_LENGTH(highlight_tab), sizeof(highlight_tab[0]), cmp_keyvalue_value_ni);
+ if (entry == NULL)
{
semsg(_(e_illegal_value_str), arg);
return FALSE;
}
+
+ attr |= entry->key;
+ off += entry->length;
if (arg[off] == ',') // another one follows
++off;
}
@@ -1086,8 +1158,6 @@ highlight_set_cterm_color(
int init)
{
int color;
- long i;
- int off;
if (init && (HL_TABLE()[idx].sg_set & SG_CTERM))
return FALSE;
@@ -1138,20 +1208,20 @@ highlight_set_cterm_color(
else
{
int bold = MAYBE;
-
- // reduce calls to STRICMP a bit, it can be slow
- off = TOUPPER_ASC(*arg);
- for (i = ARRAY_LENGTH(color_names); --i >= 0; )
- if (off == color_names[i][0]
- && STRICMP(arg + 1, color_names[i] + 1) == 0)
- break;
- if (i < 0)
+ keyvalue_T target;
+ keyvalue_T *entry;
+
+ target.key = 0;
+ target.value = (char *)arg;
+ target.length = 0; // not used, see cmp_keyvalue_value_i()
+ entry = (keyvalue_T *)bsearch(&target, &color_name_tab, ARRAY_LENGTH(color_name_tab), sizeof(color_name_tab[0]), cmp_keyvalue_value_i);
+ if (entry == NULL)
{
semsg(_(e_color_name_or_number_not_recognized_str), key_start);
return FALSE;
}
- color = lookup_color(i, key[5] == 'F', &bold);
+ color = lookup_color(entry->key, key[5] == 'F', &bold);
// set/reset bold attribute to get light foreground
// colors (on some terminals, e.g. "linux")
@@ -2424,58 +2494,56 @@ colorname2rgb(char_u *name)
guicolor_T
gui_get_color_cmn(char_u *name)
{
- int i;
guicolor_T color;
-
- struct rgbcolor_table_S {
- char_u *color_name;
- guicolor_T color;
- };
-
// Only non X11 colors (not present in rgb.txt) and colors in
- // color_names[], useful when $VIMRUNTIME is not found,.
- static struct rgbcolor_table_S rgb_table[] = {
- {(char_u *)"black", RGB(0x00, 0x00, 0x00)},
- {(char_u *)"blue", RGB(0x00, 0x00, 0xFF)},
- {(char_u *)"brown", RGB(0xA5, 0x2A, 0x2A)},
- {(char_u *)"cyan", RGB(0x00, 0xFF, 0xFF)},
- {(char_u *)"darkblue", RGB(0x00, 0x00, 0x8B)},
- {(char_u *)"darkcyan", RGB(0x00, 0x8B, 0x8B)},
- {(char_u *)"darkgray", RGB(0xA9, 0xA9, 0xA9)},
- {(char_u *)"darkgreen", RGB(0x00, 0x64, 0x00)},
- {(char_u *)"darkgrey", RGB(0xA9, 0xA9, 0xA9)},
- {(char_u *)"darkmagenta", RGB(0x8B, 0x00, 0x8B)},
- {(char_u *)"darkred", RGB(0x8B, 0x00, 0x00)},
- {(char_u *)"darkyellow", RGB(0x8B, 0x8B, 0x00)}, // No X11
- {(char_u *)"gray", RGB(0xBE, 0xBE, 0xBE)},
- {(char_u *)"green", RGB(0x00, 0xFF, 0x00)},
- {(char_u *)"grey", RGB(0xBE, 0xBE, 0xBE)},
- {(char_u *)"grey40", RGB(0x66, 0x66, 0x66)},
- {(char_u *)"grey50", RGB(0x7F, 0x7F, 0x7F)},
- {(char_u *)"grey90", RGB(0xE5, 0xE5, 0xE5)},
- {(char_u *)"lightblue", RGB(0xAD, 0xD8, 0xE6)},
- {(char_u *)"lightcyan", RGB(0xE0, 0xFF, 0xFF)},
- {(char_u *)"lightgray", RGB(0xD3, 0xD3, 0xD3)},
- {(char_u *)"lightgreen", RGB(0x90, 0xEE, 0x90)},
- {(char_u *)"lightgrey", RGB(0xD3, 0xD3, 0xD3)},
- {(char_u *)"lightmagenta", RGB(0xFF, 0x8B, 0xFF)}, // No X11
- {(char_u *)"lightred", RGB(0xFF, 0x8B, 0x8B)}, // No X11
- {(char_u *)"lightyellow", RGB(0xFF, 0xFF, 0xE0)},
- {(char_u *)"magenta", RGB(0xFF, 0x00, 0xFF)},
- {(char_u *)"red", RGB(0xFF, 0x00, 0x00)},
- {(char_u *)"seagreen", RGB(0x2E, 0x8B, 0x57)},
- {(char_u *)"white", RGB(0xFF, 0xFF, 0xFF)},
- {(char_u *)"yellow", RGB(0xFF, 0xFF, 0x00)},
+ // color_name_tab[], useful when $VIMRUNTIME is not found,.
+ // must be sorted by the 'value' field because it is used by bsearch()!
+ static keyvalue_T rgb_tab[] = {
+ KEYVALUE_ENTRY(RGB(0x00, 0x00, 0x00), "black"),
+ KEYVALUE_ENTRY(RGB(0x00, 0x00, 0xFF), "blue"),
+ KEYVALUE_ENTRY(RGB(0xA5, 0x2A, 0x2A), "brown"),
+ KEYVALUE_ENTRY(RGB(0x00, 0xFF, 0xFF), "cyan"),
+ KEYVALUE_ENTRY(RGB(0x00, 0x00, 0x8B), "darkblue"),
+ KEYVALUE_ENTRY(RGB(0x00, 0x8B, 0x8B), "darkcyan"),
+ KEYVALUE_ENTRY(RGB(0xA9, 0xA9, 0xA9), "darkgray"),
+ KEYVALUE_ENTRY(RGB(0x00, 0x64, 0x00), "darkgreen"),
+ KEYVALUE_ENTRY(RGB(0xA9, 0xA9, 0xA9), "darkgrey"),
+ KEYVALUE_ENTRY(RGB(0x8B, 0x00, 0x8B), "darkmagenta"),
+ KEYVALUE_ENTRY(RGB(0x8B, 0x00, 0x00), "darkred"),
+ KEYVALUE_ENTRY(RGB(0x8B, 0x8B, 0x00), "darkyellow"), // No X11
+ KEYVALUE_ENTRY(RGB(0xBE, 0xBE, 0xBE), "gray"),
+ KEYVALUE_ENTRY(RGB(0x00, 0xFF, 0x00), "green"),
+ KEYVALUE_ENTRY(RGB(0xBE, 0xBE, 0xBE), "grey"),
+ KEYVALUE_ENTRY(RGB(0x66, 0x66, 0x66), "grey40"),
+ KEYVALUE_ENTRY(RGB(0x7F, 0x7F, 0x7F), "grey50"),
+ KEYVALUE_ENTRY(RGB(0xE5, 0xE5, 0xE5), "grey90"),
+ KEYVALUE_ENTRY(RGB(0xAD, 0xD8, 0xE6), "lightblue"),
+ KEYVALUE_ENTRY(RGB(0xE0, 0xFF, 0xFF), "lightcyan"),
+ KEYVALUE_ENTRY(RGB(0xD3, 0xD3, 0xD3), "lightgray"),
+ KEYVALUE_ENTRY(RGB(0x90, 0xEE, 0x90), "lightgreen"),
+ KEYVALUE_ENTRY(RGB(0xD3, 0xD3, 0xD3), "lightgrey"),
+ KEYVALUE_ENTRY(RGB(0xFF, 0x8B, 0xFF), "lightmagenta"), // No XX
+ KEYVALUE_ENTRY(RGB(0xFF, 0x8B, 0x8B), "lightred"), // No XX
+ KEYVALUE_ENTRY(RGB(0xFF, 0xFF, 0xE0), "lightyellow"),
+ KEYVALUE_ENTRY(RGB(0xFF, 0x00, 0xFF), "magenta"),
+ KEYVALUE_ENTRY(RGB(0xFF, 0x00, 0x00), "red"),
+ KEYVALUE_ENTRY(RGB(0x2E, 0x8B, 0x57), "seagreen"),
+ KEYVALUE_ENTRY(RGB(0xFF, 0xFF, 0xFF), "white"),
+ KEYVALUE_ENTRY(RGB(0xFF, 0xFF, 0x00), "yellow")
};
+ keyvalue_T target;
+ keyvalue_T *entry;
color = decode_hex_color(name);
if (color != INVALCOLOR)
return color;
- // Check if the name is one of the colors we know
- for (i = 0; i < (int)ARRAY_LENGTH(rgb_table); i++)
- if (STRICMP(name, rgb_table[i].color_name) == 0)
- return gui_adjust_rgb(rgb_table[i].color);
+ target.key = 0;
+ target.value = (char *)name;
+ target.length = 0; // not used, see cmp_keyvalue_value_i()
+ entry = (keyvalue_T *)bsearch(&target, &rgb_tab, ARRAY_LENGTH(rgb_tab), sizeof(rgb_tab[0]), cmp_keyvalue_value_i);
+ if (entry != NULL)
+ return gui_adjust_rgb((guicolor_T)entry->key);
#if defined(FEAT_EVAL)
/*
@@ -3056,15 +3124,22 @@ highlight_list_arg(
ts = sarg;
else // type == LIST_ATTR
{
+ size_t buflen;
+
buf[0] = NUL;
- for (i = 0; hl_attr_table[i] != 0; ++i)
+ buflen = 0;
+ for (i = 0; i < (int)ARRAY_LENGTH(highlight_index_tab); ++i)
{
- if (iarg & hl_attr_table[i])
+ if (iarg & highlight_index_tab[i]->key)
{
- if (buf[0] != NUL)
- vim_strcat(buf, (char_u *)",", MAX_ATTR_LEN);
- vim_strcat(buf, (char_u *)hl_name_table[i], MAX_ATTR_LEN);
- iarg &= ~hl_attr_table[i]; // don't want "inverse"
+ if (buflen > 0)
+ {
+ STRCPY(buf + buflen, (char_u *)",");
+ ++buflen;
+ }
+ STRCPY(buf + buflen, (char_u *)highlight_index_tab[i]->value);
+ buflen += highlight_index_tab[i]->length;
+ iarg &= ~highlight_index_tab[i]->key; // don't want "inverse"/"reverse"
}
}
}
@@ -4155,12 +4230,12 @@ highlight_get_attr_dict(int hlattr)
if (dict == NULL)
return NULL;
- for (i = 0; hl_attr_table[i] != 0; ++i)
+ for (i = 0; i < (int)ARRAY_LENGTH(highlight_index_tab); ++i)
{
- if (hlattr & hl_attr_table[i])
+ if (hlattr & highlight_index_tab[i]->key)
{
- dict_add_bool(dict, hl_name_table[i], VVAL_TRUE);
- hlattr &= ~hl_attr_table[i]; // don't want "inverse"
+ dict_add_bool(dict, highlight_index_tab[i]->value, VVAL_TRUE);
+ hlattr &= ~highlight_index_tab[i]->key; // don't want "inverse"/"reverse"
}
}
@@ -4377,7 +4452,6 @@ hldict_attr_to_str(
dict_T *attrdict;
int i;
char_u *p;
- size_t sz;
attr_str[0] = NUL;
di = dict_find(dict, key, -1);
@@ -4400,17 +4474,16 @@ hldict_attr_to_str(
}
p = attr_str;
- for (i = 0; i < (int)ARRAY_LENGTH(hl_name_table); i++)
+ for (i = 0; i < (int)ARRAY_LENGTH(highlight_tab); ++i)
{
- if (dict_get_bool(attrdict, hl_name_table[i], VVAL_FALSE) == VVAL_TRUE)
+ if (dict_get_bool(attrdict, highlight_tab[i].value, VVAL_FALSE) == VVAL_TRUE)
{
if (p != attr_str && (size_t)(p - attr_str + 2) < len)
STRCPY(p, (char_u *)",");
- sz = STRLEN(hl_name_table[i]);
- if (p - attr_str + sz + 1 < len)
+ if (p - attr_str + highlight_tab[i].length + 1 < len)
{
- STRCPY(p, (char_u *)hl_name_table[i]);
- p += sz;
+ STRCPY(p, highlight_tab[i].value);
+ p += highlight_tab[i].length;
}
}
}
diff --git a/src/indent.c b/src/indent.c
index 56032fa..1dfde7d 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -163,7 +163,7 @@ tabstop_start(colnr_T col, int ts, int *vts)
int excess;
if (vts == NULL || vts[0] == 0)
- return (col / ts) * ts;
+ return col - col % ts;
tabcount = vts[0];
for (t = 1; t <= tabcount; ++t)
@@ -174,7 +174,7 @@ tabstop_start(colnr_T col, int ts, int *vts)
}
excess = tabcol % vts[tabcount];
- return excess + ((col - excess) / vts[tabcount]) * vts[tabcount];
+ return col - (col - excess) % vts[tabcount];
}
/*
diff --git a/src/insexpand.c b/src/insexpand.c
index 9b5e5de..93a56a8 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -2741,6 +2741,7 @@ expand_by_function(int type, char_u *base)
--textlock;
curwin->w_cursor = pos; // restore the cursor position
+ check_cursor(); // make sure cursor position is valid, just in case
validate_cursor();
if (!EQUAL_POS(curwin->w_cursor, pos))
{
@@ -4606,6 +4607,7 @@ get_userdefined_compl_info(colnr_T curs_col UNUSED)
State = save_State;
curwin->w_cursor = pos; // restore the cursor position
+ check_cursor(); // make sure cursor position is valid, just in case
validate_cursor();
if (!EQUAL_POS(curwin->w_cursor, pos))
{
diff --git a/src/main.c b/src/main.c
index 770726f..e5faaa7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1098,7 +1098,7 @@ is_safe_now(void)
}
/*
- * Trigger SafeState if currently in s safe state, that is "safe" is TRUE and
+ * Trigger SafeState if currently in a safe state, that is "safe" is TRUE and
* there is no typeahead.
*/
void
@@ -3276,6 +3276,10 @@ source_startup_scripts(mparm_T *parmp)
&& do_source((char_u *)USR_VIMRC_FILE2, TRUE,
DOSO_VIMRC, NULL) == FAIL
#endif
+#ifdef XDG_VIMRC_FILE
+ && do_source((char_u *)XDG_VIMRC_FILE, TRUE,
+ DOSO_VIMRC, NULL) == FAIL
+#endif
#ifdef USR_VIMRC_FILE3
&& do_source((char_u *)USR_VIMRC_FILE3, TRUE,
DOSO_VIMRC, NULL) == FAIL
diff --git a/src/map.c b/src/map.c
index b7bb46c..c416c0a 100644
--- a/src/map.c
+++ b/src/map.c
@@ -2574,7 +2574,10 @@ f_maplist(typval_T *argvars UNUSED, typval_T *rettv)
if ((d = dict_alloc()) == NULL)
return;
if (list_append_dict(rettv->vval.v_list, d) == FAIL)
+ {
+ dict_unref(d);
return;
+ }
keys_buf = NULL;
did_simplify = FALSE;
diff --git a/src/match.c b/src/match.c
index f59c206..bc50757 100644
--- a/src/match.c
+++ b/src/match.c
@@ -87,7 +87,7 @@ match_add(
m = ALLOC_CLEAR_ONE(matchitem_T);
if (m == NULL)
return -1;
- if (pos_list != NULL)
+ if (pos_list != NULL && pos_list->lv_len > 0)
{
m->mit_pos_array = ALLOC_CLEAR_MULT(llpos_T, pos_list->lv_len);
if (m->mit_pos_array == NULL)
@@ -1294,7 +1294,7 @@ f_matchaddpos(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
return;
}
l = argvars[1].vval.v_list;
- if (l == NULL)
+ if (l == NULL || l->lv_len == 0)
return;
if (argvars[2].v_type != VAR_UNKNOWN)
diff --git a/src/mbyte.c b/src/mbyte.c
index d6fb7ec..07446ca 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -5542,6 +5542,20 @@ string_convert_ext(
return retval;
}
+/*
+ * Return 1 or 2 when "c" is in the cellwidth table.
+ * Return 0 if not.
+ */
+ int
+get_cellwidth(int c UNUSED)
+{
+#ifdef FEAT_EVAL
+ return cw_value(c);
+#else
+ return 0;
+#endif
+}
+
#if defined(FEAT_EVAL) || defined(PROTO)
/*
@@ -5733,6 +5747,7 @@ f_setcellwidths(typval_T *argvars, typval_T *rettv UNUSED)
}
vim_free(cw_table_save);
+ changed_window_setting_all();
redraw_all_later(UPD_CLEAR);
}
diff --git a/src/memline.c b/src/memline.c
index 5ca50fc..6c63fad 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -5556,7 +5556,10 @@ ml_encrypt_data(
new_data = alloc(size);
if (new_data == NULL)
+ {
+ crypt_free_state(state);
return NULL;
+ }
head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
text_start = (char_u *)dp + dp->db_txt_start;
text_len = size - dp->db_txt_start;
diff --git a/src/message.c b/src/message.c
index 80d6a18..03c7072 100644
--- a/src/message.c
+++ b/src/message.c
@@ -1637,6 +1637,9 @@ msg_outtrans_len_attr(char_u *msgstr, int len, int attr)
// Only quit when got_int was set in here.
got_int = FALSE;
+ if (attr == 0)
+ attr = HL_ATTR(HLF_MSG);
+
// if MSG_HIST flag set, add message to history
if (attr & MSG_HIST)
{
@@ -2230,6 +2233,9 @@ msg_puts_attr_len(char *str, int maxlen, int attr)
if (msg_silent != 0)
return;
+ if (attr == 0)
+ attr = HL_ATTR(HLF_MSG);
+
// if MSG_HIST flag set, add message to history
if ((attr & MSG_HIST) && maxlen < 0)
{
@@ -2678,13 +2684,15 @@ msg_scroll_up(void)
// Scrolling up doesn't result in the right background. Set the
// background here. It's not efficient, but avoids that we have to do
// it all over the code.
- screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+ screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns,
+ ' ', ' ', HL_ATTR(HLF_MSG));
// Also clear the last char of the last but one line if it was not
// cleared before to avoid a scroll-up.
if (ScreenAttrs[LineOffset[Rows - 2] + Columns - 1] == (sattr_T)-1)
screen_fill((int)Rows - 2, (int)Rows - 1,
- (int)Columns - 1, (int)Columns, ' ', ' ', 0);
+ (int)Columns - 1, (int)Columns,
+ ' ', ' ', HL_ATTR(HLF_MSG));
}
}
@@ -2963,7 +2971,8 @@ disp_sb_line(int row, msgchunk_T *smp, int clear_to_eol)
// If clearing the screen did not work (e.g. because of a background
// color and t_ut isn't set) clear until the last column here.
if (clear_to_eol)
- screen_fill(row, row + 1, msg_col, (int)Columns, ' ', ' ', 0);
+ screen_fill(row, row + 1, msg_col, (int)Columns,
+ ' ', ' ', HL_ATTR(HLF_MSG));
if (mp->sb_eol || mp->sb_next == NULL)
break;
@@ -3131,6 +3140,9 @@ do_more_prompt(int typed_char)
msgchunk_T *mp_last = NULL;
msgchunk_T *mp;
int i;
+ int msg_attr;
+
+ msg_attr = HL_ATTR(HLF_MSG);
// We get called recursively when a timer callback outputs a message. In
// that case don't show another prompt. Also when at the hit-Enter prompt
@@ -3340,8 +3352,8 @@ do_more_prompt(int typed_char)
// scroll up, display line at bottom
msg_scroll_up();
inc_msg_scrolled();
- screen_fill((int)Rows - 2, (int)Rows - 1, 0,
- (int)Columns, ' ', ' ', 0);
+ screen_fill((int)Rows - 2, (int)Rows - 1, 0, (int)Columns,
+ ' ', ' ', msg_attr);
mp_last = disp_sb_line((int)Rows - 2, mp_last, FALSE);
--toscroll;
}
@@ -3350,8 +3362,8 @@ do_more_prompt(int typed_char)
if (toscroll <= 0)
{
// displayed the requested text, more prompt again
- screen_fill((int)Rows - 1, (int)Rows, 0,
- (int)Columns, ' ', ' ', 0);
+ screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns,
+ ' ', ' ', msg_attr);
msg_moremsg(FALSE);
continue;
}
@@ -3364,7 +3376,7 @@ do_more_prompt(int typed_char)
}
// clear the --more-- message
- screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+ screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', msg_attr);
State = oldState;
setmouse();
if (quit_more)
@@ -3710,18 +3722,25 @@ msg_clr_eos_force(void)
}
else
{
+ int msg_attr;
+
+ msg_attr = HL_ATTR(HLF_MSG);
+
#ifdef FEAT_RIGHTLEFT
if (cmdmsg_rl)
{
- screen_fill(msg_row, msg_row + 1, 0, msg_col + 1, ' ', ' ', 0);
- screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+ screen_fill(msg_row, msg_row + 1, 0, msg_col + 1,
+ ' ', ' ', msg_attr);
+ screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns,
+ ' ', ' ', msg_attr);
}
else
#endif
{
screen_fill(msg_row, msg_row + 1, msg_col, (int)Columns,
- ' ', ' ', 0);
- screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+ ' ', ' ', msg_attr);
+ screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns,
+ ' ', ' ', msg_attr);
}
}
}
diff --git a/src/misc1.c b/src/misc1.c
index 3085fc7..c5a0c38 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -502,7 +502,7 @@ plines_m_win(win_T *wp, linenr_T first, linenr_T last, int limit_winheight)
{
int count = 0;
- while (first <= last)
+ while (first <= last && (!limit_winheight || count < wp->w_height))
{
#ifdef FEAT_FOLDING
int x;
@@ -520,14 +520,19 @@ plines_m_win(win_T *wp, linenr_T first, linenr_T last, int limit_winheight)
{
#ifdef FEAT_DIFF
if (first == wp->w_topline)
- count += plines_win_nofill(wp, first, limit_winheight)
- + wp->w_topfill;
+ count += plines_win_nofill(wp, first, FALSE) + wp->w_topfill;
else
#endif
- count += plines_win(wp, first, limit_winheight);
+ count += plines_win(wp, first, FALSE);
++first;
}
}
+#ifdef FEAT_DIFF
+ if (first == wp->w_buffer->b_ml.ml_line_count + 1)
+ count += diff_check_fill(wp, first);
+#endif
+ if (limit_winheight && count > wp->w_height)
+ return wp->w_height;
return (count);
}
@@ -2092,7 +2097,7 @@ add_user(char_u *user, int need_copy)
if (user_copy == NULL || *user_copy == NUL || ga_grow(&ga_users, 1) == FAIL)
{
if (need_copy)
- vim_free(user);
+ vim_free(user_copy);
return;
}
((char_u **)(ga_users.ga_data))[ga_users.ga_len++] = user_copy;
@@ -2172,7 +2177,7 @@ init_users(void)
}
/*
- * Function given to ExpandGeneric() to obtain an user names.
+ * Function given to ExpandGeneric() to obtain user names.
*/
char_u*
get_users(expand_T *xp UNUSED, int idx)
diff --git a/src/misc2.c b/src/misc2.c
index 6df0d39..c07ed80 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -3069,3 +3069,45 @@ get_special_pty_type(void)
return 0;
#endif
}
+
+// compare two keyvalue_T structs by case sensitive value
+ int
+cmp_keyvalue_value(const void *a, const void *b)
+{
+ keyvalue_T *kv1 = (keyvalue_T *)a;
+ keyvalue_T *kv2 = (keyvalue_T *)b;
+
+ return STRCMP(kv1->value, kv2->value);
+}
+
+// compare two keyvalue_T structs by value with length
+ int
+cmp_keyvalue_value_n(const void *a, const void *b)
+{
+ keyvalue_T *kv1 = (keyvalue_T *)a;
+ keyvalue_T *kv2 = (keyvalue_T *)b;
+
+ return STRNCMP(kv1->value, kv2->value, MAX(kv1->length, kv2->length));
+}
+
+// compare two keyvalue_T structs by case insensitive value
+ int
+cmp_keyvalue_value_i(const void *a, const void *b)
+{
+ keyvalue_T *kv1 = (keyvalue_T *)a;
+ keyvalue_T *kv2 = (keyvalue_T *)b;
+
+ return STRICMP(kv1->value, kv2->value);
+}
+
+// compare two keyvalue_T structs by case insensitive value
+// with length
+ int
+cmp_keyvalue_value_ni(const void *a, const void *b)
+{
+ keyvalue_T *kv1 = (keyvalue_T *)a;
+ keyvalue_T *kv2 = (keyvalue_T *)b;
+
+ return STRNICMP(kv1->value, kv2->value, MAX(kv1->length, kv2->length));
+}
+
diff --git a/src/mouse.c b/src/mouse.c
index af14af0..247c6df 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -1129,7 +1129,7 @@ do_mousescroll(cmdarg_T *cap)
if (!(State & MODE_INSERT) && (mouse_vert_step < 0 || shift_or_ctrl))
{
// whole page up or down
- onepage(cap->arg == MSCR_UP ? FORWARD : BACKWARD, 1L);
+ pagescroll(cap->arg == MSCR_UP ? FORWARD : BACKWARD, 1L, FALSE);
}
else
{
diff --git a/src/move.c b/src/move.c
index 9ea24c8..1b6e003 100644
--- a/src/move.c
+++ b/src/move.c
@@ -59,7 +59,7 @@ adjust_plines_for_skipcol(win_T *wp)
* the window height.
*/
static int
-plines_correct_topline(win_T *wp, linenr_T lnum)
+plines_correct_topline(win_T *wp, linenr_T lnum, int limit_winheight)
{
int n;
#ifdef FEAT_DIFF
@@ -70,7 +70,7 @@ plines_correct_topline(win_T *wp, linenr_T lnum)
n = plines_win(wp, lnum, FALSE);
if (lnum == wp->w_topline)
n -= adjust_plines_for_skipcol(wp);
- if (n > wp->w_height)
+ if (limit_winheight && n > wp->w_height)
n = wp->w_height;
return n;
}
@@ -119,7 +119,7 @@ comp_botline(win_T *wp)
else
#endif
{
- n = plines_correct_topline(wp, lnum);
+ n = plines_correct_topline(wp, lnum, TRUE);
}
if (
#ifdef FEAT_FOLDING
@@ -197,13 +197,15 @@ redraw_for_cursorcolumn(win_T *wp)
* Calculates how much the 'listchars' "precedes" or 'smoothscroll' "<<<"
* marker overlaps with buffer text for window "wp".
* Parameter "extra2" should be the padding on the 2nd line, not the first
- * line.
+ * line. When "extra2" is -1 calculate the padding.
* Returns the number of columns of overlap with buffer text, excluding the
* extra padding on the ledge.
*/
int
sms_marker_overlap(win_T *wp, int extra2)
{
+ if (extra2 == -1)
+ extra2 = win_col_off(wp) - win_col_off2(wp);
#if defined(FEAT_LINEBREAK)
// There is no marker overlap when in showbreak mode, thus no need to
// account for it. See wlv_screen_line().
@@ -340,12 +342,12 @@ update_topline(void)
&& curwin->w_cursor.lnum == curwin->w_topline)
{
colnr_T vcol;
+ int overlap;
// Check that the cursor position is visible. Add columns for
// the marker displayed in the top-left if needed.
getvvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
- int overlap = sms_marker_overlap(curwin, curwin_col_off()
- - curwin_col_off2());
+ overlap = sms_marker_overlap(curwin, -1);
if (curwin->w_skipcol + overlap > vcol)
check_topline = TRUE;
}
@@ -676,6 +678,19 @@ changed_window_setting_buf(buf_T *buf)
#endif
/*
+ * Call changed_window_setting_win() for every window.
+ */
+ void
+changed_window_setting_all(void)
+{
+ tabpage_T *tp;
+ win_T *wp;
+
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ changed_window_setting_win(wp);
+}
+
+/*
* Set wp->w_topline to a certain number.
*/
void
@@ -919,7 +934,7 @@ curs_rows(win_T *wp)
else
#endif
{
- wp->w_cline_row += plines_correct_topline(wp, lnum);
+ wp->w_cline_row += plines_correct_topline(wp, lnum, TRUE);
++lnum;
}
}
@@ -1600,6 +1615,127 @@ f_virtcol2col(typval_T *argvars UNUSED, typval_T *rettv)
#endif
/*
+ * Make sure the cursor is in the visible part of the topline after scrolling
+ * the screen with 'smoothscroll'.
+ */
+static void cursor_correct_sms(void)
+{
+ if (!curwin->w_p_sms ||!curwin->w_p_wrap
+ || curwin->w_cursor.lnum != curwin->w_topline)
+ return;
+
+ long so = get_scrolloff_value();
+ int width1 = curwin->w_width - curwin_col_off();
+ int width2 = width1 + curwin_col_off2();
+ int so_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
+ int space_cols = (curwin->w_height - 1) * width2;
+ int size = so == 0 ? 0 : win_linetabsize(curwin, curwin->w_topline,
+ ml_get(curwin->w_topline), (colnr_T)MAXCOL);
+
+ if (curwin->w_topline == 1 && curwin->w_skipcol == 0)
+ so_cols = 0; // Ignore 'scrolloff' at top of buffer.
+ else if (so_cols > space_cols / 2)
+ so_cols = space_cols / 2; // Not enough room: put cursor in the middle.
+
+ // Not enough screen lines in topline: ignore 'scrolloff'.
+ while (so_cols > size && so_cols - width2 >= width1)
+ so_cols -= width2;
+ if (so_cols >= width1 && so_cols > size)
+ so_cols -= width1;
+
+ // If there is no marker or we have non-zero scrolloff, just ignore it.
+ int overlap = (curwin->w_skipcol == 0 || so_cols != 0) ? 0
+ : sms_marker_overlap(curwin, -1);
+ int top = curwin->w_skipcol + overlap + so_cols;
+ int bot = curwin->w_skipcol + width1 + (curwin->w_height - 1) * width2
+ - so_cols;
+ validate_virtcol();
+ colnr_T col = curwin->w_virtcol;
+
+ if (col < top)
+ {
+ if (col < width1)
+ col += width1;
+ while (width2 > 0 && col < top)
+ col += width2;
+ }
+ else
+ while (width2 > 0 && col >= bot)
+ col -= width2;
+
+ if (col != curwin->w_virtcol)
+ {
+ curwin->w_curswant = col;
+ coladvance(curwin->w_curswant);
+ // validate_virtcol() marked various things as valid, but after
+ // moving the cursor they need to be recomputed
+ curwin->w_valid &=
+ ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL);
+ }
+}
+
+/*
+ * Scroll "count" lines up or down, and redraw.
+ */
+ void
+scroll_redraw(int up, long count)
+{
+ linenr_T prev_topline = curwin->w_topline;
+ int prev_skipcol = curwin->w_skipcol;
+#ifdef FEAT_DIFF
+ int prev_topfill = curwin->w_topfill;
+#endif
+ linenr_T prev_lnum = curwin->w_cursor.lnum;
+
+ if (up)
+ scrollup(count, TRUE);
+ else
+ scrolldown(count, TRUE);
+ if (get_scrolloff_value() > 0)
+ {
+ // Adjust the cursor position for 'scrolloff'. Mark w_topline as
+ // valid, otherwise the screen jumps back at the end of the file.
+ cursor_correct();
+ check_cursor_moved(curwin);
+ curwin->w_valid |= VALID_TOPLINE;
+
+ // If moved back to where we were, at least move the cursor, otherwise
+ // we get stuck at one position. Don't move the cursor up if the
+ // first line of the buffer is already on the screen
+ while (curwin->w_topline == prev_topline
+ && curwin->w_skipcol == prev_skipcol
+#ifdef FEAT_DIFF
+ && curwin->w_topfill == prev_topfill
+#endif
+ )
+ {
+ if (up)
+ {
+ if (curwin->w_cursor.lnum > prev_lnum
+ || cursor_down(1L, FALSE) == FAIL)
+ break;
+ }
+ else
+ {
+ if (curwin->w_cursor.lnum < prev_lnum
+ || prev_topline == 1L
+ || cursor_up(1L, FALSE) == FAIL)
+ break;
+ }
+ // Mark w_topline as valid, otherwise the screen jumps back at the
+ // end of the file.
+ check_cursor_moved(curwin);
+ curwin->w_valid |= VALID_TOPLINE;
+ }
+ }
+
+ cursor_correct_sms();
+ if (curwin->w_cursor.lnum != prev_lnum)
+ coladvance(curwin->w_curswant);
+ redraw_later(UPD_VALID);
+}
+
+/*
* Scroll the current window down by "line_count" logical lines. "CTRL-Y"
*/
void
@@ -1744,35 +1880,8 @@ scrolldown(
#endif
coladvance(curwin->w_curswant);
}
-
- if (curwin->w_cursor.lnum == curwin->w_topline && do_sms)
- {
- long so = get_scrolloff_value();
- int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
-
- // make sure the cursor is in the visible text
- validate_virtcol();
- int col = curwin->w_virtcol - curwin->w_skipcol + scrolloff_cols;
- int row = 0;
- if (col >= width1)
- {
- col -= width1;
- ++row;
- }
- if (col > width2 && width2 > 0)
- {
- row += col / width2;
- // even so col is not used anymore,
- // make sure it is correct, just in case
- col = col % width2;
- }
- if (row >= curwin->w_height)
- {
- curwin->w_curswant = curwin->w_virtcol
- - (row - curwin->w_height + 1) * width2;
- coladvance(curwin->w_curswant);
- }
- }
+ if (curwin->w_cursor.lnum < curwin->w_topline)
+ curwin->w_cursor.lnum = curwin->w_topline;
}
/*
@@ -1894,47 +2003,6 @@ scrollup(
~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL);
coladvance(curwin->w_curswant);
}
- if (curwin->w_cursor.lnum == curwin->w_topline
- && do_sms && curwin->w_skipcol > 0)
- {
- int col_off = curwin_col_off();
- int col_off2 = curwin_col_off2();
-
- int width1 = curwin->w_width - col_off;
- int width2 = width1 + col_off2;
- int extra2 = col_off - col_off2;
- long so = get_scrolloff_value();
- int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
- int space_cols = (curwin->w_height - 1) * width2;
-
- // If we have non-zero scrolloff, just ignore the marker as we are
- // going past it anyway.
- int overlap = scrolloff_cols != 0 ? 0
- : sms_marker_overlap(curwin, extra2);
-
- // Make sure the cursor is in a visible part of the line, taking
- // 'scrolloff' into account, but using screen lines.
- // If there are not enough screen lines put the cursor in the middle.
- if (scrolloff_cols > space_cols / 2)
- scrolloff_cols = space_cols / 2;
- validate_virtcol();
- if (curwin->w_virtcol < curwin->w_skipcol + overlap + scrolloff_cols)
- {
- colnr_T col = curwin->w_virtcol;
-
- if (col < width1)
- col += width1;
- while (col < curwin->w_skipcol + overlap + scrolloff_cols)
- col += width2;
- curwin->w_curswant = col;
- coladvance(curwin->w_curswant);
-
- // validate_virtcol() marked various things as valid, but after
- // moving the cursor they need to be recomputed
- curwin->w_valid &=
- ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL);
- }
- }
}
/*
@@ -1971,8 +2039,7 @@ adjust_skipcol(void)
}
validate_virtcol();
- int overlap = sms_marker_overlap(curwin,
- curwin_col_off() - curwin_col_off2());
+ int overlap = sms_marker_overlap(curwin, -1);
while (curwin->w_skipcol > 0
&& curwin->w_virtcol < curwin->w_skipcol + overlap + scrolloff_cols)
{
@@ -2047,26 +2114,6 @@ check_topfill(
}
}
}
-
-/*
- * Use as many filler lines as possible for w_topline. Make sure w_topline
- * is still visible.
- */
- static void
-max_topfill(void)
-{
- int n;
-
- n = plines_nofill(curwin->w_topline);
- if (n >= curwin->w_height)
- curwin->w_topfill = 0;
- else
- {
- curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
- if (curwin->w_topfill + n > curwin->w_height)
- curwin->w_topfill = curwin->w_height - n;
- }
-}
#endif
/*
@@ -2269,38 +2316,6 @@ botline_forw(lineoff_T *lp)
}
}
-#ifdef FEAT_DIFF
-/*
- * Switch from including filler lines below lp->lnum to including filler
- * lines above loff.lnum + 1. This keeps pointing to the same line.
- * When there are no filler lines nothing changes.
- */
- static void
-botline_topline(lineoff_T *lp)
-{
- if (lp->fill > 0)
- {
- ++lp->lnum;
- lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
- }
-}
-
-/*
- * Switch from including filler lines above lp->lnum to including filler
- * lines below loff.lnum - 1. This keeps pointing to the same line.
- * When there are no filler lines nothing changes.
- */
- static void
-topline_botline(lineoff_T *lp)
-{
- if (lp->fill > 0)
- {
- lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
- --lp->lnum;
- }
-}
-#endif
-
/*
* Recompute topline to put the cursor at the top of the window.
* Scroll at least "min_scroll" lines.
@@ -2512,18 +2527,14 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
cln = curwin->w_cursor.lnum;
if (set_topbot)
{
- int set_skipcol = FALSE;
-
used = 0;
curwin->w_botline = cln + 1;
+ loff.lnum = cln + 1;
#ifdef FEAT_DIFF
loff.fill = 0;
#endif
- for (curwin->w_topline = curwin->w_botline;
- curwin->w_topline > 1;
- curwin->w_topline = loff.lnum)
+ while (TRUE)
{
- loff.lnum = curwin->w_topline;
topline_back_winheight(&loff, FALSE);
if (loff.height == MAXCOL)
break;
@@ -2545,27 +2556,28 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
curwin->w_topline = loff.lnum;
curwin->w_skipcol = skipcol_from_plines(
curwin, plines_offset);
- set_skipcol = TRUE;
}
}
break;
}
- used += loff.height;
#ifdef FEAT_DIFF
curwin->w_topfill = loff.fill;
#endif
+ curwin->w_topline = loff.lnum;
+ used += loff.height;
}
+
set_empty_rows(curwin, used);
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
if (curwin->w_topline != old_topline
#ifdef FEAT_DIFF
|| curwin->w_topfill != old_topfill
#endif
- || set_skipcol
+ || curwin->w_skipcol != old_skipcol
|| curwin->w_skipcol != 0)
{
curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
- if (set_skipcol)
+ if (curwin->w_skipcol != old_skipcol)
redraw_later(UPD_NOT_VALID);
else
reset_skipcol();
@@ -2768,6 +2780,8 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
curwin->w_valid = old_valid;
}
curwin->w_valid |= VALID_TOPLINE;
+
+ cursor_correct_sms();
}
/*
@@ -3077,508 +3091,192 @@ cursor_correct(void)
curwin->w_valid |= VALID_TOPLINE;
}
-static void get_scroll_overlap(lineoff_T *lp, int dir);
-
-/*
- * Move screen "count" pages up ("dir" is BACKWARD) or down ("dir" is FORWARD)
- * and update the screen.
- *
- * Return FAIL for failure, OK otherwise.
- */
- int
-onepage(int dir, long count)
-{
- long n;
- int retval = OK;
- lineoff_T loff;
- linenr_T old_topline = curwin->w_topline;
- long so = get_scrolloff_value();
-
- if (curbuf->b_ml.ml_line_count == 1) // nothing to do
- {
- beep_flush();
- return FAIL;
- }
-
- for ( ; count > 0; --count)
- {
- validate_botline();
- /*
- * It's an error to move a page up when the first line is already on
- * the screen. It's an error to move a page down when the last line
- * is on the screen and the topline is 'scrolloff' lines from the
- * last line.
- */
- if (dir == FORWARD
- ? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - so)
- && curwin->w_botline > curbuf->b_ml.ml_line_count)
- : (curwin->w_topline == 1
-#ifdef FEAT_DIFF
- && curwin->w_topfill ==
- diff_check_fill(curwin, curwin->w_topline)
-#endif
- ))
- {
- beep_flush();
- retval = FAIL;
- break;
- }
-
-#ifdef FEAT_DIFF
- loff.fill = 0;
-#endif
- if (dir == FORWARD)
- {
- if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1)
- {
- // Vi compatible scrolling
- if (p_window <= 2)
- ++curwin->w_topline;
- else
- curwin->w_topline += p_window - 2;
- if (curwin->w_topline > curbuf->b_ml.ml_line_count)
- curwin->w_topline = curbuf->b_ml.ml_line_count;
- curwin->w_cursor.lnum = curwin->w_topline;
- }
- else if (curwin->w_botline > curbuf->b_ml.ml_line_count)
- {
- // at end of file
- curwin->w_topline = curbuf->b_ml.ml_line_count;
-#ifdef FEAT_DIFF
- curwin->w_topfill = 0;
-#endif
- curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
- }
- else
- {
- // For the overlap, start with the line just below the window
- // and go upwards.
- loff.lnum = curwin->w_botline;
-#ifdef FEAT_DIFF
- loff.fill = diff_check_fill(curwin, loff.lnum)
- - curwin->w_filler_rows;
-#endif
- get_scroll_overlap(&loff, -1);
- curwin->w_topline = loff.lnum;
-#ifdef FEAT_DIFF
- curwin->w_topfill = loff.fill;
- check_topfill(curwin, FALSE);
-#endif
- curwin->w_cursor.lnum = curwin->w_topline;
- curwin->w_valid &= ~(VALID_WCOL|VALID_CHEIGHT|VALID_WROW|
- VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
- }
- }
- else // dir == BACKWARDS
- {
-#ifdef FEAT_DIFF
- if (curwin->w_topline == 1)
- {
- // Include max number of filler lines
- max_topfill();
- continue;
- }
-#endif
- if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1)
- {
- // Vi compatible scrolling (sort of)
- if (p_window <= 2)
- --curwin->w_topline;
- else
- curwin->w_topline -= p_window - 2;
- if (curwin->w_topline < 1)
- curwin->w_topline = 1;
- curwin->w_cursor.lnum = curwin->w_topline + p_window - 1;
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
- curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
- continue;
- }
-
- // Find the line at the top of the window that is going to be the
- // line at the bottom of the window. Make sure this results in
- // the same line as before doing CTRL-F.
- loff.lnum = curwin->w_topline - 1;
-#ifdef FEAT_DIFF
- loff.fill = diff_check_fill(curwin, loff.lnum + 1)
- - curwin->w_topfill;
-#endif
- get_scroll_overlap(&loff, 1);
-
- if (loff.lnum >= curbuf->b_ml.ml_line_count)
- {
- loff.lnum = curbuf->b_ml.ml_line_count;
-#ifdef FEAT_DIFF
- loff.fill = 0;
- }
- else
- {
- botline_topline(&loff);
-#endif
- }
- curwin->w_cursor.lnum = loff.lnum;
-
- // Find the line just above the new topline to get the right line
- // at the bottom of the window.
- n = 0;
- while (n <= curwin->w_height && loff.lnum >= 1)
- {
- topline_back(&loff);
- if (loff.height == MAXCOL)
- n = MAXCOL;
- else
- n += loff.height;
- }
- if (loff.lnum < 1) // at begin of file
- {
- curwin->w_topline = 1;
-#ifdef FEAT_DIFF
- max_topfill();
-#endif
- curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
- }
- else
- {
- // Go two lines forward again.
-#ifdef FEAT_DIFF
- topline_botline(&loff);
-#endif
- botline_forw(&loff);
- botline_forw(&loff);
-#ifdef FEAT_DIFF
- botline_topline(&loff);
-#endif
-#ifdef FEAT_FOLDING
- // We're at the wrong end of a fold now.
- (void)hasFolding(loff.lnum, &loff.lnum, NULL);
-#endif
-
- // Always scroll at least one line. Avoid getting stuck on
- // very long lines.
- if (loff.lnum >= curwin->w_topline
-#ifdef FEAT_DIFF
- && (loff.lnum > curwin->w_topline
- || loff.fill >= curwin->w_topfill)
-#endif
- )
- {
-#ifdef FEAT_DIFF
- // First try using the maximum number of filler lines. If
- // that's not enough, backup one line.
- loff.fill = curwin->w_topfill;
- if (curwin->w_topfill < diff_check_fill(curwin,
- curwin->w_topline))
- max_topfill();
- if (curwin->w_topfill == loff.fill)
-#endif
- {
- --curwin->w_topline;
-#ifdef FEAT_DIFF
- curwin->w_topfill = 0;
-#endif
- curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
- }
- comp_botline(curwin);
- curwin->w_cursor.lnum = curwin->w_botline - 1;
- curwin->w_valid &=
- ~(VALID_WCOL|VALID_CHEIGHT|VALID_WROW|VALID_CROW);
- }
- else
- {
- curwin->w_topline = loff.lnum;
-#ifdef FEAT_DIFF
- curwin->w_topfill = loff.fill;
- check_topfill(curwin, FALSE);
-#endif
- curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
- }
- }
- }
- }
-#ifdef FEAT_FOLDING
- foldAdjustCursor();
-#endif
- cursor_correct();
- check_cursor_col();
- if (retval == OK)
- beginline(BL_SOL | BL_FIX);
- curwin->w_valid &= ~(VALID_WCOL|VALID_WROW|VALID_VIRTCOL);
-
- if (retval == OK && dir == FORWARD)
- {
- // Avoid the screen jumping up and down when 'scrolloff' is non-zero.
- // But make sure we scroll at least one line (happens with mix of long
- // wrapping lines and non-wrapping line).
- if (check_top_offset())
- {
- scroll_cursor_top(1, FALSE);
- if (curwin->w_topline <= old_topline
- && old_topline < curbuf->b_ml.ml_line_count)
- {
- curwin->w_topline = old_topline + 1;
-#ifdef FEAT_FOLDING
- (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
-#endif
- }
- }
-#ifdef FEAT_FOLDING
- else if (curwin->w_botline > curbuf->b_ml.ml_line_count)
- (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
-#endif
- }
-
- redraw_later(UPD_VALID);
- return retval;
-}
-
/*
* Decide how much overlap to use for page-up or page-down scrolling.
* This is symmetric, so that doing both keeps the same lines displayed.
* Three lines are examined:
*
- * before CTRL-F after CTRL-F / before CTRL-B
- * etc. l1
- * l1 last but one line ------------
- * l2 last text line l2 top text line
- * ------------- l3 second text line
- * l3 etc.
+ * before CTRL-F after CTRL-F / before CTRL-B
+ * etc. l1
+ * l1 last but one line ------------
+ * l2 last text line l2 top text line
+ * ------------- l3 second text line
+ * l3 etc.
*/
- static void
-get_scroll_overlap(lineoff_T *lp, int dir)
+static int get_scroll_overlap(int dir)
{
- int h1, h2, h3, h4;
- int min_height = curwin->w_height - 2;
- lineoff_T loff0, loff1, loff2;
+ lineoff_T loff;
+ int min_height = curwin->w_height - 2;
+ validate_botline();
+ if ((dir == BACKWARD && curwin->w_topline == 1)
+ || (dir == FORWARD && curwin->w_botline > curbuf->b_ml.ml_line_count))
+ return min_height + 2; // no overlap, still handle 'smoothscroll'
+
+ loff.lnum = dir == FORWARD ? curwin->w_botline : curwin->w_topline - 1;
#ifdef FEAT_DIFF
- if (lp->fill > 0)
- lp->height = 1;
- else
- lp->height = plines_nofill(lp->lnum);
+ loff.fill = diff_check_fill(curwin, loff.lnum + (dir == BACKWARD))
+ - (dir == FORWARD ? curwin->w_filler_rows : curwin->w_topfill);
+ loff.height = loff.fill > 0 ? 1 : plines_nofill(loff.lnum);
#else
- lp->height = plines(lp->lnum);
+ loff.height = plines(loff.lnum);
#endif
- h1 = lp->height;
- if (h1 > min_height)
- return; // no overlap
- loff0 = *lp;
- if (dir > 0)
- botline_forw(lp);
+ int h1 = loff.height;
+ if (h1 > min_height)
+ return min_height + 2; // no overlap
+ if (dir == FORWARD)
+ topline_back(&loff);
else
- topline_back(lp);
- h2 = lp->height;
- if (h2 == MAXCOL || h2 + h1 > min_height)
- {
- *lp = loff0; // no overlap
- return;
- }
+ botline_forw(&loff);
- loff1 = *lp;
- if (dir > 0)
- botline_forw(lp);
+ int h2 = loff.height;
+ if (h2 == MAXCOL || h2 + h1 > min_height)
+ return min_height + 2; // no overlap
+ if (dir == FORWARD)
+ topline_back(&loff);
else
- topline_back(lp);
- h3 = lp->height;
- if (h3 == MAXCOL || h3 + h2 > min_height)
- {
- *lp = loff0; // no overlap
- return;
- }
+ botline_forw(&loff);
- loff2 = *lp;
- if (dir > 0)
- botline_forw(lp);
+ int h3 = loff.height;
+ if (h3 == MAXCOL || h3 + h2 > min_height)
+ return min_height + 2; // no overlap
+ if (dir == FORWARD)
+ topline_back(&loff);
else
- topline_back(lp);
- h4 = lp->height;
+ botline_forw(&loff);
+
+ int h4 = loff.height;
if (h4 == MAXCOL || h4 + h3 + h2 > min_height || h3 + h2 + h1 > min_height)
- *lp = loff1; // 1 line overlap
+ return min_height + 1; // 1 line overlap
else
- *lp = loff2; // 2 lines overlap
+ return min_height; // 2 lines overlap
}
/*
- * Scroll 'scroll' lines up or down.
+ * Scroll "count" lines with 'smoothscroll' in direction "dir". Return TRUE
+ * when scrolling happened.
*/
- void
-halfpage(int flag, linenr_T Prenum)
+static int scroll_with_sms(int dir, long count)
{
- long scrolled = 0;
- int i;
- int n;
- int room;
-
- if (Prenum)
- curwin->w_p_scr = (Prenum > curwin->w_height) ?
- curwin->w_height : Prenum;
- n = (curwin->w_p_scr <= curwin->w_height) ?
- curwin->w_p_scr : curwin->w_height;
-
- update_topline();
- validate_botline();
- room = curwin->w_empty_rows;
+ int prev_sms = curwin->w_p_sms;
+ colnr_T prev_skipcol = curwin->w_skipcol;
+ linenr_T prev_topline = curwin->w_topline;
#ifdef FEAT_DIFF
- room += curwin->w_filler_rows;
-#endif
- if (flag)
- {
- /*
- * scroll the text up
- */
- while (n > 0 && curwin->w_botline <= curbuf->b_ml.ml_line_count)
- {
-#ifdef FEAT_DIFF
- if (curwin->w_topfill > 0)
- {
- i = 1;
- --n;
- --curwin->w_topfill;
- }
- else
-#endif
- {
- i = PLINES_NOFILL(curwin->w_topline);
- n -= i;
- if (n < 0 && scrolled > 0)
- break;
-#ifdef FEAT_FOLDING
- (void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline);
-#endif
- ++curwin->w_topline;
-#ifdef FEAT_DIFF
- curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+ int prev_topfill = curwin->w_topfill;
#endif
- if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
- {
- ++curwin->w_cursor.lnum;
- curwin->w_valid &=
- ~(VALID_VIRTCOL|VALID_CHEIGHT|VALID_WCOL);
- }
- }
- curwin->w_valid &= ~(VALID_CROW|VALID_WROW);
- scrolled += i;
+ curwin->w_p_sms = TRUE;
+ scroll_redraw(dir == FORWARD, count);
+
+ // Not actually smoothscrolling but ended up with partially visible line.
+ // Continue scrolling until skipcol is zero.
+ if (!prev_sms && curwin->w_skipcol > 0)
+ {
+ int fixdir = dir;
+ // Reverse the scroll direction when topline already changed. One line
+ // extra for scrolling backward so that consuming skipcol is symmetric.
+ if (labs(curwin->w_topline - prev_topline) > (dir == BACKWARD))
+ fixdir = dir * -1;
+ while (curwin->w_skipcol > 0
+ && curwin->w_topline < curbuf->b_ml.ml_line_count)
+ scroll_redraw(fixdir == FORWARD, 1);
+ }
+ curwin->w_p_sms = prev_sms;
- /*
- * Correct w_botline for changed w_topline.
- * Won't work when there are filler lines.
- */
+ return curwin->w_topline == prev_topline
#ifdef FEAT_DIFF
- if (curwin->w_p_diff)
- curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
- else
+ && curwin->w_topfill == prev_topfill
#endif
- {
- room += i;
- do
- {
- i = plines(curwin->w_botline);
- if (i > room)
- break;
-#ifdef FEAT_FOLDING
- (void)hasFolding(curwin->w_botline, NULL,
- &curwin->w_botline);
-#endif
- ++curwin->w_botline;
- room -= i;
- } while (curwin->w_botline <= curbuf->b_ml.ml_line_count);
- }
+ && curwin->w_skipcol == prev_skipcol;
+}
+
+/*
+ * Move screen "count" (half) pages up ("dir" is BACKWARD) or down ("dir" is
+ * FORWARD) and update the screen. Handle moving the cursor and not scrolling
+ * to reveal end of buffer lines for half-page scrolling with CTRL-D and CTRL-U.
+ *
+ * Return FAIL for failure, OK otherwise.
+ */
+ int
+pagescroll(int dir, long count, int half)
+{
+ int nochange = TRUE;
+ int buflen = curbuf->b_ml.ml_line_count;
+ colnr_T prev_col = curwin->w_cursor.col;
+ colnr_T prev_curswant = curwin->w_curswant;
+ linenr_T prev_lnum = curwin->w_cursor.lnum;
+ oparg_T oa = { 0 };
+ cmdarg_T ca = { 0 };
+ ca.oap = &oa;
+
+ if (half)
+ {
+ // Scroll [count], 'scroll' or current window height lines.
+ if (count)
+ curwin->w_p_scr = MIN(curwin->w_height, count);
+ count = MIN(curwin->w_height, curwin->w_p_scr);
+
+ int curscount = count;
+ // Adjust count so as to not reveal end of buffer lines.
+ if (dir == FORWARD)
+ {
+ int n = plines_correct_topline(curwin, curwin->w_topline, FALSE);
+ if (n - count < curwin->w_height && curwin->w_topline < buflen)
+ n += plines_m_win(curwin, curwin->w_topline + 1, buflen, FALSE);
+ if (n - count < curwin->w_height)
+ count = n - curwin->w_height;
}
- /*
- * When hit bottom of the file: move cursor down.
- */
- if (n > 0)
+ // (Try to) scroll the window unless already at the end of the buffer.
+ if (count > 0)
{
-# ifdef FEAT_FOLDING
- if (hasAnyFolding(curwin))
- {
- while (--n >= 0
- && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
- {
- (void)hasFolding(curwin->w_cursor.lnum, NULL,
- &curwin->w_cursor.lnum);
- ++curwin->w_cursor.lnum;
- }
- }
- else
-# endif
- curwin->w_cursor.lnum += n;
- check_cursor_lnum();
+ nochange = scroll_with_sms(dir, count);
+ curwin->w_cursor.lnum = prev_lnum;
+ curwin->w_cursor.col = prev_col;
+ curwin->w_curswant = prev_curswant;
}
+
+ // Move the cursor the same amount of screen lines.
+ if (curwin->w_p_wrap)
+ nv_screengo(&oa, dir, curscount);
+ else if (dir == FORWARD)
+ cursor_down_inner(curwin, curscount);
+ else
+ cursor_up_inner(curwin, curscount);
}
else
{
- /*
- * scroll the text down
- */
- while (n > 0 && curwin->w_topline > 1)
- {
-#ifdef FEAT_DIFF
- if (curwin->w_topfill < diff_check_fill(curwin, curwin->w_topline))
- {
- i = 1;
- --n;
- ++curwin->w_topfill;
- }
- else
-#endif
- {
- i = PLINES_NOFILL(curwin->w_topline - 1);
- n -= i;
- if (n < 0 && scrolled > 0)
- break;
- --curwin->w_topline;
-#ifdef FEAT_FOLDING
- (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
-#endif
-#ifdef FEAT_DIFF
- curwin->w_topfill = 0;
-#endif
- }
- curwin->w_valid &= ~(VALID_CROW|VALID_WROW|
- VALID_BOTLINE|VALID_BOTLINE_AP);
- scrolled += i;
- if (curwin->w_cursor.lnum > 1)
- {
- --curwin->w_cursor.lnum;
- curwin->w_valid &= ~(VALID_VIRTCOL|VALID_CHEIGHT|VALID_WCOL);
- }
- }
+ // Scroll [count] times 'window' or current window height lines.
+ count *= ((ONE_WINDOW && p_window > 0 && p_window < Rows - 1) ?
+ MAX(1, p_window - 2) : get_scroll_overlap(dir));
+ nochange = scroll_with_sms(dir, count);
- /*
- * When hit top of the file: move cursor up.
- */
- if (n > 0)
- {
- if (curwin->w_cursor.lnum <= (linenr_T)n)
- curwin->w_cursor.lnum = 1;
- else
-# ifdef FEAT_FOLDING
- if (hasAnyFolding(curwin))
- {
- while (--n >= 0 && curwin->w_cursor.lnum > 1)
- {
- --curwin->w_cursor.lnum;
- (void)hasFolding(curwin->w_cursor.lnum,
- &curwin->w_cursor.lnum, NULL);
- }
- }
- else
-# endif
- curwin->w_cursor.lnum -= n;
- }
+ // Place cursor at top or bottom of window.
+ validate_botline();
+ curwin->w_cursor.lnum = (dir == FORWARD ? curwin->w_topline
+ : curwin->w_botline - 1);
}
-# ifdef FEAT_FOLDING
+
+ if (get_scrolloff_value() > 0)
+ cursor_correct();
+#ifdef FEAT_FOLDING
// Move cursor to first line of closed fold.
foldAdjustCursor();
-# endif
-#ifdef FEAT_DIFF
- check_topfill(curwin, !flag);
#endif
- cursor_correct();
- beginline(BL_SOL | BL_FIX);
- redraw_later(UPD_VALID);
+ nochange = nochange
+ && prev_col == curwin->w_cursor.col
+ && prev_lnum == curwin->w_cursor.lnum;
+
+ // Error if both the viewport and cursor did not change.
+ if (nochange)
+ beep_flush();
+ else if (!curwin->w_p_sms)
+ beginline(BL_SOL | BL_FIX);
+ else if (p_sol)
+ nv_g_home_m_cmd(&ca);
+
+ return nochange;
}
void
diff --git a/src/normal.c b/src/normal.c
index 5ef3a92..fef2826 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -1708,6 +1708,7 @@ add_to_showcmd(int c)
int extra_len;
int overflow;
int i;
+ char_u mbyte_buf[MB_MAXBYTES];
static int ignore[] =
{
#ifdef FEAT_GUI
@@ -1739,9 +1740,17 @@ add_to_showcmd(int c)
if (ignore[i] == c)
return FALSE;
- p = transchar(c);
- if (*p == ' ')
- STRCPY(p, "<20>");
+ if (c <= 0x7f || !vim_isprintc(c))
+ {
+ p = transchar(c);
+ if (*p == ' ')
+ STRCPY(p, "<20>");
+ }
+ else
+ {
+ mbyte_buf[(*mb_char2bytes)(c, mbyte_buf)] = NUL;
+ p = mbyte_buf;
+ }
old_len = (int)STRLEN(showcmd_buf);
extra_len = (int)STRLEN(p);
overflow = old_len + extra_len - SHOWCMD_COLS;
@@ -1810,7 +1819,7 @@ pop_showcmd(void)
static void
display_showcmd(void)
{
- int len = (int)STRLEN(showcmd_buf);
+ int len = vim_strsize(showcmd_buf);
showcmd_is_clear = (len == 0);
cursor_off();
@@ -2066,7 +2075,7 @@ nv_page(cmdarg_T *cap)
goto_tabpage((int)cap->count0);
}
else
- (void)onepage(cap->arg, cap->count1);
+ (void)pagescroll(cap->arg, cap->count1, FALSE);
}
/*
@@ -2303,10 +2312,12 @@ find_decl(
*
* Return OK if able to move cursor, FAIL otherwise.
*/
- static int
+ int
nv_screengo(oparg_T *oap, int dir, long dist)
{
- int linelen = linetabsize(curwin, curwin->w_cursor.lnum);
+
+ int linelen = linetabsize_no_outer(curwin, curwin->w_cursor.lnum);
+
int retval = OK;
int atend = FALSE;
int n;
@@ -2376,7 +2387,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
}
cursor_up_inner(curwin, 1);
- linelen = linetabsize(curwin, curwin->w_cursor.lnum);
+ linelen = linetabsize_no_outer(curwin, curwin->w_cursor.lnum);
if (linelen > width1)
curwin->w_curswant += (((linelen - width1 - 1) / width2)
+ 1) * width2;
@@ -2413,7 +2424,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
// clipped to column 0.
if (curwin->w_curswant >= width1)
curwin->w_curswant -= width2;
- linelen = linetabsize(curwin, curwin->w_cursor.lnum);
+ linelen = linetabsize_no_outer(curwin, curwin->w_cursor.lnum);
}
}
}
@@ -2472,65 +2483,6 @@ nv_scroll_line(cmdarg_T *cap)
}
/*
- * Scroll "count" lines up or down, and redraw.
- */
- void
-scroll_redraw(int up, long count)
-{
- linenr_T prev_topline = curwin->w_topline;
- int prev_skipcol = curwin->w_skipcol;
-#ifdef FEAT_DIFF
- int prev_topfill = curwin->w_topfill;
-#endif
- linenr_T prev_lnum = curwin->w_cursor.lnum;
-
- if (up)
- scrollup(count, TRUE);
- else
- scrolldown(count, TRUE);
- if (get_scrolloff_value() > 0)
- {
- // Adjust the cursor position for 'scrolloff'. Mark w_topline as
- // valid, otherwise the screen jumps back at the end of the file.
- cursor_correct();
- check_cursor_moved(curwin);
- curwin->w_valid |= VALID_TOPLINE;
-
- // If moved back to where we were, at least move the cursor, otherwise
- // we get stuck at one position. Don't move the cursor up if the
- // first line of the buffer is already on the screen
- while (curwin->w_topline == prev_topline
- && curwin->w_skipcol == prev_skipcol
-#ifdef FEAT_DIFF
- && curwin->w_topfill == prev_topfill
-#endif
- )
- {
- if (up)
- {
- if (curwin->w_cursor.lnum > prev_lnum
- || cursor_down(1L, FALSE) == FAIL)
- break;
- }
- else
- {
- if (curwin->w_cursor.lnum < prev_lnum
- || prev_topline == 1L
- || cursor_up(1L, FALSE) == FAIL)
- break;
- }
- // Mark w_topline as valid, otherwise the screen jumps back at the
- // end of the file.
- check_cursor_moved(curwin);
- curwin->w_valid |= VALID_TOPLINE;
- }
- }
- if (curwin->w_cursor.lnum != prev_lnum)
- coladvance(curwin->w_curswant);
- redraw_later(UPD_VALID);
-}
-
-/*
* Get the count specified after a 'z' command. Only the 'z<CR>', 'zl', 'zh',
* 'z<Left>', and 'z<Right>' commands accept a count after 'z'.
* Returns TRUE to process the 'z' command and FALSE to skip it.
@@ -5743,7 +5695,7 @@ nv_gv_cmd(cmdarg_T *cap)
* "g0", "g^" : Like "0" and "^" but for screen lines.
* "gm": middle of "g0" and "g$".
*/
- static void
+ void
nv_g_home_m_cmd(cmdarg_T *cap)
{
int i;
@@ -5769,6 +5721,15 @@ nv_g_home_m_cmd(cmdarg_T *cap)
i = 0;
if (virtcol >= (colnr_T)width1 && width2 > 0)
i = (virtcol - width1) / width2 * width2 + width1;
+
+ // When ending up below 'smoothscroll' marker, move just beyond it so
+ // that skipcol is not adjusted later.
+ if (curwin->w_skipcol > 0 && curwin->w_cursor.lnum == curwin->w_topline)
+ {
+ int overlap = sms_marker_overlap(curwin, -1);
+ if (overlap > 0 && i == curwin->w_skipcol)
+ i += overlap;
+ }
}
else
i = curwin->w_leftcol;
@@ -6064,7 +6025,7 @@ nv_g_cmd(cmdarg_T *cap)
{
oap->motion_type = MCHAR;
oap->inclusive = FALSE;
- i = linetabsize(curwin, curwin->w_cursor.lnum);
+ i = linetabsize_no_outer(curwin, curwin->w_cursor.lnum);
if (cap->count0 > 0 && cap->count0 <= 100)
coladvance((colnr_T)(i * cap->count0 / 100));
else
@@ -7261,12 +7222,9 @@ nv_at(cmdarg_T *cap)
static void
nv_halfpage(cmdarg_T *cap)
{
- if ((cap->cmdchar == Ctrl_U && curwin->w_cursor.lnum == 1)
- || (cap->cmdchar == Ctrl_D
- && curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count))
- clearopbeep(cap->oap);
- else if (!checkclearop(cap->oap))
- halfpage(cap->cmdchar == Ctrl_D, cap->count0);
+ int dir = cap->cmdchar == Ctrl_D ? FORWARD : BACKWARD;
+ if (!checkclearop(cap->oap))
+ pagescroll(dir, cap->count0, TRUE);
}
/*
diff --git a/src/ops.c b/src/ops.c
index dbdf119..e3e7827 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -281,6 +281,7 @@ shift_block(oparg_T *oap, int amount)
int oldstate = State;
int total;
char_u *newp, *oldp;
+ size_t newlen, oldlen;
int oldcol = curwin->w_cursor.col;
int sw_val = (int)get_sw_value_indent(curbuf);
int ts_val = (int)curbuf->b_p_ts;
@@ -288,7 +289,7 @@ shift_block(oparg_T *oap, int amount)
int incr;
colnr_T ws_vcol;
int added;
- unsigned new_line_len; // the length of the line after the
+ size_t new_line_len; // the length of the line after the
// block shift
#ifdef FEAT_RIGHTLEFT
int old_p_ri = p_ri;
@@ -307,6 +308,7 @@ shift_block(oparg_T *oap, int amount)
return; // multiplication overflow
oldp = ml_get_curline();
+ oldlen = ml_get_curline_len();
if (!left)
{
@@ -369,15 +371,16 @@ shift_block(oparg_T *oap, int amount)
// if we're splitting a TAB, allow for it
bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0);
- new_line_len = bd.textcol + tabs + spaces + (int)STRLEN(bd.textstart);
+ new_line_len = bd.textcol + tabs + spaces + (oldlen - (bd.textstart - oldp));
newp = alloc(new_line_len + 1);
if (newp == NULL)
return;
mch_memmove(newp, oldp, (size_t)bd.textcol);
- vim_memset(newp + bd.textcol, TAB, (size_t)tabs);
- vim_memset(newp + bd.textcol + tabs, ' ', (size_t)spaces);
- // Note that STRMOVE() copies the trailing NUL.
- STRMOVE(newp + bd.textcol + tabs + spaces, bd.textstart);
+ newlen = bd.textcol;
+ vim_memset(newp + newlen, TAB, (size_t)tabs);
+ newlen += tabs;
+ vim_memset(newp + newlen, ' ', (size_t)spaces);
+ STRCPY(newp + newlen + spaces, bd.textstart);
}
else // left
{
@@ -387,11 +390,13 @@ shift_block(oparg_T *oap, int amount)
// copied verbatim
colnr_T verbatim_copy_width;// the (displayed) width of this part
// of line
- unsigned fill; // nr of spaces that replace a TAB
+ size_t fill; // nr of spaces that replace a TAB
size_t block_space_width;
size_t shift_amount;
char_u *non_white = bd.textstart;
colnr_T non_white_col;
+ size_t fixedlen; // length of string left of the shift
+ // position (ie the string not being shifted)
chartabsize_T cts;
/*
@@ -463,21 +468,27 @@ shift_block(oparg_T *oap, int amount)
// - the beginning of the original line up to "verbatim_copy_end",
// - "fill" number of spaces,
// - the rest of the line, pointed to by non_white.
- new_line_len = (unsigned)(verbatim_copy_end - oldp)
- + fill
- + (unsigned)STRLEN(non_white);
+ fixedlen = verbatim_copy_end - oldp;
+ new_line_len = fixedlen + fill + (oldlen - (non_white - oldp));
newp = alloc(new_line_len + 1);
if (newp == NULL)
return;
- mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
- vim_memset(newp + (verbatim_copy_end - oldp), ' ', (size_t)fill);
- // Note that STRMOVE() copies the trailing NUL.
- STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
+ mch_memmove(newp, oldp, fixedlen);
+ newlen = fixedlen;
+ vim_memset(newp + newlen, ' ', (size_t)fill);
+ STRCPY(newp + newlen + fill, non_white);
}
// replace the line
- added = new_line_len - ml_get_curline_len();
ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+
+ // compute the number of bytes added or subtracted.
+ // note new_line_len and oldlen are unsigned so we have
+ // to be careful about how we calculate this.
+ if (new_line_len >= oldlen)
+ added = (int)(new_line_len - oldlen);
+ else
+ added = 0 - (int)(oldlen - new_line_len);
inserted_bytes(curwin->w_cursor.lnum, bd.textcol, added);
State = oldstate;
curwin->w_cursor.col = oldcol;
@@ -494,6 +505,7 @@ shift_block(oparg_T *oap, int amount)
block_insert(
oparg_T *oap,
char_u *s,
+ size_t slen,
int b_insert,
struct block_def *bdp)
{
@@ -502,13 +514,11 @@ block_insert(
int spaces = 0; // non-zero if cutting a TAB
colnr_T offset; // pointer along new line
colnr_T startcol; // column where insert starts
- unsigned s_len; // STRLEN(s)
char_u *newp, *oldp; // new, old lines
linenr_T lnum; // loop var
int oldstate = State;
State = MODE_INSERT; // don't want MODE_REPLACE for State
- s_len = (unsigned)STRLEN(s);
for (lnum = oap->start.lnum + 1; lnum <= oap->end.lnum; lnum++)
{
@@ -554,7 +564,7 @@ block_insert(
spaces = 0;
// Make sure the allocated size matches what is actually copied below.
- newp = alloc(ml_get_len(lnum) + spaces + s_len
+ newp = alloc(ml_get_len(lnum) + spaces + slen
+ (spaces > 0 && !bdp->is_short ? ts_val - spaces : 0)
+ count + 1);
if (newp == NULL)
@@ -569,8 +579,8 @@ block_insert(
startcol = offset + spaces;
// copy the new text
- mch_memmove(newp + startcol, s, (size_t)s_len);
- offset += s_len;
+ mch_memmove(newp + startcol, s, slen);
+ offset += slen;
if (spaces > 0 && !bdp->is_short)
{
@@ -591,13 +601,13 @@ block_insert(
if (spaces > 0)
offset += count;
- STRMOVE(newp + offset, oldp);
+ STRCPY(newp + offset, oldp);
ml_replace(lnum, newp, FALSE);
if (b_insert)
// correct any text properties
- inserted_bytes(lnum, startcol, s_len);
+ inserted_bytes(lnum, startcol, slen);
if (lnum == oap->end.lnum)
{
@@ -809,8 +819,8 @@ op_delete(oparg_T *oap)
vim_memset(newp + bd.textcol, ' ',
(size_t)(bd.startspaces + bd.endspaces));
// copy the part after the deleted part
- oldp += bd.textcol + bd.textlen;
- STRMOVE(newp + bd.textcol + bd.startspaces + bd.endspaces, oldp);
+ STRCPY(newp + bd.textcol + bd.startspaces + bd.endspaces,
+ oldp + bd.textcol + bd.textlen);
// replace the line
ml_replace(lnum, newp, FALSE);
@@ -1030,7 +1040,7 @@ op_replace(oparg_T *oap, int c)
int n, numc;
int num_chars;
char_u *newp, *oldp;
- size_t oldlen;
+ size_t newlen, oldlen;
struct block_def bd;
char_u *after_p = NULL;
int had_ctrl_v_cr = FALSE;
@@ -1122,9 +1132,10 @@ op_replace(oparg_T *oap, int c)
vim_memset(newp, NUL, (size_t)(oldlen + 1 + n));
// copy up to deleted part
mch_memmove(newp, oldp, (size_t)bd.textcol);
- oldp += bd.textcol + bd.textlen;
+ newlen = bd.textcol;
// insert pre-spaces
- vim_memset(newp + bd.textcol, ' ', (size_t)bd.startspaces);
+ vim_memset(newp + newlen, ' ', (size_t)bd.startspaces);
+ newlen += bd.startspaces;
// insert replacement chars CHECK FOR ALLOCATED SPACE
// REPLACE_CR_NCHAR/REPLACE_NL_NCHAR is used for entering CR
// literally.
@@ -1132,27 +1143,31 @@ op_replace(oparg_T *oap, int c)
{
if (has_mbyte)
{
- n = (int)STRLEN(newp);
while (--num_chars >= 0)
- n += (*mb_char2bytes)(c, newp + n);
+ newlen += (*mb_char2bytes)(c, newp + newlen);
}
else
- vim_memset(newp + STRLEN(newp), c, (size_t)numc);
+ {
+ vim_memset(newp + newlen, c, (size_t)numc);
+ newlen += numc;
+ }
if (!bd.is_short)
{
// insert post-spaces
- vim_memset(newp + STRLEN(newp), ' ', (size_t)bd.endspaces);
+ vim_memset(newp + newlen, ' ', (size_t)bd.endspaces);
// copy the part after the changed part
- STRMOVE(newp + STRLEN(newp), oldp);
+ STRCPY(newp + newlen + bd.endspaces,
+ oldp + bd.textcol + bd.textlen);
}
}
else
{
// Replacing with \r or \n means splitting the line.
- after_p = alloc(oldlen + 1 + n - STRLEN(newp));
+ after_p = alloc(oldlen + 1 + n - newlen);
if (after_p != NULL)
- STRMOVE(after_p, oldp);
+ STRCPY(after_p, oldp + bd.textcol + bd.textlen);
}
+
// replace the line
ml_replace(curwin->w_cursor.lnum, newp, FALSE);
if (after_p != NULL)
@@ -1593,12 +1608,12 @@ op_insert(oparg_T *oap, long count1)
if (oap->block_mode)
{
- long ins_len;
+ size_t ins_len;
char_u *firstline, *ins_text;
struct block_def bd2;
int did_indent = FALSE;
size_t len;
- int add;
+ size_t add;
// offset when cursor was moved in insert mode
int offset = 0;
@@ -1703,7 +1718,7 @@ op_insert(oparg_T *oap, long count1)
return;
}
}
- if ((size_t)add > len)
+ if (add > len)
add = len; // short line, point to the NUL
firstline += add;
len -= add;
@@ -1715,7 +1730,7 @@ op_insert(oparg_T *oap, long count1)
// block handled here
if (u_save(oap->start.lnum,
(linenr_T)(oap->end.lnum + 1)) == OK)
- block_insert(oap, ins_text, (oap->op_type == OP_INSERT),
+ block_insert(oap, ins_text, ins_len, (oap->op_type == OP_INSERT),
&bd);
curwin->w_cursor.col = oap->start.col;
@@ -1736,9 +1751,7 @@ op_change(oparg_T *oap)
{
colnr_T l;
int retval;
- long offset;
linenr_T linenr;
- long ins_len;
long pre_textlen = 0;
long pre_indent = 0;
char_u *firstline;
@@ -1798,6 +1811,8 @@ op_change(oparg_T *oap)
*/
if (oap->block_mode && oap->start.lnum != oap->end.lnum && !got_int)
{
+ size_t ins_len;
+
// Auto-indenting may have changed the indent. If the cursor was past
// the indent, exclude that indent change from the inserted text.
firstline = ml_get(oap->start.lnum);
@@ -1816,7 +1831,7 @@ op_change(oparg_T *oap)
// copy of the inserted text.
if ((ins_text = alloc(ins_len + 1)) != NULL)
{
- vim_strncpy(ins_text, firstline + bd.textcol, (size_t)ins_len);
+ vim_strncpy(ins_text, firstline + bd.textcol, ins_len);
for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum;
linenr++)
{
@@ -1824,6 +1839,7 @@ op_change(oparg_T *oap)
if (!bd.is_short || virtual_op)
{
pos_T vpos;
+ size_t newlen;
// If the block starts in virtual space, count the
// initial coladd offset as part of "startspaces"
@@ -1835,19 +1851,16 @@ op_change(oparg_T *oap)
else
vpos.coladd = 0;
oldp = ml_get(linenr);
- newp = alloc(ml_get_len(linenr)
- + vpos.coladd + ins_len + 1);
+ newp = alloc(ml_get_len(linenr) + vpos.coladd + ins_len + 1);
if (newp == NULL)
continue;
// copy up to block start
mch_memmove(newp, oldp, (size_t)bd.textcol);
- offset = bd.textcol;
- vim_memset(newp + offset, ' ', (size_t)vpos.coladd);
- offset += vpos.coladd;
- mch_memmove(newp + offset, ins_text, (size_t)ins_len);
- offset += ins_len;
- oldp += bd.textcol;
- STRMOVE(newp + offset, oldp);
+ newlen = bd.textcol;
+ vim_memset(newp + newlen, ' ', (size_t)vpos.coladd);
+ newlen += vpos.coladd;
+ mch_memmove(newp + newlen, ins_text, ins_len);
+ STRCPY(newp + newlen + ins_len, oldp + bd.textcol);
ml_replace(linenr, newp, FALSE);
#ifdef FEAT_PROP_POPUP
// Shift the properties for linenr as edit() would do.
diff --git a/src/option.c b/src/option.c
index 8123a2a..0cd2823 100644
--- a/src/option.c
+++ b/src/option.c
@@ -364,6 +364,68 @@ set_init_clean_rtp(void)
}
#endif
+#ifdef UNIX
+/*
+ * Change 'runtimepath' and 'packdir' to '$XDG_CONFIG_HOME/vim' if the only
+ * vimrc found is located in '$XDG_CONFIG_HOME/vim/vimrc'.
+ * In case the '$XDG_CONFIG_HOME' variable is not set, '$HOME/.config' is used
+ * as a fallback as is defined in the XDG base dir specification:
+ * <https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html>
+ */
+ static void
+set_init_xdg_rtp(void)
+{
+ int opt_idx;
+ int has_xdg_env = TRUE;
+ int should_free_xdg_dir = FALSE;
+ char_u *vimrc1 = NULL;
+ char_u *vimrc2 = NULL;
+ char_u *xdg_dir = NULL;
+ char_u *xdg_rtp = NULL;
+ char_u *vimrc_xdg = NULL;
+
+ // initialize chartab, so we can expand $HOME
+ (void)init_chartab();
+ vimrc1 = expand_env_save((char_u *)USR_VIMRC_FILE);
+ vimrc2 = expand_env_save((char_u *)USR_VIMRC_FILE2);
+
+ xdg_dir = mch_getenv("XDG_CONFIG_HOME");
+ if (!xdg_dir)
+ {
+ xdg_dir = expand_env_save((char_u *)"~/.config");
+ should_free_xdg_dir = TRUE;
+ has_xdg_env = FALSE;
+ }
+ vimrc_xdg = concat_fnames(xdg_dir, (char_u *)"vim/vimrc", TRUE);
+
+ if (file_is_readable(vimrc1) || file_is_readable(vimrc2) ||
+ !file_is_readable(vimrc_xdg))
+ goto theend;
+
+ xdg_rtp = has_xdg_env ? (char_u *)XDG_RUNTIMEPATH
+ : (char_u *)XDG_RUNTIMEPATH_FB;
+
+ if ((opt_idx = findoption((char_u *)"runtimepath")) < 0)
+ goto theend;
+
+ options[opt_idx].def_val[VI_DEFAULT] = xdg_rtp;
+ p_rtp = xdg_rtp;
+
+ if ((opt_idx = findoption((char_u *)"packpath")) < 0)
+ goto theend;
+
+ options[opt_idx].def_val[VI_DEFAULT] = xdg_rtp;
+ p_pp = xdg_rtp;
+
+theend:
+ vim_free(vimrc1);
+ vim_free(vimrc2);
+ vim_free(vimrc_xdg);
+ if (should_free_xdg_dir)
+ vim_free(xdg_dir);
+}
+#endif
+
/*
* Expand environment variables and things like "~" for the defaults.
* If option_expand() returns non-NULL the variable is expanded. This can
@@ -588,6 +650,7 @@ set_init_1(int clean_arg)
set_options_default(0);
#ifdef UNIX
+ set_init_xdg_rtp();
set_init_restricted_mode();
#endif
@@ -792,7 +855,10 @@ set_string_default_esc(char *name, char_u *val, int escape)
opt_idx = findoption((char_u *)name);
if (opt_idx < 0)
+ {
+ vim_free(p);
return;
+ }
if (options[opt_idx].flags & P_DEF_ALLOCED)
vim_free(options[opt_idx].def_val[VI_DEFAULT]);
@@ -3678,7 +3744,7 @@ did_set_modified(optset_T *args)
if (!args->os_newval.boolean)
save_file_ff(curbuf); // Buffer is unchanged
redraw_titles();
- modified_was_set = args->os_newval.boolean;
+ curbuf->b_modified_was_set = args->os_newval.boolean;
return NULL;
}
diff --git a/src/optiondefs.h b/src/optiondefs.h
index 4ee2e20..33e3165 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -300,7 +300,7 @@ struct vimoption
# define ISP_LATIN1 (char_u *)"@,161-255"
#endif
-# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC"
+# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC,g:MsgArea"
// Default python version for pyx* commands
#if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
@@ -3014,6 +3014,7 @@ static struct vimoption options[] =
p_term("t_8f", T_8F)
p_term("t_8b", T_8B)
p_term("t_8u", T_8U)
+ p_term("t_xo", T_XON)
// terminal key codes are not in here
diff --git a/src/optionstr.c b/src/optionstr.c
index e5f4946..45f126f 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -4332,7 +4332,7 @@ do_filetype_autocmd(char_u **varp, int opt_flags, int value_changed)
secure = 0;
++ft_recursive;
- did_filetype = TRUE;
+ curbuf->b_did_filetype = TRUE;
// Only pass TRUE for "force" when the value changed or not
// used recursively, to avoid endless recurrence.
apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft, curbuf->b_fname,
diff --git a/src/os_unix.c b/src/os_unix.c
index e98911e..d155142 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3766,7 +3766,8 @@ mch_settmode(tmode_T tmode)
{
// ~ICRNL enables typing ^V^M
// ~IXON disables CTRL-S stopping output, so that it can be mapped.
- tnew.c_iflag &= ~(ICRNL | IXON);
+ tnew.c_iflag &= ~(ICRNL |
+ (T_XON == NULL || *T_XON == NUL ? IXON : 0));
tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE
# if defined(IEXTEN)
| IEXTEN // IEXTEN enables typing ^V on SOLARIS
@@ -7494,7 +7495,19 @@ gpm_open(void)
return 1; // succeed
}
if (gpm_fd == -2)
+ {
Gpm_Close(); // We don't want to talk to xterm via gpm
+
+ // Gpm_Close fails to properly restore the WINCH and TSTP handlers,
+ // leading to Vim ignoring resize signals. We have to re-initialize
+ // these handlers again here.
+# ifdef SIGWINCH
+ mch_signal(SIGWINCH, sig_winch);
+# endif
+# ifdef SIGTSTP
+ mch_signal(SIGTSTP, restricted ? SIG_IGN : sig_tstp);
+# endif
+ }
return 0;
}
diff --git a/src/os_unix.h b/src/os_unix.h
index 4c77e15..6efd8ce 100644
--- a/src/os_unix.h
+++ b/src/os_unix.h
@@ -249,6 +249,12 @@ typedef struct dsc$descriptor DESC;
# endif
#endif
+#ifndef XDG_VIMRC_FILE
+# define XDG_VIMRC_FILE (mch_getenv("XDG_CONFIG_HOME") \
+ ? "$XDG_CONFIG_HOME/vim/vimrc" \
+ : "~/.config/vim/vimrc")
+#endif
+
#if !defined(USR_VIMRC_FILE3) && defined(VMS)
# define USR_VIMRC_FILE3 "sys$login:_vimrc"
#endif
@@ -273,6 +279,12 @@ typedef struct dsc$descriptor DESC;
# ifndef USR_GVIMRC_FILE3
# define USR_GVIMRC_FILE3 "sys$login:_gvimrc"
# endif
+#else
+# ifndef USR_GVIMRC_FILE3
+# define USR_GVIMRC_FILE3 (mch_getenv("XDG_CONFIG_HOME") \
+ ? "$XDG_CONFIG_HOME/vim/gvimrc" \
+ : "~/.config/vim/gvimrc")
+# endif
#endif
#ifndef VIM_DEFAULTS_FILE
@@ -349,13 +361,19 @@ typedef struct dsc$descriptor DESC;
# ifdef RUNTIME_GLOBAL
# ifdef RUNTIME_GLOBAL_AFTER
# define DFLT_RUNTIMEPATH "~/.vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER ",~/.vim/after"
+# define XDG_RUNTIMEPATH "$XDG_CONFIG_HOME/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER "/after,$XDG_CONFIG_HOME/vim/after"
+# define XDG_RUNTIMEPATH_FB "~/.config/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER "/after,~/.config/vim/after"
# define CLEAN_RUNTIMEPATH RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER
# else
# define DFLT_RUNTIMEPATH "~/.vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after,~/.vim/after"
+# define XDG_RUNTIMEPATH "$XDG_CONFIG_HOME/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after,$XDG_CONFIG_HOME/vim/after"
+# define XDG_RUNTIMEPATH_FB "~/.config/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after,~/.config/vim/after"
# define CLEAN_RUNTIMEPATH RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after"
# endif
# else
# define DFLT_RUNTIMEPATH "~/.vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,~/.vim/after"
+# define XDG_RUNTIMEPATH "$XDG_CONFIG_HOME/vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,$XDG_CONFIG_HOME/vim/after"
+# define XDG_RUNTIMEPATH_FB "~/.config/vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,~/.config/vim/after"
# define CLEAN_RUNTIMEPATH "$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after"
# endif
# endif
diff --git a/src/po/Make_mvc.mak b/src/po/Make_mvc.mak
index fa6a1ba..a9a69fd 100644
--- a/src/po/Make_mvc.mak
+++ b/src/po/Make_mvc.mak
@@ -44,7 +44,9 @@ VIM = ..\vim.exe
# Correct the following line for the directory where gettext et al is
# installed. Please do not put the path in quotes.
+!IFNDEF GETTEXT_PATH
GETTEXT_PATH = D:\Programs\GetText\bin
+!ENDIF
# Starting from version 0.22, msgfmt forcibly converts text to UTF-8 regardless
# of the value of the "charset" field.
diff --git a/src/po/check.vim b/src/po/check.vim
index 917c648..b0460f1 100644
--- a/src/po/check.vim
+++ b/src/po/check.vim
@@ -226,6 +226,15 @@ elseif ctu
" endif
endif
+" Check that all lines are no longer than 80 chars
+let overlong = search('\%>80v', 'n')
+if overlong > 0
+ echomsg "Lines should be wrapped at 80 columns"
+ " TODO: make this an error
+ " if error == 0
+ " let error = overlong
+ " endif
+endif
if error == 0
" If all was OK restore the view.
diff --git a/src/po/ru.cp1251.po b/src/po/ru.cp1251.po
index 2dd453a..05d10e0 100644
--- a/src/po/ru.cp1251.po
+++ b/src/po/ru.cp1251.po
@@ -21,10 +21,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: RuVim_0.9010059.260124\n"
+"Project-Id-Version: RuVim_0.9010225.290324\n"
"Report-Msgid-Bugs-To: The Vim Project, <vim-dev@vim.org>\n"
-"POT-Creation-Date: 2024-01-26 14:54+0300\n"
-"PO-Revision-Date: 2024-01-26 14:57+0300\n"
+"POT-Creation-Date: 2024-03-29 13:02+0300\n"
+"PO-Revision-Date: 2024-03-29 13:57+0300\n"
"Last-Translator: Restorer, <restorer@mail2k.ru>\n"
"Language-Team: RuVim, https://github.com/RestorerZ/RuVim\n"
"Language: ru_RU\n"
@@ -692,7 +692,7 @@ msgstr "×æóèíü (áîïîìîôî)"
# :!~ Restorer
msgid "Not enough memory to set references, garbage collection aborted!"
-msgstr "Ñáîðêà ìóñîðà ïðåðâàíà! Íåäîñòàòî÷íî ïàìÿòè äëÿ óñòàíîâêè ññûëîê"
+msgstr "Ñáîð ìóñîðà ïðåðâàí! Íåäîñòàòî÷íî ïàìÿòè äëÿ óñòàíîâêè ññûëîê"
# #Restorer: âûâîäèòñÿ ïðè çíà÷åíèè 'verbose'>0
# :!~ Restorer
@@ -2490,11 +2490,11 @@ msgstr "--ttyfail\t\tÇàâåðøèòü ðàáîòó ïðè îòñóòñòâèè òåðìèíàëà ââîäà-âûâîäà"
# :!~ Restorer
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <ôàéë>\t\tÏðèìåíèòü âìåñòî ôàéëîâ .vimrc óêàçàííûé <ôàéë>"
+msgstr "-u <ôàéë>\t\tÈñïîëüçîâàòü âìåñòî ôàéëîâ .vimrc óêàçàííûé <ôàéë>"
# :!~ Restorer
msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-msgstr "-U <ôàéë>\t\tÏðèìåíèòü âìåñòî ôàéëîâ .gvimrc óêàçàííûé <ôàéë>"
+msgstr "-U <ôàéë>\t\tÈñïîëüçîâàòü âìåñòî ôàéëîâ .gvimrc óêàçàííûé <ôàéë>"
# :!~ Restorer
msgid "--noplugin\t\tDon't load plugin scripts"
@@ -2511,7 +2511,7 @@ msgstr ""
# :!~ Restorer
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr ""
-"-o[N]\t\tÑîçäàòü îêíà äëÿ N ôàéëîâ (ïî óìîë÷àíèþ ñîçäà¸òñÿ\n"
+"-o[N]\t\tÑîçäàíèå îêîí äëÿ N ôàéëîâ (ïî óìîë÷àíèþ ñîçäà¸òñÿ\n"
"\t\t\t ïî îäíîìó îêíó íà êàæäûé ôàéë)"
# :!~ Restorer
@@ -2528,19 +2528,19 @@ msgstr "+<íîìåð>\t\tÓñòàíîâêà êàðåòêè íà <íîìåð> ñòðîêè îòêðûòîãî ôàéëà"
# :!~ Restorer
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <êîìàíäà>\tÂûïîëíåíèå <êîìàíäû> ïåðåä îáðàáîòêîé ôàéëà .vimrc"
+msgstr "--cmd <êîìàíäà>\tÈñïîëíåíèå <êîìàíäû> ïåðåä îáðàáîòêîé ôàéëà .vimrc"
# ~!: earlier
msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <êîìàíäà>\t\tÂûïîëíåíèå <êîìàíäû> ïîñëå çàãðóçêè ïåðâîãî ôàéëà"
+msgstr "-c <êîìàíäà>\t\tÈñïîëíåíèå <êîìàíäû> ïîñëå ñ÷èòûâàíèÿ ïåðâîãî ôàéëà"
# :!~ Restorer
msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <ñåàíñ>\t\tÂûïîëíåíèå ôàéëà <ñåàíñà> ïîñëå çàãðóçêè ïåðâîãî ôàéëà"
+msgstr "-S <ñåàíñ>\t\tÇàïóñê ôàéëà <ñåàíñà> ïîñëå ñ÷èòûâàíèÿ ïåðâîãî ôàéëà"
# :!~ Restorer
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <ñöåíàðèé>\tÑ÷èòàòü êîìàíäû ðåæèìà êîìàíä èç ôàéëà <ñöåíàðèÿ>"
+msgstr "-s <ñöåíàðèé>\tÑ÷èòûâàíèå êîìàíä ðåæèìà êîìàíä èç ôàéëà <ñöåíàðèÿ>"
# :!~ Restorer
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
@@ -2556,8 +2556,7 @@ msgstr "-x\t\t\tÈñïîëüçîâàòü øèôðîâàíèå ïðè ñ÷èòûâàíèè è çàïèñè ôàéëîâ"
# :!~ Restorer
msgid "-display <display>\tConnect Vim to this particular X-server"
-msgstr ""
-"-display <display>\tÂûïîëíèòü ïîäêëþ÷åíèå ïðîãðàììû ê óêàçàííîìó X-ñåðâåðó"
+msgstr "-display <display>\tÏîäêëþ÷åíèå ïðîãðàììû ê óêàçàííîìó X-ñåðâåðó"
# :!~ Restorer
msgid "-X\t\t\tDo not connect to X server"
@@ -2620,7 +2619,7 @@ msgstr ""
# :!~ Restorer
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <ôàéë>\t\tÈñïîëüçîâàíèå âìåñòî ôàéëà .viminfo óêàçàííîãî <ôàéëà>"
+msgstr "-i <ôàéë>\t\tÈñïîëüçîâàòü âìåñòî ôàéëà .viminfo óêàçàííûé <ôàéë>"
# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ (Ñ. Àë¸øèí)
# :!~ Restorer
@@ -6106,6 +6105,11 @@ msgstr "E105: Êîìàíäà :loadkeymap óêàçàíà âíå êîìàíäíîãî ôàéëà"
# :!~ Restorer
#, c-format
+msgid "E106: Unsupported diff output format: %s"
+msgstr "E106: Óêàçàííûé ôîðìàò ðåçóëüòàòà ñðàâíåíèÿ íå ïîääåðæèâàåòñÿ %s"
+
+# :!~ Restorer
+#, c-format
msgid "E107: Missing parentheses: %s"
msgstr "E107: Íå óêàçàíû àðãóìåíòû â êðóãëûõ ñêîáêàõ ïðè âûçîâå ôóíêöèè %s"
@@ -9695,6 +9699,11 @@ msgid "E876: (NFA regexp) Not enough space to store the whole NFA"
msgstr "E876: ÍÊÀ. Íåäîñòàòî÷íî ïàìÿòè äëÿ ñîõðàíåíèÿ âñåõ ñîñòîÿíèé ìåõàíèçìà"
# :!~ Restorer
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %d"
+msgstr "E877: ÍÊÀ. Íå óäàëîñü ðàñïîçíàòü ñèìâîëüíûé êëàññ %d"
+
+# :!~ Restorer
msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!"
msgstr "E878: ÍÊÀ. Íå óäàëîñü âûäåëèòü ïàìÿòü äëÿ îáõîäà âåòâè!"
@@ -12273,6 +12282,88 @@ msgstr "E1411: Íå óêàçàí ñèìâîë òî÷êè ïîñëå íàèìåíîâàíèÿ îáúåêòà %s"
# :!~ Restorer
#, c-format
+msgid "E1412: Builtin object method \"%s\" not supported"
+msgstr "E1412: Íå ïîääåðæèâàåòñÿ âñòðîåííûé ìåòîä îáúåêòà \"%s\""
+
+# :!~ Restorer
+msgid "E1413: Builtin class method not supported"
+msgstr "E1413: Â êëàññå íå äîñòóïíû âñòðîåííûå ìåòîäû"
+
+# :!~ Restorer
+msgid "E1414: Enum can only be defined in Vim9 script"
+msgstr ""
+"E1414: Òèï äàííûõ Enum ìîæåò áûòü îïðåäåë¸í òîëüêî â êîìàíäíûõ ôàéëàõ Vim9"
+
+# :!~ Restorer
+#, c-format
+msgid "E1415: Enum name must start with an uppercase letter: %s"
+msgstr "E1415: Íàèìåíîâàíèå òèïà Enum äîëæíî íà÷èíàòüñÿ ñ ïðîïèñíîé áóêâû %s"
+
+# :!~ Restorer
+msgid "E1416: Enum cannot extend a class or enum"
+msgstr "E1416: Òèï Enum íå ìîæåò íàñëåäîâàòüñÿ â êëàññàõ èëè äðóãèõ òèïàõ Enum"
+
+# :!~ Restorer
+msgid "E1417: Abstract cannot be used in an Enum"
+msgstr "E1417: Èíòåðôåéñû íå ïîääåðæèâàþò òèïû äàííûõ Enum"
+
+# :!~ Restorer
+#, c-format
+msgid "E1418: Invalid enum value declaration: %s"
+msgstr "E1418: Íåäîïóñòèìîå îáúÿâëåíèå ïåðåìåííîé òèïà äàííûõ Enum %s"
+
+# :!~ Restorer
+#, c-format
+msgid "E1419: Not a valid command in an Enum: %s"
+msgstr "E1419: Íåäîïóñòèìàÿ êîìàíäà â îáúÿâëåíèè òèïà äàííûõ Enum %s"
+
+# :!~ Restorer
+msgid "E1420: Missing :endenum"
+msgstr "E1420: Íå óêàçàíà êîìàíäà :endenum"
+
+# :!~ Restorer
+#, c-format
+msgid "E1421: Enum \"%s\" cannot be used as a value"
+msgstr "E1421: Íå äîïóñêàåòñÿ â êà÷åñòâå çíà÷åíèÿ óêàçûâàòü òèï Enum \"%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1422: Enum value \"%s\" not found in enum \"%s\""
+msgstr "E1422: Ó òèïà äàííûõ Enum \"%2$s\" îòñóòñòâóåò ïåðåìåííàÿ \"%1$s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1423: Enum value \"%s.%s\" cannot be modified"
+msgstr "E1423: Íå äîïóñêàåòñÿ èçìåíåíèå çíà÷åíèÿ òèïà Enum \"%s.%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1424: Using an Enum \"%s\" as a Number"
+msgstr "E1424: Îæèäàëñÿ òèï äàííûõ Number, à ïîëó÷åí òèï äàííûõ Enum \"%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1425: Using an Enum \"%s\" as a String"
+msgstr "E1425: Îæèäàëñÿ òèï äàííûõ String, à ïîëó÷åí òèï äàííûõ Enum \"%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1426: Enum \"%s\" ordinal value cannot be modified"
+msgstr ""
+"E1426: Íå äîïóñêàåòñÿ èçìåíåíèå ïîðÿäêà çíà÷åíèé â òèïå äàííûõ Enum \"%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1427: Enum \"%s\" name cannot be modified"
+msgstr "E1427: Íå äîïóñêàåòñÿ èçìåíåíèå íàèìåíîâàíèÿ òèïà äàííûõ Enum \"%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1428: Duplicate enum value: %s"
+msgstr "E1428: Ïîâòîð çíà÷åíèÿ %s"
+
+# :!~ Restorer
+#, c-format
msgid "E1500: Cannot mix positional and non-positional arguments: %s"
msgstr "E1500: Óêàçàíû êàê ïîçèöèîííûå, òàê è íå ïîçèöèîííûå ñïåöèôèêàòîðû %s"
@@ -12340,6 +12431,10 @@ msgstr "E1511:  äàííîì ïîëå óêàçàíî íåäîïóñòèìîå êîëè÷åñòâî ñèìâîëîâ \"%s\""
msgid "E1512: Wrong character width for field \"%s\""
msgstr "E1512: Â äàííîì ïîëå íå ïîääåðæèâàþòñÿ ïîëíîøèðèííûå ñèìâîëû \"%s\""
+# :!~ Restorer
+msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled"
+msgstr "E1513: Íå óäàëîñü ñìåíèòü áóôåð. Óñòàíîâëåí ïàðàìåòð 'winfixbuf'"
+
# #Restorer: âûâîäèòñÿ, íàïðèìåð, ïî êîìàíäå `CTRL+g`, `g CTRL+g` è ò. ï.
# :!~ Restorer
msgid "--No lines in buffer--"
@@ -13331,6 +13426,10 @@ msgid "minimal number of lines used for any window"
msgstr "ìèíèìàëüíîå êîëè÷åñòâî ñòðîê äëÿ âñåõ îêîí"
# :!~ Restorer
+msgid "keep window focused on a single buffer"
+msgstr "çàêðåïèòü çà îêíîì îäèí áóôåð"
+
+# :!~ Restorer
msgid "keep the height of the window"
msgstr "îñòàâëÿòü íåèçìåííîé âûñîòó îêíà"
diff --git a/src/po/ru.po b/src/po/ru.po
index d4b7d6b..13589d0 100644
--- a/src/po/ru.po
+++ b/src/po/ru.po
@@ -21,10 +21,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: RuVim_0.9010059.260124\n"
+"Project-Id-Version: RuVim_0.9010225.290324\n"
"Report-Msgid-Bugs-To: The Vim Project, <vim-dev@vim.org>\n"
-"POT-Creation-Date: 2024-01-26 14:54+0300\n"
-"PO-Revision-Date: 2024-01-26 14:57+0300\n"
+"POT-Creation-Date: 2024-03-29 13:02+0300\n"
+"PO-Revision-Date: 2024-03-29 13:57+0300\n"
"Last-Translator: Restorer, <restorer@mail2k.ru>\n"
"Language-Team: RuVim, https://github.com/RestorerZ/RuVim\n"
"Language: ru_RU\n"
@@ -691,7 +691,7 @@ msgstr "Чжуинь (бопомофо)"
# :!~ Restorer
msgid "Not enough memory to set references, garbage collection aborted!"
-msgstr "Сборка муÑора прервана! ÐедоÑтаточно памÑти Ð´Ð»Ñ ÑƒÑтановки ÑÑылок"
+msgstr "Сбор муÑора прерван! ÐедоÑтаточно памÑти Ð´Ð»Ñ ÑƒÑтановки ÑÑылок"
# #Restorer: выводитÑÑ Ð¿Ñ€Ð¸ значении 'verbose'>0
# :!~ Restorer
@@ -2482,11 +2482,11 @@ msgstr "--ttyfail\t\tЗавершить работу при отÑутÑтвии
# :!~ Restorer
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <файл>\t\tПрименить вмеÑто файлов .vimrc указанный <файл>"
+msgstr "-u <файл>\t\tИÑпользовать вмеÑто файлов .vimrc указанный <файл>"
# :!~ Restorer
msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-msgstr "-U <файл>\t\tПрименить вмеÑто файлов .gvimrc указанный <файл>"
+msgstr "-U <файл>\t\tИÑпользовать вмеÑто файлов .gvimrc указанный <файл>"
# :!~ Restorer
msgid "--noplugin\t\tDon't load plugin scripts"
@@ -2503,7 +2503,7 @@ msgstr ""
# :!~ Restorer
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr ""
-"-o[N]\t\tСоздать окна Ð´Ð»Ñ N файлов (по умолчанию ÑоздаётÑÑ\n"
+"-o[N]\t\tСоздание окон Ð´Ð»Ñ N файлов (по умолчанию ÑоздаётÑÑ\n"
"\t\t\t по одному окну на каждый файл)"
# :!~ Restorer
@@ -2520,19 +2520,19 @@ msgstr "+<номер>\t\tУÑтановка каретки на <номер> ÑÑ
# :!~ Restorer
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <команда>\tВыполнение <команды> перед обработкой файла .vimrc"
+msgstr "--cmd <команда>\tИÑполнение <команды> перед обработкой файла .vimrc"
# ~!: earlier
msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <команда>\t\tВыполнение <команды> поÑле загрузки первого файла"
+msgstr "-c <команда>\t\tИÑполнение <команды> поÑле ÑÑ‡Ð¸Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð¿ÐµÑ€Ð²Ð¾Ð³Ð¾ файла"
# :!~ Restorer
msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <ÑеанÑ>\t\tВыполнение файла <ÑеанÑа> поÑле загрузки первого файла"
+msgstr "-S <ÑеанÑ>\t\tЗапуÑк файла <ÑеанÑа> поÑле ÑÑ‡Ð¸Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð¿ÐµÑ€Ð²Ð¾Ð³Ð¾ файла"
# :!~ Restorer
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <Ñценарий>\tСчитать команды режима команд из файла <ÑценариÑ>"
+msgstr "-s <Ñценарий>\tСчитывание команд режима команд из файла <ÑценариÑ>"
# :!~ Restorer
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
@@ -2548,8 +2548,7 @@ msgstr "-x\t\t\tИÑпользовать шифрование при ÑчитыÐ
# :!~ Restorer
msgid "-display <display>\tConnect Vim to this particular X-server"
-msgstr ""
-"-display <display>\tВыполнить подключение программы к указанному X-Ñерверу"
+msgstr "-display <display>\tПодключение программы к указанному X-Ñерверу"
# :!~ Restorer
msgid "-X\t\t\tDo not connect to X server"
@@ -2608,7 +2607,7 @@ msgstr "--log <файл>\t\tЗапиÑÑŒ протокола работы Ñ ÑÑ‚
# :!~ Restorer
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <файл>\t\tИÑпользование вмеÑто файла .viminfo указанного <файла>"
+msgstr "-i <файл>\t\tИÑпользовать вмеÑто файла .viminfo указанный <файл>"
# \n\t\t.. Ð´Ð»Ñ ÑƒÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² 80 Ñтолбцов (С. Ðлёшин)
# :!~ Restorer
@@ -6070,6 +6069,11 @@ msgstr "E105: Команда :loadkeymap указана вне командноÐ
# :!~ Restorer
#, c-format
+msgid "E106: Unsupported diff output format: %s"
+msgstr "E106: Указанный формат результата ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ поддерживаетÑÑ %s"
+
+# :!~ Restorer
+#, c-format
msgid "E107: Missing parentheses: %s"
msgstr "E107: Ðе указаны аргументы в круглых Ñкобках при вызове функции %s"
@@ -9627,6 +9631,11 @@ msgid "E876: (NFA regexp) Not enough space to store the whole NFA"
msgstr "E876: ÐКÐ. ÐедоÑтаточно памÑти Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ñех ÑоÑтоÑний механизма"
# :!~ Restorer
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %d"
+msgstr "E877: ÐКÐ. Ðе удалоÑÑŒ раÑпознать Ñимвольный клаÑÑ %d"
+
+# :!~ Restorer
msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!"
msgstr "E878: ÐКÐ. Ðе удалоÑÑŒ выделить памÑÑ‚ÑŒ Ð´Ð»Ñ Ð¾Ð±Ñ…Ð¾Ð´Ð° ветви!"
@@ -12183,6 +12192,88 @@ msgstr "E1411: Ðе указан Ñимвол точки поÑле наимен
# :!~ Restorer
#, c-format
+msgid "E1412: Builtin object method \"%s\" not supported"
+msgstr "E1412: Ðе поддерживаетÑÑ Ð²Ñтроенный метод объекта \"%s\""
+
+# :!~ Restorer
+msgid "E1413: Builtin class method not supported"
+msgstr "E1413: Ð’ клаÑÑе не доÑтупны вÑтроенные методы"
+
+# :!~ Restorer
+msgid "E1414: Enum can only be defined in Vim9 script"
+msgstr ""
+"E1414: Тип данных Enum может быть определён только в командных файлах Vim9"
+
+# :!~ Restorer
+#, c-format
+msgid "E1415: Enum name must start with an uppercase letter: %s"
+msgstr "E1415: Ðаименование типа Enum должно начинатьÑÑ Ñ Ð¿Ñ€Ð¾Ð¿Ð¸Ñной буквы %s"
+
+# :!~ Restorer
+msgid "E1416: Enum cannot extend a class or enum"
+msgstr "E1416: Тип Enum не может наÑледоватьÑÑ Ð² клаÑÑах или других типах Enum"
+
+# :!~ Restorer
+msgid "E1417: Abstract cannot be used in an Enum"
+msgstr "E1417: ИнтерфейÑÑ‹ не поддерживают типы данных Enum"
+
+# :!~ Restorer
+#, c-format
+msgid "E1418: Invalid enum value declaration: %s"
+msgstr "E1418: ÐедопуÑтимое объÑвление переменной типа данных Enum %s"
+
+# :!~ Restorer
+#, c-format
+msgid "E1419: Not a valid command in an Enum: %s"
+msgstr "E1419: ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° в объÑвлении типа данных Enum %s"
+
+# :!~ Restorer
+msgid "E1420: Missing :endenum"
+msgstr "E1420: Ðе указана команда :endenum"
+
+# :!~ Restorer
+#, c-format
+msgid "E1421: Enum \"%s\" cannot be used as a value"
+msgstr "E1421: Ðе допуÑкаетÑÑ Ð² качеÑтве Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÑƒÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ тип Enum \"%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1422: Enum value \"%s\" not found in enum \"%s\""
+msgstr "E1422: У типа данных Enum \"%2$s\" отÑутÑтвует Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ \"%1$s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1423: Enum value \"%s.%s\" cannot be modified"
+msgstr "E1423: Ðе допуÑкаетÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° Enum \"%s.%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1424: Using an Enum \"%s\" as a Number"
+msgstr "E1424: ОжидалÑÑ Ñ‚Ð¸Ð¿ данных Number, а получен тип данных Enum \"%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1425: Using an Enum \"%s\" as a String"
+msgstr "E1425: ОжидалÑÑ Ñ‚Ð¸Ð¿ данных String, а получен тип данных Enum \"%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1426: Enum \"%s\" ordinal value cannot be modified"
+msgstr ""
+"E1426: Ðе допуÑкаетÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ порÑдка значений в типе данных Enum \"%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1427: Enum \"%s\" name cannot be modified"
+msgstr "E1427: Ðе допуÑкаетÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ Ð½Ð°Ð¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° данных Enum \"%s\""
+
+# :!~ Restorer
+#, c-format
+msgid "E1428: Duplicate enum value: %s"
+msgstr "E1428: Повтор Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ %s"
+
+# :!~ Restorer
+#, c-format
msgid "E1500: Cannot mix positional and non-positional arguments: %s"
msgstr "E1500: Указаны как позиционные, так и не позиционные Ñпецификаторы %s"
@@ -12248,6 +12339,10 @@ msgstr "E1511: Ð’ данном поле указано недопуÑтимое
msgid "E1512: Wrong character width for field \"%s\""
msgstr "E1512: Ð’ данном поле не поддерживаютÑÑ Ð¿Ð¾Ð»Ð½Ð¾ÑˆÐ¸Ñ€Ð¸Ð½Ð½Ñ‹Ðµ Ñимволы \"%s\""
+# :!~ Restorer
+msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled"
+msgstr "E1513: Ðе удалоÑÑŒ Ñменить буфер. УÑтановлен параметр 'winfixbuf'"
+
# #Restorer: выводитÑÑ, например, по команде `CTRL+g`, `g CTRL+g` и Ñ‚. п.
# :!~ Restorer
msgid "--No lines in buffer--"
@@ -13235,6 +13330,10 @@ msgid "minimal number of lines used for any window"
msgstr "минимальное количеÑтво Ñтрок Ð´Ð»Ñ Ð²Ñех окон"
# :!~ Restorer
+msgid "keep window focused on a single buffer"
+msgstr "закрепить за окном один буфер"
+
+# :!~ Restorer
msgid "keep the height of the window"
msgstr "оÑтавлÑÑ‚ÑŒ неизменной выÑоту окна"
diff --git a/src/po/sr.po b/src/po/sr.po
index 2f5113c..6372f92 100644
--- a/src/po/sr.po
+++ b/src/po/sr.po
@@ -10,8 +10,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim(Serbian)\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-03-04 14:05+0400\n"
-"PO-Revision-Date: 2024-03-04 14:10+0400\n"
+"POT-Creation-Date: 2024-04-25 12:55+0400\n"
+"PO-Revision-Date: 2024-04-25 13:09+0400\n"
"Last-Translator: Ivan Pešić <ivan.pesic@gmail.com>\n"
"Language-Team: Serbian\n"
"Language: sr\n"
@@ -3622,6 +3622,9 @@ msgstr " 2ги кориÑнички vimrc фајл: \""
msgid " 3rd user vimrc file: \""
msgstr " 3ћи кориÑнички vimrc фајл: \""
+msgid " 4th user vimrc file: \""
+msgstr " 4ти кориÑнички vimrc фајл: \""
+
msgid " user exrc file: \""
msgstr " кориÑнички exrc фајл: \""
@@ -6834,6 +6837,10 @@ msgstr ""
"E876: (ÐКРрегуларни израз) Ðема довољно проÑтора да Ñе уÑкладишти комплетан "
"ÐКÐ"
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %d"
+msgstr "E877: (ÐКРрегуларни израз) ÐеиÑправна клаÑа карактера: %d"
+
msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!"
msgstr ""
"E878: (ÐКРрегуларни израз) Ðије могла да Ñе алоцира меморија за обилазак "
@@ -8457,14 +8464,14 @@ msgid "E1330: Invalid type for object variable: %s"
msgstr "E1330: ÐеиÑправан тип променљиве објекта: %s"
msgid ""
-"E1331: Public must be followed by \"var\" or \"static\" or \"final\" or "
+"E1331: public must be followed by \"var\" or \"static\" or \"final\" or "
"\"const\""
msgstr ""
-"E1331: Ðакон Public мора да Ñледи „var†или „static†или „final†или „constâ€"
+"E1331: Ðакон public мора да Ñледи „var†или „static†или „final†или „constâ€"
#, c-format
-msgid "E1332: Public variable name cannot start with underscore: %s"
-msgstr "E1332: Име Public променљиве не може почети доњом цртом: %s"
+msgid "E1332: public variable name cannot start with underscore: %s"
+msgstr "E1332: Име public променљиве не може почети доњом цртом: %s"
#, c-format
msgid "E1333: Cannot access protected variable \"%s\" in class \"%s\""
@@ -8662,10 +8669,10 @@ msgstr ""
"E1386: Методи објекта „%s†може да Ñе приÑтупи Ñамо кориÑтећи објекат клаÑе "
"„%sâ€"
-msgid "E1387: Public variable not supported in an interface"
-msgstr "E1387: У интерфејÑу Ñе не подржава јавна променљива"
+msgid "E1387: public variable not supported in an interface"
+msgstr "E1387: У интерфејÑу Ñе не подржава public променљива"
-msgid "E1388: Public keyword not supported for a method"
+msgid "E1388: public keyword not supported for a method"
msgstr "E1388: Метода не подржава кључну реч public"
msgid "E1389: Missing name after implements"
@@ -8763,6 +8770,65 @@ msgstr "E1412: Ðије подржана уграђена метода објеÐ
msgid "E1413: Builtin class method not supported"
msgstr "E1413: Ðије подржана уграђена метода клаÑе"
+msgid "E1414: Enum can only be defined in Vim9 script"
+msgstr "E1414: Ðабрајање може да Ñе дефинише Ñамо у Vim9 Ñкрипти"
+
+#, c-format
+msgid "E1415: Enum name must start with an uppercase letter: %s"
+msgstr "E1415: Име набрајања мора да почне великим Ñловом: %s"
+
+msgid "E1416: Enum cannot extend a class or enum"
+msgstr "E1416: Ðабрајање не може да прошири клаÑу или набрајање"
+
+msgid "E1417: Abstract cannot be used in an Enum"
+msgstr "E1417: Abstract не може да Ñе кориÑти у набрајању"
+
+#, c-format
+msgid "E1418: Invalid enum value declaration: %s"
+msgstr "E1418: ÐеиÑправна декларација вредноÑти набрајања: %s"
+
+#, c-format
+msgid "E1419: Not a valid command in an Enum: %s"
+msgstr "E1419: Команда не важи у набрајању: %s"
+
+msgid "E1420: Missing :endenum"
+msgstr "E1420: ÐедоÑтаје :endenum"
+
+#, c-format
+msgid "E1421: Enum \"%s\" cannot be used as a value"
+msgstr "E1421: Ðабрајање „%s†не може да Ñе кориÑти као вредноÑÑ‚"
+
+#, c-format
+msgid "E1422: Enum value \"%s\" not found in enum \"%s\""
+msgstr "E1422: ВредноÑÑ‚ набрајања „%s†није пронађена у набрајању „%sâ€"
+
+#, c-format
+msgid "E1423: Enum value \"%s.%s\" cannot be modified"
+msgstr "E1423: ВредноÑÑ‚ набрајања „%s.%s†не може да Ñе измени"
+
+#, c-format
+msgid "E1424: Using an Enum \"%s\" as a Number"
+msgstr "E1424: Ðабрајање „%s†Ñе кориÑти као Број"
+
+#, c-format
+msgid "E1425: Using an Enum \"%s\" as a String"
+msgstr "E1425: Ðабрајање „%s†Ñе кориÑти као Стринг"
+
+#, c-format
+msgid "E1426: Enum \"%s\" ordinal value cannot be modified"
+msgstr "E1426: Редна вредноÑÑ‚ набрајања „%s†не може да Ñе измени"
+
+#, c-format
+msgid "E1427: Enum \"%s\" name cannot be modified"
+msgstr "E1427: Ðабрајање „%s†не може да Ñе измени"
+
+#, c-format
+msgid "E1428: Duplicate enum value: %s"
+msgstr "E1428: Дуплирана вредноÑÑ‚ набрајања: %s"
+
+msgid "E1429: Class can only be used in a script"
+msgstr "E1429: Class може да Ñе употреби Ñамо у Ñкрипти"
+
#, c-format
msgid "E1500: Cannot mix positional and non-positional arguments: %s"
msgstr "E1500: Ðе могу да Ñе мешају позициони и непозициони аргументи: %s"
@@ -8817,8 +8883,8 @@ msgstr "E1511: Погрешан број карактера за поље „%sâ
msgid "E1512: Wrong character width for field \"%s\""
msgstr "E1512: Погрешна ширина карактера за поље „%sâ€"
-msgid "E1513: Cannot edit buffer. 'winfixbuf' is enabled"
-msgstr "E1513: Ðе може да Ñе уређује бафер. Укључена је опција 'winfixbuf'"
+msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled"
+msgstr "E1513: Ðе може да пређе на други бафер. Укључена је опција 'winfixbuf'"
msgid "--No lines in buffer--"
msgstr "--У баферу нема линија--"
diff --git a/src/popupwin.c b/src/popupwin.c
index bdf4ac7..25bb153 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -654,7 +654,7 @@ popup_show_curline(win_T *wp)
wp->w_topline = wp->w_buffer->b_ml.ml_line_count;
while (wp->w_topline < wp->w_cursor.lnum
&& wp->w_topline < wp->w_buffer->b_ml.ml_line_count
- && plines_m_win(wp, wp->w_topline, wp->w_cursor.lnum, TRUE)
+ && plines_m_win(wp, wp->w_topline, wp->w_cursor.lnum, FALSE)
> wp->w_height)
++wp->w_topline;
}
diff --git a/src/proto/charset.pro b/src/proto/charset.pro
index c915c58..a747319 100644
--- a/src/proto/charset.pro
+++ b/src/proto/charset.pro
@@ -20,6 +20,7 @@ int linetabsize_str(char_u *s);
int linetabsize_col(int startcol, char_u *s);
int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len);
int linetabsize(win_T *wp, linenr_T lnum);
+int linetabsize_no_outer(win_T *wp, linenr_T lnum);
void win_linetabsize_cts(chartabsize_T *cts, colnr_T len);
int vim_isIDc(int c);
int vim_isNormalIDc(int c);
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index 47fd83d..1c2d05d 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -14,9 +14,9 @@ void init_evalarg(evalarg_T *evalarg);
void clear_evalarg(evalarg_T *evalarg, exarg_T *eap);
int skip_expr(char_u **pp, evalarg_T *evalarg);
int skip_expr_concatenate(char_u **arg, char_u **start, char_u **end, evalarg_T *evalarg);
-char_u *typval2string(typval_T *tv, int convert);
-char_u *eval_to_string_eap(char_u *arg, int convert, exarg_T *eap, int use_simple_function);
-char_u *eval_to_string(char_u *arg, int convert, int use_simple_function);
+char_u *typval2string(typval_T *tv, int join_list);
+char_u *eval_to_string_eap(char_u *arg, int join_list, exarg_T *eap, int use_simple_function);
+char_u *eval_to_string(char_u *arg, int join_list, int use_simple_function);
char_u *eval_to_string_safe(char_u *arg, int use_sandbox, int keep_script_version, int use_simple_function);
varnumber_T eval_to_number(char_u *expr, int use_simple_function);
typval_T *eval_expr(char_u *arg, exarg_T *eap);
diff --git a/src/proto/evalvars.pro b/src/proto/evalvars.pro
index ea14fe5..a0e0100 100644
--- a/src/proto/evalvars.pro
+++ b/src/proto/evalvars.pro
@@ -63,6 +63,7 @@ int eval_variable(char_u *name, int len, scid_T sid, typval_T *rettv, dictitem_T
int eval_variable_import(char_u *name, typval_T *rettv);
void check_vars(char_u *name, int len);
dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
+dictitem_T *find_var_autoload_prefix(char_u *name, int sid, hashtab_T **htp, char_u **namep);
dictitem_T *find_var_also_in_script(char_u *name, hashtab_T **htp, int no_autoload);
dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
hashtab_T *get_script_local_ht(void);
diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro
index 7883b3b..c57c94c 100644
--- a/src/proto/mbyte.pro
+++ b/src/proto/mbyte.pro
@@ -85,6 +85,7 @@ int convert_input(char_u *ptr, int len, int maxlen);
int convert_input_safe(char_u *ptr, int len, int maxlen, char_u **restp, int *restlenp);
char_u *string_convert(vimconv_T *vcp, char_u *ptr, int *lenp);
char_u *string_convert_ext(vimconv_T *vcp, char_u *ptr, int *lenp, int *unconvlenp);
+int get_cellwidth(int c);
void f_setcellwidths(typval_T *argvars, typval_T *rettv);
void f_getcellwidths(typval_T *argvars, typval_T *rettv);
void f_charclass(typval_T *argvars, typval_T *rettv);
diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro
index f596ffa..7a5b367 100644
--- a/src/proto/misc2.pro
+++ b/src/proto/misc2.pro
@@ -61,4 +61,8 @@ int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc);
int build_argv_from_string(char_u *cmd, char ***argv, int *argc);
int build_argv_from_list(list_T *l, char ***argv, int *argc);
int get_special_pty_type(void);
+int cmp_keyvalue_value(const void *a, const void *b);
+int cmp_keyvalue_value_n(const void *a, const void *b);
+int cmp_keyvalue_value_i(const void *a, const void *b);
+int cmp_keyvalue_value_ni(const void *a, const void *b);
/* vim: set ft=c : */
diff --git a/src/proto/move.pro b/src/proto/move.pro
index bc9c025..1302c29 100644
--- a/src/proto/move.pro
+++ b/src/proto/move.pro
@@ -9,6 +9,7 @@ void check_cursor_moved(win_T *wp);
void changed_window_setting(void);
void changed_window_setting_win(win_T *wp);
void changed_window_setting_buf(buf_T *buf);
+void changed_window_setting_all(void);
void set_topline(win_T *wp, linenr_T lnum);
void changed_cline_bef_curs(void);
void changed_cline_bef_curs_win(win_T *wp);
@@ -37,6 +38,7 @@ void f_screenpos(typval_T *argvars, typval_T *rettv);
void f_virtcol2col(typval_T *argvars, typval_T *rettv);
void scrolldown(long line_count, int byfold);
void scrollup(long line_count, int byfold);
+void scroll_redraw(int up, long count);
void adjust_skipcol(void);
void check_topfill(win_T *wp, int down);
void scrolldown_clamp(void);
@@ -46,7 +48,6 @@ void set_empty_rows(win_T *wp, int used);
void scroll_cursor_bot(int min_scroll, int set_topbot);
void scroll_cursor_halfway(int atend, int prefer_above);
void cursor_correct(void);
-int onepage(int dir, long count);
-void halfpage(int flag, linenr_T Prenum);
+int pagescroll(int dir, long count, int half);
void do_check_cursorbind(void);
/* vim: set ft=c : */
diff --git a/src/proto/normal.pro b/src/proto/normal.pro
index eff08df..6dcbe41 100644
--- a/src/proto/normal.pro
+++ b/src/proto/normal.pro
@@ -22,8 +22,9 @@ void pop_showcmd(void);
void do_check_scrollbind(int check);
void check_scrollbind(linenr_T topline_diff, long leftcol_diff);
int find_decl(char_u *ptr, int len, int locally, int thisblock, int flags_arg);
+void nv_g_home_m_cmd(cmdarg_T *cap);
+int nv_screengo(oparg_T *oap, int dir, long dist);
void nv_scroll_line(cmdarg_T *cap);
-void scroll_redraw(int up, long count);
void handle_tabmenu(void);
void do_nv_ident(int c1, int c2);
int get_visual_text(cmdarg_T *cap, char_u **pp, int *lenp);
diff --git a/src/proto/scriptfile.pro b/src/proto/scriptfile.pro
index dbcc849..c8ff04a 100644
--- a/src/proto/scriptfile.pro
+++ b/src/proto/scriptfile.pro
@@ -9,6 +9,7 @@ void ex_runtime(exarg_T *eap);
void set_context_in_runtime_cmd(expand_T *xp, char_u *arg);
int find_script_by_name(char_u *name);
int get_new_scriptitem_for_fname(int *error, char_u *fname);
+void check_script_symlink(int sid);
int do_in_path(char_u *path, char *prefix, char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);
int do_in_runtimepath(char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);
int source_runtime(char_u *name, int flags);
diff --git a/src/proto/vim9class.pro b/src/proto/vim9class.pro
index 1ed175e..d3d3b99 100644
--- a/src/proto/vim9class.pro
+++ b/src/proto/vim9class.pro
@@ -3,6 +3,7 @@ int object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *c
int is_valid_builtin_obj_methodname(char_u *funcname);
ufunc_T *class_get_builtin_method(class_T *cl, class_builtin_T builtin_method, int *method_idx);
void ex_class(exarg_T *eap);
+void enum_set_internal_obj_vars(class_T *en, object_T *enval);
type_T *oc_member_type(class_T *cl, int is_object, char_u *name, char_u *name_end, int *member_idx);
type_T *oc_member_type_by_idx(class_T *cl, int is_object, int member_idx);
void ex_enum(exarg_T *eap);
diff --git a/src/proto/vim9instr.pro b/src/proto/vim9instr.pro
index 0fb449d..1b2f79c 100644
--- a/src/proto/vim9instr.pro
+++ b/src/proto/vim9instr.pro
@@ -7,7 +7,7 @@ int generate_CONSTRUCT(cctx_T *cctx, class_T *cl);
int generate_GET_OBJ_MEMBER(cctx_T *cctx, int idx, type_T *type);
int generate_GET_ITF_MEMBER(cctx_T *cctx, class_T *itf, int idx, type_T *type);
int generate_STORE_THIS(cctx_T *cctx, int idx);
-int may_generate_2STRING(int offset, int tolerant, cctx_T *cctx);
+int may_generate_2STRING(int offset, int tostring_flags, cctx_T *cctx);
int generate_add_instr(cctx_T *cctx, vartype_T vartype, type_T *type1, type_T *type2, exprtype_T expr_type);
vartype_T operator_type(type_T *type1, type_T *type2);
int generate_two_op(cctx_T *cctx, char_u *op);
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 9e66db5..26c7040 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -57,6 +57,7 @@ tabpage_T *win_find_tabpage(win_T *win);
win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, int up, long count);
win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, int left, long count);
void win_enter(win_T *wp, int undo_sync);
+void win_fix_current_dir(void);
win_T *buf_jump_open_win(buf_T *buf);
win_T *buf_jump_open_tab(buf_T *buf);
int win_unlisted(win_T *wp);
diff --git a/src/quickfix.c b/src/quickfix.c
index 0bf4cfe..2e5b693 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -4964,12 +4964,12 @@ qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
0L, (char_u *)"qf", OPT_LOCAL);
curbuf->b_p_ma = FALSE;
- keep_filetype = TRUE; // don't detect 'filetype'
+ curbuf->b_keep_filetype = TRUE; // don't detect 'filetype'
apply_autocmds(EVENT_BUFREADPOST, (char_u *)"quickfix", NULL,
FALSE, curbuf);
apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL,
FALSE, curbuf);
- keep_filetype = FALSE;
+ curbuf->b_keep_filetype = FALSE;
--curbuf_lock;
// make sure it will be redrawn
diff --git a/src/regexp_bt.c b/src/regexp_bt.c
index 198946e..5d9450d 100644
--- a/src/regexp_bt.c
+++ b/src/regexp_bt.c
@@ -1641,7 +1641,7 @@ regatom(int *flagp)
n = n * 10 + (c - '0');
c = getchr();
}
- if (c == '\'' && n == 0)
+ if (no_Magic(c) == '\'' && n == 0)
{
// "\%'m", "\%<'m" and "\%>'m": Mark
c = getchr();
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
index ff54348..5e4fadd 100644
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -1733,7 +1733,7 @@ nfa_regatom(void)
EMIT((int)n);
break;
}
- else if (c == '\'' && n == 0)
+ else if (no_Magic(c) == '\'' && n == 0)
{
// \%'m \%<'m \%>'m
EMIT(cmp == '<' ? NFA_MARK_LT :
@@ -5150,7 +5150,7 @@ check_char_class(int class, int c)
default:
// should not be here :P
- siemsg(e_nfa_regexp_invalid_character_class_nr, class);
+ siemsg(_(e_nfa_regexp_invalid_character_class_nr), class);
return FAIL;
}
return FAIL;
diff --git a/src/screen.c b/src/screen.c
index 71ddbca..35d3002 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1981,7 +1981,21 @@ screen_char(unsigned off, int row, int col)
{
char_u buf[MB_MAXBYTES + 1];
- if (utf_ambiguous_width(ScreenLinesUC[off]))
+ if (
+#ifdef FEAT_GUI
+ !gui.in_use &&
+#endif
+ get_cellwidth(ScreenLinesUC[off]) > 1
+ )
+ {
+ // If the width is set to 2 with setcellwidths()
+ // clear the two screen cells. If the character is actually
+ // single width it won't change the second cell.
+ out_str((char_u *)" ");
+ term_windgoto(row, col);
+ screen_cur_col = 9999;
+ }
+ else if (utf_ambiguous_width(ScreenLinesUC[off]))
{
if (*p_ambw == 'd'
#ifdef FEAT_GUI
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 6dc5557..d5ec7cf 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -215,6 +215,9 @@ estack_sfile(estack_arg_T which UNUSED)
if (*class_name != NUL)
{
// For class methods prepend "<class name>." to the function name.
+ ga_concat(&ga, (char_u *)"<SNR>");
+ ga.ga_len += vim_snprintf((char *)ga.ga_data + ga.ga_len, 23,
+ "%d_", entry->es_info.ufunc->uf_script_ctx.sc_sid);
ga_concat(&ga, class_name);
ga_append(&ga, '.');
}
@@ -402,6 +405,43 @@ get_new_scriptitem_for_fname(int *error, char_u *fname)
return sid;
}
+/*
+ * If the script for "sid" is a symlink and "sn_source_sid" is not set
+ * then initialize it. A new script_item is created if needed.
+ */
+ void
+check_script_symlink(int sid)
+{
+ scriptitem_T *si = SCRIPT_ITEM(sid);
+ if (si->sn_syml_checked || si->sn_sourced_sid > 0)
+ return;
+ si->sn_syml_checked = TRUE;
+
+ // If fname is a symbolic link, create an script_item for the real file.
+
+ char_u *real_fname = fix_fname(si->sn_name);
+ if (real_fname != NULL && STRCMP(real_fname, si->sn_name) != 0)
+ {
+ int real_sid = find_script_by_name(real_fname);
+ int error2 = OK;
+ int new_sid = FALSE;
+ if (real_sid < 0)
+ {
+ real_sid = get_new_scriptitem_for_fname(&error2, real_fname);
+ new_sid = TRUE;
+ }
+ if (error2 == OK)
+ {
+ si = SCRIPT_ITEM(sid);
+ si->sn_sourced_sid = real_sid;
+ if (new_sid)
+ SCRIPT_ITEM(real_sid)->sn_import_autoload
+ = si->sn_import_autoload;
+ }
+ }
+ vim_free(real_fname);
+}
+
static void
find_script_callback(char_u *fname, void *cookie)
{
@@ -1233,7 +1273,7 @@ cmd_source(char_u *fname, exarg_T *eap)
emsg(_(e_argument_required));
else
// source ex commands from the current buffer
- do_source_ext(NULL, FALSE, FALSE, NULL, eap, clearvars);
+ do_source_ext(NULL, FALSE, DOSO_NONE, NULL, eap, clearvars);
}
else if (eap != NULL && eap->forceit)
// ":source!": read Normal mode commands
@@ -1384,14 +1424,17 @@ do_source_buffer_init(source_cookie_T *sp, exarg_T *eap)
char_u *line = NULL;
char_u *fname;
- CLEAR_FIELD(*sp);
-
if (curbuf == NULL)
return NULL;
// Use ":source buffer=<num>" as the script name
- vim_snprintf((char *)IObuff, IOSIZE, ":source buffer=%d", curbuf->b_fnum);
- fname = vim_strsave(IObuff);
+ if (curbuf->b_ffname != NULL)
+ fname = vim_strsave(curbuf->b_ffname);
+ else
+ {
+ vim_snprintf((char *)IObuff, IOSIZE, ":source buffer=%d", curbuf->b_fnum);
+ fname = vim_strsave(IObuff);
+ }
if (fname == NULL)
return NULL;
@@ -1408,6 +1451,8 @@ do_source_buffer_init(source_cookie_T *sp, exarg_T *eap)
}
sp->buf_lnum = 0;
sp->source_from_buf = TRUE;
+ // When sourcing a range of lines from a buffer, use buffer line number.
+ sp->sourcing_lnum = eap->line1 - 1;
return fname;
@@ -1596,13 +1641,6 @@ do_source_ext(
cookie.fileformat = EOL_UNKNOWN;
#endif
- if (fname == NULL)
- // When sourcing a range of lines from a buffer, use the buffer line
- // number.
- cookie.sourcing_lnum = eap->line1 - 1;
- else
- cookie.sourcing_lnum = 0;
-
#ifdef FEAT_EVAL
// Check if this script has a breakpoint.
cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
diff --git a/src/session.c b/src/session.c
index e39ce4d..eea57a2 100644
--- a/src/session.c
+++ b/src/session.c
@@ -1392,6 +1392,8 @@ theend:
#ifdef FEAT_SESSION
vim_free(viewFile);
#endif
+
+ apply_autocmds(EVENT_SESSIONWRITEPOST, NULL, NULL, FALSE, curbuf);
}
#if (defined(FEAT_VIMINFO) || defined(FEAT_SESSION)) || defined(PROTO)
diff --git a/src/structs.h b/src/structs.h
index 47a0050..36339c4 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1562,9 +1562,10 @@ struct itf2class_S {
// array with ints follows
};
-#define CLASS_INTERFACE 1
-#define CLASS_EXTENDED 2 // another class extends this one
-#define CLASS_ABSTRACT 4 // abstract class
+#define CLASS_INTERFACE 0x1
+#define CLASS_EXTENDED 0x2 // another class extends this one
+#define CLASS_ABSTRACT 0x4 // abstract class
+#define CLASS_ENUM 0x8 // enum
// "class_T": used for v_class of typval of VAR_CLASS
// Also used for an interface (class_flags has CLASS_INTERFACE).
@@ -1613,6 +1614,9 @@ struct class_S
type_T class_object_type; // same as class_type but VAR_OBJECT
};
+#define IS_INTERFACE(cl) ((cl)->class_flags & CLASS_INTERFACE)
+#define IS_ENUM(cl) ((cl)->class_flags & CLASS_ENUM)
+
// Used for v_object of typval of VAR_OBJECT.
// The member variables follow in an array of typval_T.
struct object_S
@@ -2127,6 +2131,7 @@ typedef struct
int sn_state; // SN_STATE_ values
char_u *sn_save_cpo; // 'cpo' value when :vim9script found
char sn_is_vimrc; // .vimrc file, do not restore 'cpo'
+ char sn_syml_checked;// flag: this has been checked for sym link
// for a Vim9 script under "rtp/autoload/" this is "dir#scriptname#"
char_u *sn_autoload_prefix;
@@ -3129,6 +3134,19 @@ struct file_buffer
int b_marks_read; // Have we read viminfo marks yet?
#endif
+ int b_modified_was_set; // did ":set modified"
+ int b_did_filetype; // FileType event found
+ int b_keep_filetype; // value for did_filetype when starting
+ // to execute autocommands
+
+ // Set by the apply_autocmds_group function if the given event is equal to
+ // EVENT_FILETYPE. Used by the readfile function in order to determine if
+ // EVENT_BUFREADPOST triggered the EVENT_FILETYPE.
+ //
+ // Relying on this value requires one to reset it prior calling
+ // apply_autocmds_group().
+ int b_au_did_filetype;
+
/*
* The following only used in undo.c.
*/
@@ -4380,6 +4398,7 @@ typedef struct
int new_curwin_id; // ID of new curwin
int save_prevwin_id; // ID of saved prevwin
bufref_T new_curbuf; // new curbuf
+ char_u *tp_localdir; // saved value of tp_localdir
char_u *globaldir; // saved value of globaldir
int save_VIsual_active; // saved VIsual_active
int save_State; // saved State
@@ -5043,3 +5062,18 @@ typedef struct {
linenr_T spv_capcol_lnum; // line number for "cap_col"
#endif
} spellvars_T;
+
+// Return the length of a string literal
+#define STRLEN_LITERAL(s) (sizeof(s) - 1)
+
+// Store a key/value pair
+typedef struct
+{
+ int key; // the key
+ char *value; // the value string
+ size_t length; // length of the value string
+} keyvalue_T;
+
+#define KEYVALUE_ENTRY(k, v) \
+ {(k), (v), STRLEN_LITERAL(v)}
+
diff --git a/src/tag.c b/src/tag.c
index 2ac0da2..9117d0f 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -289,17 +289,6 @@ do_tag(
static char_u **matches = NULL;
static int flags;
- if (postponed_split == 0 && !check_can_set_curbuf_forceit(forceit))
- return FALSE;
-
-#ifdef FEAT_EVAL
- if (tfu_in_use)
- {
- emsg(_(e_cannot_modify_tag_stack_within_tagfunc));
- return FALSE;
- }
-#endif
-
#ifdef EXITFREE
if (type == DT_FREE)
{
@@ -313,6 +302,17 @@ do_tag(
}
#endif
+#ifdef FEAT_EVAL
+ if (tfu_in_use)
+ {
+ emsg(_(e_cannot_modify_tag_stack_within_tagfunc));
+ return FALSE;
+ }
+#endif
+
+ if (postponed_split == 0 && !check_can_set_curbuf_forceit(forceit))
+ return FALSE;
+
if (type == DT_HELP)
{
type = DT_TAG;
diff --git a/src/term.c b/src/term.c
index 8aa86ce..7e39b03 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1798,6 +1798,8 @@ get_term_entries(int *height, int *width)
T_DA = (char_u *)"y";
if ((T_UT == NULL || T_UT == empty_option) && tgetflag("ut") > 0)
T_UT = (char_u *)"y";
+ if ((T_XON == NULL || T_XON == empty_option) && tgetflag("xo") > 0)
+ T_XON = (char_u *)"y";
/*
* get key codes
diff --git a/src/termdefs.h b/src/termdefs.h
index f28fd19..2b65abb 100644
--- a/src/termdefs.h
+++ b/src/termdefs.h
@@ -115,10 +115,11 @@ enum SpecialKey
KS_SRI, // restore icon text
KS_FD, // disable focus event tracking
KS_FE, // enable focus event tracking
- KS_CF // set terminal alternate font
+ KS_CF, // set terminal alternate font
+ KS_XON // terminal uses xon/xoff handshaking
};
-#define KS_LAST KS_CF
+#define KS_LAST KS_XON
/*
* the terminal capabilities are stored in this array
@@ -224,6 +225,7 @@ extern char_u *(term_strings[]); // current terminal strings
#define T_SRI (TERM_STR(KS_SRI)) // restore icon text
#define T_FD (TERM_STR(KS_FD)) // disable focus event tracking
#define T_FE (TERM_STR(KS_FE)) // enable focus event tracking
+#define T_XON (TERM_STR(KS_XON)) // terminal uses xon/xoff handshaking
typedef enum {
TMODE_COOK, // terminal mode for external cmds and Ex mode
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index c4403e6..b41f5f4 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -40,6 +40,7 @@ TEST_VIM9 = \
test_vim9_class \
test_vim9_cmd \
test_vim9_disassemble \
+ test_vim9_enum \
test_vim9_expr \
test_vim9_fails \
test_vim9_func \
@@ -53,6 +54,7 @@ TEST_VIM9_RES = \
test_vim9_class.res \
test_vim9_cmd.res \
test_vim9_disassemble.res \
+ test_vim9_enum.res \
test_vim9_expr.res \
test_vim9_fails.res \
test_vim9_func.res \
@@ -329,6 +331,7 @@ NEW_TESTS = \
test_wnext \
test_wordcount \
test_writefile \
+ test_xdg \
test_xxd \
test_alot_latin \
test_alot_utf8 \
@@ -459,6 +462,7 @@ NEW_TESTS_RES = \
test_matchadd_conceal.res \
test_matchadd_conceal_utf8.res \
test_matchfuzzy.res \
+ test_matchparen.res \
test_memory_usage.res \
test_menu.res \
test_messages.res \
@@ -561,6 +565,7 @@ NEW_TESTS_RES = \
test_winfixbuf.res \
test_wordcount.res \
test_writefile.res \
+ test_xdg.res \
test_xxd.res \
test_alot_latin.res \
test_alot_utf8.res \
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
index fd2e56c..4e476f9 100644
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -89,7 +89,7 @@ RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u un
# Delete files that may interfere with running tests. This includes some files
# that may result from working on the tests, not only from running them.
clean:
- -rm -rf *.out *.failed *.res *.rej *.orig XfakeHOME Xdir1 Xfind
+ -rm -rf *.out *.failed *.res *.rej *.orig XfakeHOME Xdir1 Xfind failed
-rm -f opt_test.vim test_result.log $(CLEANUP_FILES)
-rm -rf $(RM_ON_RUN) $(RM_ON_START)
-rm -f valgrind.*
diff --git a/src/testdir/dumps/Test_ambiwidth_hl_dump_1.dump b/src/testdir/dumps/Test_ambiwidth_hl_dump_1.dump
new file mode 100644
index 0000000..383a6f4
--- /dev/null
+++ b/src/testdir/dumps/Test_ambiwidth_hl_dump_1.dump
@@ -0,0 +1,6 @@
+>℃+8&#ffffff0@49
+@10|$+8#4040ff13&| +8#0000000&@38
+|℃+0&&@49
+@10|$+0#4040ff13&| +0#0000000&@38
+|~+0#4040ff13&| @48
+| +0#0000000&@31|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_ambiwidth_hl_dump_2.dump b/src/testdir/dumps/Test_ambiwidth_hl_dump_2.dump
new file mode 100644
index 0000000..81aeb7b
--- /dev/null
+++ b/src/testdir/dumps/Test_ambiwidth_hl_dump_2.dump
@@ -0,0 +1,6 @@
+>℃+8&#ffffff0| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃|
+|℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃|
+|℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |$+8#4040ff13&| +8#0000000&@28
+|℃+0&&| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃|
+|℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| |℃| @1|@+0#4040ff13&@2
+| +0#0000000&@31|1|,|1| @10|T|o|p|
diff --git a/src/testdir/dumps/Test_display_visual_block_scroll.dump b/src/testdir/dumps/Test_display_visual_block_scroll.dump
index afb52fb..36eae0c 100644
--- a/src/testdir/dumps/Test_display_visual_block_scroll.dump
+++ b/src/testdir/dumps/Test_display_visual_block_scroll.dump
@@ -1,7 +1,7 @@
-|{+0&#e0e0e08| | +0&#ffffff0@72
-|}+0&#e0e0e08| | +0&#ffffff0@72
-|{+0&#e0e0e08| | +0&#ffffff0@72
-|f+0&#e0e0e08| | +0&#ffffff0@72
->g| +0&#e0e0e08| +0&#ffffff0@72
+|{+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72
+|}+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72
+|{+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72
+|f+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72
+>g| +0#0000001#a8a8a8255| +0#0000000#ffffff0@72
|}| @73
|-+2&&@1| |V|I|S|U|A|L| |L|I|N|E| |-@1| +0&&@29|7| @8|1@1|,|1| @9|B|o|t|
diff --git a/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_1.dump b/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_1.dump
new file mode 100644
index 0000000..7a0b848
--- /dev/null
+++ b/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_1.dump
@@ -0,0 +1,16 @@
+| +0#af5f00255#ffffff0@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|1| |F+0#0000000&|i|r>s|t| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|2| |A+0#0000001#ffff4012|f|t|e|r| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@5
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3| +0#0000000&@35
+| +0#af5f00255&@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|3| |T+0#0000000&|h|i|r|d| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+@22|1|,|4|-|4|0| @7|A|l@1|
diff --git a/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_2.dump b/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_2.dump
new file mode 100644
index 0000000..d463990
--- /dev/null
+++ b/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_2.dump
@@ -0,0 +1,16 @@
+| +0#af5f00255#ffffff0@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|1| |F+0#0000000&|i|r|s|t| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|2| >A+0#0000001#ffff4012|f|t|e|r| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@5
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3| +0#0000000&@35
+| +0#af5f00255&@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|3| |T+0#0000000&|h|i|r|d| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+@22|2|,|0|-|3|7| @7|A|l@1|
diff --git a/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_3.dump b/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_3.dump
new file mode 100644
index 0000000..85a469d
--- /dev/null
+++ b/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_3.dump
@@ -0,0 +1,16 @@
+| +0#af5f00255#ffffff0@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|1| |F+0#0000000&|i|r|s|t| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|2| |A+0#0000001#ffff4012|f|t|e|r| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@5
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3| +0#0000000&@35
+| +0#af5f00255&@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|3| |T+0#0000000&|h|i>r|d| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+@22|3|,|4|-|4|0| @7|A|l@1|
diff --git a/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_4.dump b/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_4.dump
new file mode 100644
index 0000000..2c03fdf
--- /dev/null
+++ b/src/testdir/dumps/Test_prop_normal_gj_gk_gM_with_outer_virtual_text_4.dump
@@ -0,0 +1,16 @@
+| +0#af5f00255#ffffff0@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|1| |F+0#0000000&|i|r|s|t| |l|i|n|e| |f|i|t|s> |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|2| |A+0#0000001#ffff4012|f|t|e|r| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@5
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3| +0#0000000&@35
+| +0#af5f00255&@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|3| |T+0#0000000&|h|i|r|d| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+@22|1|,|1|6|-|5|2| @6|A|l@1|
diff --git a/src/testdir/dumps/Test_props_with_text_truncated_just_before_after_1.dump b/src/testdir/dumps/Test_props_with_text_truncated_just_before_after_1.dump
new file mode 100644
index 0000000..f46f47e
--- /dev/null
+++ b/src/testdir/dumps/Test_props_with_text_truncated_just_before_after_1.dump
@@ -0,0 +1,8 @@
+|h+0&#ffffff0|e|r|e| |i|s| |t|e|x|t| |l|o|n|g| |e|n|o|u|g|h| |t|o| |f|i|l@1| |t|h|e| |r|o|>+0#4040ff13&
+|s+0#0000000&|e|c|o|n|d| |l|i|n>e| @28
+|~+0#4040ff13&| @38
+|~| @38
+|~| @38
+|~| @38
+|~| @38
+| +0#0000000&@21|2|,|1@1| @9|A|l@1|
diff --git a/src/testdir/dumps/Test_props_with_text_truncated_just_before_after_2.dump b/src/testdir/dumps/Test_props_with_text_truncated_just_before_after_2.dump
new file mode 100644
index 0000000..3434669
--- /dev/null
+++ b/src/testdir/dumps/Test_props_with_text_truncated_just_before_after_2.dump
@@ -0,0 +1,8 @@
+|h+0&#ffffff0|e|r|e| |i|s| |t|e|x|t| |l|o|n|g| |e|n|o|u|g|h| |t|o| |f|i|l@1| |t|h|e| |r|o|>+0#4040ff13&
+|b+0#ffffff16#ff404010|e|l|o|w| |t|e|x|t| +0#0000000#ffffff0@29
+|s|e|c|o|n|d| |l|i|n>e| @28
+|~+0#4040ff13&| @38
+|~| @38
+|~| @38
+|~| @38
+| +0#0000000&@21|2|,|1@1| @9|A|l@1|
diff --git a/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_1.dump b/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_1.dump
new file mode 100644
index 0000000..73f4418
--- /dev/null
+++ b/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_1.dump
@@ -0,0 +1,6 @@
+>➜+0&#ffffff0@49
+@10| @39
+|➜@49
+@10| @39
+|~+0#4040ff13&| @48
+| +0#0000000&@31|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_2.dump b/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_2.dump
new file mode 100644
index 0000000..2b575f6
--- /dev/null
+++ b/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_2.dump
@@ -0,0 +1,6 @@
+>➜+0&#ffffff0| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜|
+|➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜|
+|➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| @30
+|➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜|
+|@+0#4040ff13&@2| @46
+| +0#0000000&@31|1|,|1| @10|T|o|p|
diff --git a/src/testdir/dumps/Test_smooth_long_6.dump b/src/testdir/dumps/Test_smooth_long_6.dump
index ba48c28..507aa46 100644
--- a/src/testdir/dumps/Test_smooth_long_6.dump
+++ b/src/testdir/dumps/Test_smooth_long_6.dump
@@ -3,4 +3,4 @@
|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o
|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e
|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w
-| @21|3|,|9|0| @9|6@1|%|
+|:|s|e|t| |s|c|r|o|l@1|o| @9|3|,|9|0| @9|6@1|%|
diff --git a/src/testdir/dumps/Test_smooth_long_7.dump b/src/testdir/dumps/Test_smooth_long_7.dump
index 222e001..225207f 100644
--- a/src/testdir/dumps/Test_smooth_long_7.dump
+++ b/src/testdir/dumps/Test_smooth_long_7.dump
@@ -3,4 +3,4 @@
|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o
|f| |t|e|x|t| |w|i>t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e
|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w
-| @21|3|,|1|7|0| @8|6@1|%|
+|:|s|e|t| |s|c|r|o|l@1|o| @9|3|,|1|7|0| @8|6@1|%|
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 564d568..6745ecb 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -3702,73 +3702,6 @@ func Test_autocmd_with_block()
augroup END
endfunc
-" Test TextChangedI and TextChanged
-func Test_Changed_ChangedI()
- new
- call test_override("char_avail", 1)
- let [g:autocmd_i, g:autocmd_n] = ['','']
-
- func! TextChangedAutocmdI(char)
- let g:autocmd_{tolower(a:char)} = a:char .. b:changedtick
- endfunc
-
- augroup Test_TextChanged
- au!
- au TextChanged <buffer> :call TextChangedAutocmdI('N')
- au TextChangedI <buffer> :call TextChangedAutocmdI('I')
- augroup END
-
- call feedkeys("ifoo\<esc>", 'tnix')
- " TODO: Test test does not seem to trigger TextChanged autocommand, this
- " requires running Vim in a terminal window.
- " call assert_equal('N3', g:autocmd_n)
- call assert_equal('I3', g:autocmd_i)
-
- call feedkeys("yyp", 'tnix')
- " TODO: Test test does not seem to trigger TextChanged autocommand.
- " call assert_equal('N4', g:autocmd_n)
- call assert_equal('I3', g:autocmd_i)
-
- " TextChangedI should only trigger if change was done in Insert mode
- let g:autocmd_i = ''
- call feedkeys("yypi\<esc>", 'tnix')
- call assert_equal('', g:autocmd_i)
-
- " TextChanged should only trigger if change was done in Normal mode
- let g:autocmd_n = ''
- call feedkeys("ibar\<esc>", 'tnix')
- call assert_equal('', g:autocmd_n)
-
- " If change is a mix of Normal and Insert modes, TextChangedI should trigger
- func s:validate_mixed_textchangedi(keys)
- call feedkeys("ifoo\<esc>", 'tnix')
- let g:autocmd_i = ''
- let g:autocmd_n = ''
- call feedkeys(a:keys, 'tnix')
- call assert_notequal('', g:autocmd_i)
- call assert_equal('', g:autocmd_n)
- endfunc
-
- call s:validate_mixed_textchangedi("o\<esc>")
- call s:validate_mixed_textchangedi("O\<esc>")
- call s:validate_mixed_textchangedi("ciw\<esc>")
- call s:validate_mixed_textchangedi("cc\<esc>")
- call s:validate_mixed_textchangedi("C\<esc>")
- call s:validate_mixed_textchangedi("s\<esc>")
- call s:validate_mixed_textchangedi("S\<esc>")
-
-
- " CleanUp
- call test_override("char_avail", 0)
- au! TextChanged <buffer>
- au! TextChangedI <buffer>
- augroup! Test_TextChanged
- delfu TextChangedAutocmdI
- unlet! g:autocmd_i g:autocmd_n
-
- bw!
-endfunc
-
func Test_closing_autocmd_window()
let lines =<< trim END
edit Xa.txt
@@ -3794,6 +3727,49 @@ func Test_switch_window_in_autocmd_window()
call assert_false(bufexists('Xb.txt'))
endfunc
+" Test that using the autocommand window doesn't change current directory.
+func Test_autocmd_window_cwd()
+ let saveddir = getcwd()
+ call mkdir('Xcwd/a/b/c/d', 'pR')
+
+ new Xa.txt
+ tabnew
+ new Xb.txt
+
+ tabprev
+ cd Xcwd
+ call assert_match('/Xcwd$', getcwd())
+ call assert_match('\[global\] .*/Xcwd$', trim(execute('verbose pwd')))
+
+ autocmd BufEnter Xb.txt lcd ./a/b/c/d
+ doautoall BufEnter
+ au! BufEnter
+ call assert_match('/Xcwd$', getcwd())
+ call assert_match('\[global\] .*/Xcwd$', trim(execute('verbose pwd')))
+
+ tabnext
+ cd ./a
+ tcd ./b
+ lcd ./c
+ call assert_match('/Xcwd/a/b/c$', getcwd())
+ call assert_match('\[window\] .*/Xcwd/a/b/c$', trim(execute('verbose pwd')))
+
+ autocmd BufEnter Xa.txt call assert_match('Xcwd/a/b/c$', getcwd())
+ doautoall BufEnter
+ au! BufEnter
+ call assert_match('/Xcwd/a/b/c$', getcwd())
+ call assert_match('\[window\] .*/Xcwd/a/b/c$', trim(execute('verbose pwd')))
+ bwipe!
+ call assert_match('/Xcwd/a/b$', getcwd())
+ call assert_match('\[tabpage\] .*/Xcwd/a/b$', trim(execute('verbose pwd')))
+ bwipe!
+ call assert_match('/Xcwd/a$', getcwd())
+ call assert_match('\[global\] .*/Xcwd/a$', trim(execute('verbose pwd')))
+ bwipe!
+
+ call chdir(saveddir)
+endfunc
+
func Test_bufwipeout_changes_window()
" This should not crash, but we don't have any expectations about what
" happens, changing window in BufWipeout has unpredictable results.
@@ -4474,4 +4450,245 @@ func Test_autocmd_creates_new_buffer_on_bufleave()
bw c.txt
endfunc
+" Ensure `expected` was just recently written as a Vim session
+func s:assert_session_path(expected)
+ call assert_equal(a:expected, v:this_session)
+endfunc
+
+" Check for `expected` after a session is written to-disk.
+func s:watch_for_session_path(expected)
+ execute 'autocmd SessionWritePost * ++once execute "call s:assert_session_path(\"'
+ \ . a:expected
+ \ . '\")"'
+endfunc
+
+" Ensure v:this_session gets the full session path, if explicitly stated
+func Test_explicit_session_absolute_path()
+ %bwipeout!
+
+ let directory = getcwd()
+
+ let v:this_session = ""
+ let name = "some_file.vim"
+ let expected = fnamemodify(name, ":p")
+ call s:watch_for_session_path(expected)
+ execute "mksession! " .. expected
+
+ call delete(expected)
+endfunc
+
+" Ensure v:this_session gets the full session path, if explicitly stated
+func Test_explicit_session_relative_path()
+ %bwipeout!
+
+ let directory = getcwd()
+
+ let v:this_session = ""
+ let name = "some_file.vim"
+ let expected = fnamemodify(name, ":p")
+ call s:watch_for_session_path(expected)
+ execute "mksession! " .. name
+
+ call delete(expected)
+endfunc
+
+" Ensure v:this_session gets the full session path, if not specified
+func Test_implicit_session()
+ %bwipeout!
+
+ let directory = getcwd()
+
+ let v:this_session = ""
+ let expected = fnamemodify("Session.vim", ":p")
+ call s:watch_for_session_path(expected)
+ mksession!
+
+ call delete(expected)
+endfunc
+
+" Test TextChangedI and TextChanged
+func Test_Changed_ChangedI()
+ " Run this test in a terminal because it requires running the main loop.
+ " Don't use CheckRunVimInTerminal as that will skip the test on Windows.
+ CheckFeature terminal
+ CheckNotGui
+ " Starting a terminal to run Vim is always considered flaky.
+ let g:test_is_flaky = 1
+
+ call writefile(['one', 'two', 'three'], 'XTextChangedI2', 'D')
+ let before =<< trim END
+ set ttimeout ttimeoutlen=10
+ let [g:autocmd_n, g:autocmd_i] = ['','']
+
+ func TextChangedAutocmd(char)
+ let g:autocmd_{tolower(a:char)} = a:char .. b:changedtick
+ call writefile([$'{g:autocmd_n},{g:autocmd_i}'], 'XTextChangedI3')
+ endfunc
+
+ au TextChanged <buffer> :call TextChangedAutocmd('N')
+ au TextChangedI <buffer> :call TextChangedAutocmd('I')
+
+ nnoremap <CR> o<Esc>
+ autocmd SafeState * ++once call writefile([''], 'XTextChangedI3')
+ END
+
+ call writefile(before, 'Xinit', 'D')
+ let buf = term_start(
+ \ GetVimCommandCleanTerm() .. '-n -S Xinit XTextChangedI2',
+ \ {'term_rows': 10})
+ call assert_equal('running', term_getstatus(buf))
+ call WaitForAssert({-> assert_true(filereadable('XTextChangedI3'))})
+ defer delete('XTextChangedI3')
+ call WaitForAssert({-> assert_equal([''], readfile('XTextChangedI3'))})
+
+ " TextChanged should trigger if a mapping enters and leaves Insert mode.
+ call term_sendkeys(buf, "\<CR>")
+ call WaitForAssert({-> assert_equal('N4,', readfile('XTextChangedI3')->join("\n"))})
+
+ call term_sendkeys(buf, "i")
+ call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_equal('N4,', readfile('XTextChangedI3')->join("\n"))})
+ " TextChangedI should trigger if change is done in Insert mode.
+ call term_sendkeys(buf, "f")
+ call WaitForAssert({-> assert_equal('N4,I5', readfile('XTextChangedI3')->join("\n"))})
+ call term_sendkeys(buf, "o")
+ call WaitForAssert({-> assert_equal('N4,I6', readfile('XTextChangedI3')->join("\n"))})
+ call term_sendkeys(buf, "o")
+ call WaitForAssert({-> assert_equal('N4,I7', readfile('XTextChangedI3')->join("\n"))})
+ " TextChanged shouldn't trigger when leaving Insert mode and TextChangedI
+ " has been triggered.
+ call term_sendkeys(buf, "\<Esc>")
+ call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_equal('N4,I7', readfile('XTextChangedI3')->join("\n"))})
+
+ " TextChanged should trigger if change is done in Normal mode.
+ call term_sendkeys(buf, "yyp")
+ call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
+
+ " TextChangedI shouldn't trigger if change isn't done in Insert mode.
+ call term_sendkeys(buf, "i")
+ call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
+ call term_sendkeys(buf, "\<Esc>")
+ call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
+
+ " TextChangedI should trigger if change is a mix of Normal and Insert modes.
+ func! s:validate_mixed_textchangedi(buf, keys)
+ let buf = a:buf
+ call term_sendkeys(buf, "ifoo")
+ call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
+ call term_sendkeys(buf, "\<Esc>")
+ call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
+ call term_sendkeys(buf, ":let [g:autocmd_n, g:autocmd_i] = ['', '']\<CR>")
+ call writefile([], 'XTextChangedI3')
+ call term_sendkeys(buf, a:keys)
+ call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_match('^,I\d\+', readfile('XTextChangedI3')->join("\n"))})
+ call term_sendkeys(buf, "\<Esc>")
+ call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
+ call WaitForAssert({-> assert_match('^,I\d\+', readfile('XTextChangedI3')->join("\n"))})
+ endfunc
+
+ call s:validate_mixed_textchangedi(buf, "o")
+ call s:validate_mixed_textchangedi(buf, "O")
+ call s:validate_mixed_textchangedi(buf, "ciw")
+ call s:validate_mixed_textchangedi(buf, "cc")
+ call s:validate_mixed_textchangedi(buf, "C")
+ call s:validate_mixed_textchangedi(buf, "s")
+ call s:validate_mixed_textchangedi(buf, "S")
+
+ " clean up
+ bwipe!
+endfunc
+
+" Test that filetype detection still works when SwapExists autocommand sets
+" filetype in another buffer.
+func Test_SwapExists_set_other_buf_filetype()
+ let lines =<< trim END
+ set nocompatible directory=.
+ filetype on
+
+ let g:buf = bufnr()
+ new
+
+ func SwapExists()
+ let v:swapchoice = 'o'
+ call setbufvar(g:buf, '&filetype', 'text')
+ endfunc
+
+ func SafeState()
+ edit <script>
+ redir! > XftSwapExists.out
+ set readonly? filetype?
+ redir END
+ qall!
+ endfunc
+
+ autocmd SwapExists * ++nested call SwapExists()
+ autocmd SafeState * ++nested ++once call SafeState()
+ END
+ call writefile(lines, 'XftSwapExists.vim', 'D')
+
+ new XftSwapExists.vim
+ if RunVim('', '', ' -S XftSwapExists.vim')
+ call assert_equal(
+ \ ['', ' readonly', ' filetype=vim'],
+ \ readfile('XftSwapExists.out'))
+ call delete('XftSwapExists.out')
+ endif
+
+ bwipe!
+endfunc
+
+" Test that file is not marked as modified when SwapExists autocommand sets
+" 'modified' in another buffer.
+func Test_SwapExists_set_other_buf_modified()
+ let lines =<< trim END
+ set nocompatible directory=.
+
+ let g:buf = bufnr()
+ new
+
+ func SwapExists()
+ let v:swapchoice = 'o'
+ call setbufvar(g:buf, '&modified', 1)
+ endfunc
+
+ func SafeState()
+ edit <script>
+ redir! > XmodSwapExists.out
+ set readonly? modified?
+ redir END
+ qall!
+ endfunc
+
+ autocmd SwapExists * ++nested call SwapExists()
+ autocmd SafeState * ++nested ++once call SafeState()
+ END
+ call writefile(lines, 'XmodSwapExists.vim', 'D')
+
+ new XmodSwapExists.vim
+ if RunVim('', '', ' -S XmodSwapExists.vim')
+ call assert_equal(
+ \ ['', ' readonly', 'nomodified'],
+ \ readfile('XmodSwapExists.out'))
+ call delete('XmodSwapExists.out')
+ endif
+
+ bwipe!
+endfunc
+
+func Test_BufEnter_botline()
+ set hidden
+ call writefile(range(10), 'Xxx1', 'D')
+ call writefile(range(20), 'Xxx2', 'D')
+ edit Xxx1
+ edit Xxx2
+ au BufEnter Xxx1 call assert_true(line('w$') > 1)
+ edit Xxx1
+ au! BufEnter Xxx1
+ set hidden&vim
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_buffer.vim b/src/testdir/test_buffer.vim
index bc29c21..de088bd 100644
--- a/src/testdir/test_buffer.vim
+++ b/src/testdir/test_buffer.vim
@@ -133,7 +133,7 @@ func Test_bdelete_cmd()
call assert_fails('1,1bdelete 1 2', 'E488:')
call assert_fails('bdelete \)', 'E55:')
- " Deleting a unlisted and unloaded buffer
+ " Deleting an unlisted and unloaded buffer
edit Xbdelfile1
let bnr = bufnr()
set nobuflisted
@@ -252,21 +252,30 @@ func Test_goto_buf_with_confirm()
CheckUnix
CheckNotGui
CheckFeature dialog_con
+ " When dialog_con_gui is defined, Vim is compiled with GUI support
+ " and FEAT_BROWSE will be defined, which causes :confirm :b to
+ " call do_browse(), which will try to use a GUI file browser,
+ " which aborts if a GUI is not available.
+ CheckNotFeature dialog_con_gui
new XgotoConf
enew
call setline(1, 'test')
call assert_fails('b XgotoConf', 'E37:')
call feedkeys('c', 'L')
call assert_fails('confirm b XgotoConf', 'E37:')
- call assert_equal(1, &modified)
- call assert_equal('', @%)
+ call assert_true(&modified)
+ call assert_true(empty(bufname('%')))
call feedkeys('y', 'L')
- call assert_fails('confirm b XgotoConf', ['', 'E37:'])
- call assert_equal(1, &modified)
- call assert_equal('', @%)
+ confirm b XgotoConf
+ call assert_equal('XgotoConf', bufname('%'))
+ call assert_equal(['test'], readfile('Untitled'))
+ e Untitled
+ call setline(2, 'test2')
call feedkeys('n', 'L')
confirm b XgotoConf
- call assert_equal('XgotoConf', @%)
+ call assert_equal('XgotoConf', bufname('%'))
+ call assert_equal(['test'], readfile('Untitled'))
+ call delete('Untitled')
close!
endfunc
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 7c86bcd..ed8f89d 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -3733,9 +3733,9 @@ func Test_custom_completion()
call assert_fails("call getcompletion('', 'custom')", 'E475:')
call assert_fails("call getcompletion('', 'customlist')", 'E475:')
- call assert_equal(getcompletion('', 'custom,CustomComplete1'), ['a', 'b', 'c'])
- call assert_equal(getcompletion('', 'customlist,CustomComplete2'), ['a', 'b'])
- call assert_equal(getcompletion('b', 'customlist,CustomComplete2'), ['b'])
+ call assert_equal(['a', 'b', 'c'], getcompletion('', 'custom,CustomComplete1'))
+ call assert_equal(['a', 'b'], getcompletion('', 'customlist,CustomComplete2'))
+ call assert_equal(['b'], getcompletion('b', 'customlist,CustomComplete2'))
delcom Test1
delcom Test2
@@ -3792,4 +3792,21 @@ func Test_buffer_completion()
call assert_equal("\"b Xbuf_complete/Foobar.c Xbuf_complete/MyFoobar.c AFoobar.h", @:)
endfunc
+" :set t_??
+func Test_term_option()
+ set wildoptions&
+ let _cpo = &cpo
+ set cpo-=C
+ " There may be more, test only until t_xo
+ let expected='"set t_AB t_AF t_AU t_AL t_al t_bc t_BE t_BD t_cd t_ce t_Ce t_CF t_cl t_cm'
+ \ .. ' t_Co t_CS t_Cs t_cs t_CV t_da t_db t_DL t_dl t_ds t_Ds t_EC t_EI t_fs t_fd t_fe'
+ \ .. ' t_GP t_IE t_IS t_ke t_ks t_le t_mb t_md t_me t_mr t_ms t_nd t_op t_RF t_RB t_RC'
+ \ .. ' t_RI t_Ri t_RK t_RS t_RT t_RV t_Sb t_SC t_se t_Sf t_SH t_SI t_Si t_so t_SR t_sr'
+ \ .. ' t_ST t_Te t_te t_TE t_ti t_TI t_Ts t_ts t_u7 t_ue t_us t_Us t_ut t_vb t_ve t_vi'
+ \ .. ' t_VS t_vs t_WP t_WS t_XM t_xn t_xs t_ZH t_ZR t_8f t_8b t_8u t_xo .*'
+ call feedkeys(":set t_\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match(expected, @:)
+ let &cpo = _cpo
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_cmdmods.vim b/src/testdir/test_cmdmods.vim
index 323a78e..66ff6a1 100644
--- a/src/testdir/test_cmdmods.vim
+++ b/src/testdir/test_cmdmods.vim
@@ -8,10 +8,10 @@ def Test_cmdmods_array()
# :hide is both a command and a modifier
cmds->extend(['hide'])
- # Get the entries of cmdmods[] in ex_docmd.c
+ # Get the entries of cmdmod_info_tab[] in ex_docmd.c
edit ../ex_docmd.c
- var top = search('^} cmdmods[') + 1
- var bot = search('^};') - 1
+ var top = search('^static cmdmod_info_T cmdmod_info_tab[') + 1
+ var bot = search('^};.*\/\/ cmdmod_info_tab') - 1
lines = getline(top, bot)
var mods = lines->map((_, v) => substitute(v, '.*"\(\k*\)".*', '\1', ''))
diff --git a/src/testdir/test_codestyle.vim b/src/testdir/test_codestyle.vim
index 359410d..a455264 100644
--- a/src/testdir/test_codestyle.vim
+++ b/src/testdir/test_codestyle.vim
@@ -7,13 +7,17 @@ def s:ReportError(fname: string, lnum: number, msg: string)
enddef
def s:PerformCheck(fname: string, pattern: string, msg: string, skip: string)
+ var prev_lnum = 1
var lnum = 1
while (lnum > 0)
cursor(lnum, 1)
lnum = search(pattern, 'W', 0, 0, skip)
- ReportError(fname, lnum, msg)
+ if (prev_lnum == lnum)
+ break
+ endif
+ prev_lnum = lnum
if (lnum > 0)
- lnum += 1
+ ReportError(fname, lnum, msg)
endif
endwhile
enddef
diff --git a/src/testdir/test_compiler.vim b/src/testdir/test_compiler.vim
index 4b710df..b7315e1 100644
--- a/src/testdir/test_compiler.vim
+++ b/src/testdir/test_compiler.vim
@@ -71,10 +71,10 @@ func Test_compiler_completion()
call assert_match('^"compiler ' .. clist .. '$', @:)
call feedkeys(":compiler p\<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_match('"compiler pbx perl\( p[a-z]\+\)\+ pylint pyunit', @:)
+ call assert_match('"compiler pandoc pbx perl\( p[a-z_]\+\)\+ pylint pyunit', @:)
call feedkeys(":compiler! p\<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_match('"compiler! pbx perl\( p[a-z]\+\)\+ pylint pyunit', @:)
+ call assert_match('"compiler! pandoc pbx perl\( p[a-z_]\+\)\+ pylint pyunit', @:)
endfunc
func Test_compiler_error()
diff --git a/src/testdir/test_conceal.vim b/src/testdir/test_conceal.vim
index 355817d..2ce7384 100644
--- a/src/testdir/test_conceal.vim
+++ b/src/testdir/test_conceal.vim
@@ -199,6 +199,7 @@ endfunc
" Same as Test_conceal_wrapped_cursorline_wincolor(), but with 'rightleft'.
func Test_conceal_wrapped_cursorline_wincolor_rightleft()
+ CheckFeature rightleft
CheckScreendump
let code =<< trim [CODE]
diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim
index 7602bd3..098d5d0 100644
--- a/src/testdir/test_diffmode.vim
+++ b/src/testdir/test_diffmode.vim
@@ -1647,36 +1647,39 @@ endfunc
func Test_diff_scroll_many_filler()
20new
vnew
- call setline(1, ['^^^', '^^^', '$$$', '$$$'])
+ call setline(1, range(1, 40))
diffthis
setlocal scrolloff=0
wincmd p
- call setline(1, ['^^^', '^^^'] + repeat(['###'], 41) + ['$$$', '$$$'])
+ call setline(1, range(1, 20)->reverse() + ['###']->repeat(41) + range(21, 40)->reverse())
diffthis
setlocal scrolloff=0
wincmd p
redraw
" Note: need a redraw after each scroll, otherwise the test always passes.
- normal! G
- redraw
- call assert_equal(3, winsaveview().topline)
- call assert_equal(18, winsaveview().topfill)
- exe "normal! \<C-B>"
- redraw
- call assert_equal(3, winsaveview().topline)
- call assert_equal(19, winsaveview().topfill)
- exe "normal! \<C-B>"
- redraw
- call assert_equal(2, winsaveview().topline)
- call assert_equal(0, winsaveview().topfill)
- exe "normal! \<C-B>"
- redraw
- call assert_equal(1, winsaveview().topline)
- call assert_equal(0, winsaveview().topfill)
+ for _ in range(2)
+ normal! G
+ redraw
+ call assert_equal(40, winsaveview().topline)
+ call assert_equal(19, winsaveview().topfill)
+ exe "normal! \<C-B>"
+ redraw
+ call assert_equal(22, winsaveview().topline)
+ call assert_equal(0, winsaveview().topfill)
+ exe "normal! \<C-B>"
+ redraw
+ call assert_equal(4, winsaveview().topline)
+ call assert_equal(0, winsaveview().topfill)
+ exe "normal! \<C-B>"
+ redraw
+ call assert_equal(1, winsaveview().topline)
+ call assert_equal(0, winsaveview().topfill)
+ set smoothscroll
+ endfor
- bwipe!
- bwipe!
+ set smoothscroll&
+ %bwipe!
endfunc
" This was trying to update diffs for a buffer being closed
@@ -2020,4 +2023,23 @@ func Test_diff_toggle_wrap_skipcol_leftcol()
bwipe!
endfunc
+" Ctrl-D reveals filler lines below the last line in the buffer.
+func Test_diff_eob_halfpage()
+ new
+ call setline(1, ['']->repeat(10) + ['a'])
+ diffthis
+ new
+ call setline(1, ['']->repeat(3) + ['a', 'b'])
+ diffthis
+ resize 5
+ wincmd j
+ resize 5
+ norm G
+ call assert_equal(7, line('w0'))
+ exe "norm! \<C-D>"
+ call assert_equal(8, line('w0'))
+
+ %bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_digraph.vim b/src/testdir/test_digraph.vim
index 4aed403..3312faf 100644
--- a/src/testdir/test_digraph.vim
+++ b/src/testdir/test_digraph.vim
@@ -595,13 +595,13 @@ func Test_digraph_getlist_function()
call digraph_setlist([['aa', 'ã'], ['bb', 'ã']])
for pair in digraph_getlist(1)
- call assert_equal(digraph_get(pair[0]), pair[1])
+ call assert_equal(pair[1], digraph_get(pair[0]))
endfor
" We don't know how many digraphs are registered before, so check the number
" of digraphs returned.
call assert_equal(digraph_getlist()->len(), digraph_getlist(0)->len())
- call assert_notequal((digraph_getlist()->len()), digraph_getlist(1)->len())
+ call assert_notequal(digraph_getlist()->len(), digraph_getlist(1)->len())
call assert_fails('call digraph_getlist(0z12)', 'E974: Using a Blob as a Number')
endfunc
diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
index 36e0525..789e44c 100644
--- a/src/testdir/test_edit.vim
+++ b/src/testdir/test_edit.vim
@@ -6,8 +6,6 @@ endif
source check.vim
source screendump.vim
-
-" Needed for testing basic rightleft: Test_edit_rightleft
source view_util.vim
" Needs to come first until the bug in getchar() is
@@ -1302,9 +1300,9 @@ func Test_edit_PAGEUP_PAGEDOWN()
call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 13, 1, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix')
- call assert_equal([0, 5, 1, 0], getpos('.'))
+ call assert_equal([0, 10, 1, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
" <S-Up> is the same as <PageUp>
" <S-Down> is the same as <PageDown>
call cursor(1, 1)
@@ -1325,9 +1323,9 @@ func Test_edit_PAGEUP_PAGEDOWN()
call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 13, 1, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix')
- call assert_equal([0, 5, 1, 0], getpos('.'))
+ call assert_equal([0, 10, 1, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
set nostartofline
call cursor(30, 11)
norm! zt
@@ -1338,9 +1336,9 @@ func Test_edit_PAGEUP_PAGEDOWN()
call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 13, 11, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
call cursor(1, 1)
call feedkeys("A\<PageDown>\<esc>", 'tnix')
call assert_equal([0, 9, 11, 0], getpos('.'))
@@ -1363,9 +1361,9 @@ func Test_edit_PAGEUP_PAGEDOWN()
call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 13, 11, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix')
- call assert_equal([0, 5, 11, 0], getpos('.'))
+ call assert_equal([0, 10, 11, 0], getpos('.'))
call cursor(1, 1)
call feedkeys("A\<S-Down>\<esc>", 'tnix')
call assert_equal([0, 9, 11, 0], getpos('.'))
@@ -1964,8 +1962,8 @@ func Test_edit_ctrl_r_failed()
let buf = RunVimInTerminal('', #{rows: 6, cols: 60})
- " trying to insert a dictionary produces an error
- call term_sendkeys(buf, "i\<C-R>={}\<CR>")
+ " trying to insert a blob produces an error
+ call term_sendkeys(buf, "i\<C-R>=0z\<CR>")
" ending Insert mode should put the cursor back on the ':'
call term_sendkeys(buf, ":\<Esc>")
@@ -2046,7 +2044,10 @@ func Test_edit_revins()
call setline(1, 'one two three')
exe "normal! wi\nfour"
call assert_equal(['one two three', 'ruof'], getline(1, '$'))
- set revins&
+ set backspace=indent,eol,start
+ exe "normal! ggA\<BS>:"
+ call assert_equal(['one two three:ruof'], getline(1, '$'))
+ set revins& backspace&
bw!
endfunc
@@ -2158,4 +2159,133 @@ func Test_edit_Ctrl_RSB()
bwipe!
endfunc
+func s:check_backspace(expected)
+ let g:actual = []
+ inoremap <buffer> <F2> <Cmd>let g:actual += [getline('.')]<CR>
+ set backspace=indent,eol,start
+
+ exe "normal i" .. repeat("\<BS>\<F2>", len(a:expected))
+ call assert_equal(a:expected, g:actual)
+
+ set backspace&
+ iunmap <buffer> <F2>
+ unlet g:actual
+endfunc
+
+" Test that backspace works with 'smarttab' and mixed Tabs and spaces.
+func Test_edit_backspace_smarttab_mixed()
+ set smarttab
+ call NewWindow(1, 30)
+ setlocal tabstop=4 shiftwidth=4
+
+ call setline(1, "\t \t \t a")
+ normal! $
+ call s:check_backspace([
+ \ "\t \t \ta",
+ \ "\t \t a",
+ \ "\t \t a",
+ \ "\t \ta",
+ \ "\t a",
+ \ "\ta",
+ \ "a",
+ \ ])
+
+ call CloseWindow()
+ set smarttab&
+endfunc
+
+" Test that backspace works with 'smarttab' and 'varsofttabstop'.
+func Test_edit_backspace_smarttab_varsofttabstop()
+ CheckFeature vartabs
+
+ set smarttab
+ call NewWindow(1, 30)
+ setlocal tabstop=8 varsofttabstop=6,2,5,3
+
+ call setline(1, "a\t \t a")
+ normal! $
+ call s:check_backspace([
+ \ "a\t \ta",
+ \ "a\t a",
+ \ "a\ta",
+ \ "a a",
+ \ "aa",
+ \ "a",
+ \ ])
+
+ call CloseWindow()
+ set smarttab&
+endfunc
+
+" Test that backspace works with 'smarttab' when a Tab is shown as "^I".
+func Test_edit_backspace_smarttab_list()
+ set smarttab
+ call NewWindow(1, 30)
+ setlocal tabstop=4 shiftwidth=4 list listchars=
+
+ call setline(1, "\t \t \t a")
+ normal! $
+ call s:check_backspace([
+ \ "\t \t a",
+ \ "\t \t a",
+ \ "\t \ta",
+ \ "\t a",
+ \ "a",
+ \ ])
+
+ call CloseWindow()
+ set smarttab&
+endfunc
+
+" Test that backspace works with 'smarttab' and 'breakindent'.
+func Test_edit_backspace_smarttab_breakindent()
+ CheckFeature linebreak
+
+ set smarttab
+ call NewWindow(3, 17)
+ setlocal tabstop=4 shiftwidth=4 breakindent breakindentopt=min:5
+
+ call setline(1, "\t \t \t a")
+ normal! $
+ call s:check_backspace([
+ \ "\t \t \ta",
+ \ "\t \t a",
+ \ "\t \t a",
+ \ "\t \ta",
+ \ "\t a",
+ \ "\ta",
+ \ "a",
+ \ ])
+
+ call CloseWindow()
+ set smarttab&
+endfunc
+
+" Test that backspace works with 'smarttab' and virtual text.
+func Test_edit_backspace_smarttab_virtual_text()
+ CheckFeature textprop
+
+ set smarttab
+ call NewWindow(1, 50)
+ setlocal tabstop=4 shiftwidth=4
+
+ call setline(1, "\t \t \t a")
+ call prop_type_add('theprop', {})
+ call prop_add(1, 3, {'type': 'theprop', 'text': 'text'})
+ normal! $
+ call s:check_backspace([
+ \ "\t \t \ta",
+ \ "\t \t a",
+ \ "\t \t a",
+ \ "\t \ta",
+ \ "\t a",
+ \ "\ta",
+ \ "a",
+ \ ])
+
+ call CloseWindow()
+ call prop_type_delete('theprop')
+ set smarttab&
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_expr.vim b/src/testdir/test_expr.vim
index c1869c1..6acfe00 100644
--- a/src/testdir/test_expr.vim
+++ b/src/testdir/test_expr.vim
@@ -950,6 +950,22 @@ func Test_string_interp()
endif
call assert_equal(0, tmp)
+ #" Dict interpolation
+ VAR d = {'a': 10, 'b': [1, 2]}
+ call assert_equal("{'a': 10, 'b': [1, 2]}", $'{d}')
+ VAR emptydict = {}
+ call assert_equal("a{}b", $'a{emptydict}b')
+ VAR nulldict = test_null_dict()
+ call assert_equal("a{}b", $'a{nulldict}b')
+
+ #" List interpolation
+ VAR l = ['a', 'b', 'c']
+ call assert_equal("['a', 'b', 'c']", $'{l}')
+ VAR emptylist = []
+ call assert_equal("a[]b", $'a{emptylist}b')
+ VAR nulllist = test_null_list()
+ call assert_equal("a[]b", $'a{nulllist}b')
+
#" Stray closing brace.
call assert_fails('echo $"moo}"', 'E1278:')
#" Undefined variable in expansion.
diff --git a/src/testdir/test_filechanged.vim b/src/testdir/test_filechanged.vim
index c3a5664..12ac4cc 100644
--- a/src/testdir/test_filechanged.vim
+++ b/src/testdir/test_filechanged.vim
@@ -11,8 +11,12 @@ func Test_FileChangedShell_reload()
new Xchanged_r
call setline(1, 'reload this')
write
- " Need to wait until the timestamp would change by at least a second.
- sleep 2
+ " Need to wait until the timestamp would change.
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
silent !echo 'extra line' >>Xchanged_r
checktime
call assert_equal('changed', g:reason)
@@ -50,7 +54,11 @@ func Test_FileChangedShell_reload()
call assert_equal('new line', getline(1))
" Only time changed
- sleep 2
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
silent !touch Xchanged_r
let g:reason = ''
checktime
@@ -65,7 +73,11 @@ func Test_FileChangedShell_reload()
call setline(2, 'before write')
write
call setline(2, 'after write')
- sleep 2
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
silent !echo 'different line' >>Xchanged_r
let g:reason = ''
checktime
@@ -192,8 +204,12 @@ func Test_file_changed_dialog()
new Xchanged_d
call setline(1, 'reload this')
write
- " Need to wait until the timestamp would change by at least a second.
- sleep 2
+ " Need to wait until the timestamp would change.
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
silent !echo 'extra line' >>Xchanged_d
call feedkeys('L', 'L')
checktime
@@ -228,7 +244,11 @@ func Test_file_changed_dialog()
call assert_equal('new line', getline(1))
" Only time changed, no prompt
- sleep 2
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
silent !touch Xchanged_d
let v:warningmsg = ''
checktime Xchanged_d
diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim
index d77e5e0..f8fe9ec 100644
--- a/src/testdir/test_filetype.vim
+++ b/src/testdir/test_filetype.vim
@@ -126,6 +126,7 @@ def s:GetFilenameChecks(): dict<list<string>>
blade: ['file.blade.php'],
blank: ['file.bl'],
blueprint: ['file.blp'],
+ bp: ['Android.bp'],
bsdl: ['file.bsd', 'file.bsdl'],
bst: ['file.bst'],
bzl: ['file.bazel', 'file.bzl', 'WORKSPACE', 'WORKSPACE.bzlmod'],
@@ -144,6 +145,7 @@ def s:GetFilenameChecks(): dict<list<string>>
cf: ['file.cfm', 'file.cfi', 'file.cfc'],
cfengine: ['cfengine.conf'],
cfg: ['file.hgrc', 'filehgrc', 'hgrc', 'some-hgrc'],
+ cgdbrc: ['cgdbrc'],
ch: ['file.chf'],
chaiscript: ['file.chai'],
chaskell: ['file.chs'],
@@ -153,16 +155,17 @@ def s:GetFilenameChecks(): dict<list<string>>
chuck: ['file.ck'],
cl: ['file.eni'],
clean: ['file.dcl', 'file.icl'],
- clojure: ['file.clj', 'file.cljs', 'file.cljx', 'file.cljc'],
+ clojure: ['file.clj', 'file.cljs', 'file.cljx', 'file.cljc', 'init.trans', 'any/etc/translate-shell', '.trans'],
cmake: ['CMakeLists.txt', 'file.cmake', 'file.cmake.in'],
+ cmakecache: ['CMakeCache.txt'],
cmod: ['file.cmod'],
cmusrc: ['any/.cmus/autosave', 'any/.cmus/rc', 'any/.cmus/command-history', 'any/.cmus/file.theme', 'any/cmus/rc', 'any/cmus/file.theme', '/.cmus/autosave', '/.cmus/command-history', '/.cmus/file.theme', '/.cmus/rc', '/cmus/file.theme', '/cmus/rc'],
cobol: ['file.cbl', 'file.cob', 'file.lib'],
coco: ['file.atg'],
conaryrecipe: ['file.recipe'],
- conf: ['auto.master', 'file.conf'],
+ conf: ['auto.master', 'file.conf', 'texdoc.cnf', '.x11vncrc', '.chktexrc', '.ripgreprc', 'ripgreprc', 'file.ctags', '.mbsyncrc'],
config: ['configure.in', 'configure.ac', '/etc/hostname.file', 'any/etc/hostname.file'],
- confini: ['/etc/pacman.conf', 'any/etc/pacman.conf', 'mpv.conf', 'any/.aws/config', 'any/.aws/credentials', 'file.nmconnection'],
+ confini: ['pacman.conf', 'paru.conf', 'mpv.conf', 'any/.aws/config', 'any/.aws/credentials', 'file.nmconnection'],
context: ['tex/context/any/file.tex', 'file.mkii', 'file.mkiv', 'file.mkvi', 'file.mkxl', 'file.mklx'],
cook: ['file.cook'],
corn: ['file.corn'],
@@ -210,16 +213,24 @@ def s:GetFilenameChecks(): dict<list<string>>
dnsmasq: ['/etc/dnsmasq.conf', '/etc/dnsmasq.d/file', 'any/etc/dnsmasq.conf', 'any/etc/dnsmasq.d/file'],
dockerfile: ['Containerfile', 'Dockerfile', 'dockerfile', 'file.Dockerfile', 'file.dockerfile', 'Dockerfile.debian', 'Containerfile.something'],
dosbatch: ['file.bat'],
- dosini: ['/etc/yum.conf', 'file.ini', 'npmrc', '.npmrc', 'php.ini', 'php.ini-5', 'php.ini-file', '/etc/yum.repos.d/file', 'any/etc/yum.conf', 'any/etc/yum.repos.d/file', 'file.wrap', 'file.vbp', 'ja2.ini', 'JA2.INI'],
+ dosini: ['/etc/yum.conf', '/etc/nfs.conf', '/etc/nfsmount.conf', 'file.ini',
+ 'npmrc', '.npmrc', 'php.ini', 'php.ini-5', 'php.ini-file',
+ '/etc/yum.repos.d/file', 'any/etc/yum.conf', 'any/etc/yum.repos.d/file', 'file.wrap',
+ 'file.vbp', 'ja2.ini', 'JA2.INI', 'mimeapps.list', 'pip.conf', 'setup.cfg', 'pudb.cfg',
+ '.coveragerc', '.pypirc', '.gitlint', '.oelint.cfg', 'pylintrc', '.pylintrc',
+ '/home/user/.config/bpython/config', '/home/user/.config/mypy/config', '.wakatime.cfg', '.replyrc',
+ 'psprint.conf', 'sofficerc', 'any/.config/lxqt/globalkeyshortcuts.conf', 'any/.config/screengrab/screengrab.conf',
+ 'any/.local/share/flatpak/repo/config', '.notmuch-config'],
dot: ['file.dot', 'file.gv'],
dracula: ['file.drac', 'file.drc', 'filelvs', 'filelpe', 'drac.file', 'lpe', 'lvs', 'some-lpe', 'some-lvs'],
dtd: ['file.dtd'],
dtrace: ['/usr/lib/dtrace/io.d'],
- dts: ['file.dts', 'file.dtsi', 'file.dtso', 'file.its'],
+ dts: ['file.dts', 'file.dtsi', 'file.dtso', 'file.its', 'file.keymap'],
dune: ['jbuild', 'dune', 'dune-project', 'dune-workspace'],
dylan: ['file.dylan'],
dylanintr: ['file.intr'],
dylanlid: ['file.lid'],
+ earthfile: ['Earthfile'],
ecd: ['file.ecd'],
edif: ['file.edf', 'file.edif', 'file.edo'],
editorconfig: ['.editorconfig'],
@@ -283,7 +294,7 @@ def s:GetFilenameChecks(): dict<list<string>>
glsl: ['file.glsl'],
gn: ['file.gn', 'file.gni'],
gnash: ['gnashrc', '.gnashrc', 'gnashpluginrc', '.gnashpluginrc'],
- gnuplot: ['file.gpi', '.gnuplot', 'file.gnuplot'],
+ gnuplot: ['file.gpi', '.gnuplot', 'file.gnuplot', '.gnuplot_history'],
go: ['file.go'],
gomod: ['go.mod'],
gosum: ['go.sum', 'go.work.sum'],
@@ -312,7 +323,7 @@ def s:GetFilenameChecks(): dict<list<string>>
hcl: ['file.hcl'],
heex: ['file.heex'],
hercules: ['file.vc', 'file.ev', 'file.sum', 'file.errsum'],
- hex: ['file.hex', 'file.h32'],
+ hex: ['file.hex', 'file.ihex', 'file.ihe', 'file.ihx', 'file.int', 'file.mcs', 'file.h32', 'file.h80', 'file.h86', 'file.a43', 'file.a90'],
hgcommit: ['hg-editor-file.txt'],
hjson: ['file.hjson'],
hlsplaylist: ['file.m3u', 'file.m3u8'],
@@ -342,7 +353,7 @@ def s:GetFilenameChecks(): dict<list<string>>
janet: ['file.janet'],
java: ['file.java', 'file.jav'],
javacc: ['file.jj', 'file.jjt'],
- javascript: ['file.js', 'file.jsm', 'file.javascript', 'file.es', 'file.mjs', 'file.cjs'],
+ javascript: ['file.js', 'file.jsm', 'file.javascript', 'file.es', 'file.mjs', 'file.cjs', '.node_repl_history'],
'javascript.glimmer': ['file.gjs'],
javascriptreact: ['file.jsx'],
jess: ['file.clp'],
@@ -350,9 +361,9 @@ def s:GetFilenameChecks(): dict<list<string>>
jq: ['file.jq'],
jovial: ['file.jov', 'file.j73', 'file.jovial'],
jproperties: ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file', 'org.eclipse.xyz.prefs'],
- json: ['file.json', 'file.jsonp', 'file.json-patch', 'file.geojson', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', '.prettierrc', '.firebaserc', '.stylelintrc', 'file.slnf'],
+ json: ['file.json', 'file.jsonp', 'file.json-patch', 'file.geojson', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', 'file.jupyterlab-settings', '.prettierrc', '.firebaserc', '.stylelintrc', 'file.slnf', 'file.sublime-project', 'file.sublime-settings', 'file.sublime-workspace', 'file.bd', 'file.bda', 'file.xci', 'flake.lock'],
json5: ['file.json5'],
- jsonc: ['file.jsonc', '.babelrc', '.eslintrc', '.jsfmtrc', '.jshintrc', '.hintrc', '.swrc', 'jsconfig.json', 'tsconfig.json', 'tsconfig.test.json', 'tsconfig-test.json', '.luaurc'],
+ jsonc: ['file.jsonc', '.babelrc', '.eslintrc', '.jsfmtrc', '.jshintrc', '.jscsrc', '.vsconfig', '.hintrc', '.swrc', 'jsconfig.json', 'tsconfig.json', 'tsconfig.test.json', 'tsconfig-test.json', '.luaurc'],
jsonl: ['file.jsonl'],
jsonnet: ['file.jsonnet', 'file.libsonnet'],
jsp: ['file.jsp'],
@@ -368,7 +379,7 @@ def s:GetFilenameChecks(): dict<list<string>>
kwt: ['file.k'],
lace: ['file.ace', 'file.ACE'],
latte: ['file.latte', 'file.lte'],
- ld: ['file.ld'],
+ ld: ['file.ld', 'any/usr/lib/aarch64-xilinx-linux/ldscripts/aarch64elf32b.x'],
ldif: ['file.ldif'],
lean: ['file.lean'],
ledger: ['file.ldg', 'file.ledger', 'file.journal'],
@@ -383,7 +394,7 @@ def s:GetFilenameChecks(): dict<list<string>>
limits: ['/etc/limits', '/etc/anylimits.conf', '/etc/anylimits.d/file.conf', '/etc/limits.conf', '/etc/limits.d/file.conf', '/etc/some-limits.conf', '/etc/some-limits.d/file.conf', 'any/etc/limits', 'any/etc/limits.conf', 'any/etc/limits.d/file.conf', 'any/etc/some-limits.conf', 'any/etc/some-limits.d/file.conf'],
liquidsoap: ['file.liq'],
liquid: ['file.liquid'],
- lisp: ['file.lsp', 'file.lisp', 'file.asd', 'file.el', 'file.cl', '.emacs', '.sawfishrc', 'sbclrc', '.sbclrc'],
+ lisp: ['file.lsp', 'file.lisp', 'file.asd', 'file.el', 'file.cl', '.emacs', '.sawfishrc', 'sbclrc', '.sbclrc', 'file.stsg', 'any/local/share/supertux2/config'],
lite: ['file.lite', 'file.lt'],
litestep: ['/LiteStep/any/file.rc', 'any/LiteStep/any/file.rc'],
logcheck: ['/etc/logcheck/file.d-some/file', '/etc/logcheck/file.d/file', 'any/etc/logcheck/file.d-some/file', 'any/etc/logcheck/file.d/file'],
@@ -396,13 +407,13 @@ def s:GetFilenameChecks(): dict<list<string>>
lpc: ['file.lpc', 'file.ulpc'],
lsl: ['file.lsl'],
lss: ['file.lss'],
- lua: ['file.lua', 'file.rockspec', 'file.nse', '.luacheckrc', '.busted'],
+ lua: ['file.lua', 'file.tlu', 'file.rockspec', 'file.nse', '.lua_history', '.luacheckrc', '.busted', 'rock_manifest', 'config.ld'],
luau: ['file.luau'],
lynx: ['lynx.cfg'],
lyrics: ['file.lrc'],
m3build: ['m3makefile', 'm3overrides'],
m3quake: ['file.quake', 'cm3.cfg'],
- m4: ['file.at'],
+ m4: ['file.at', '.m4_history'],
mail: ['snd.123', '.letter', '.letter.123', '.followup', '.article', '.article.123', 'pico.123', 'mutt-xx-xxx', 'muttng-xx-xxx', 'ae123.txt', 'file.eml', 'reportbug-file'],
mailaliases: ['/etc/mail/aliases', '/etc/aliases', 'any/etc/aliases', 'any/etc/mail/aliases'],
mailcap: ['.mailcap', 'mailcap'],
@@ -466,6 +477,7 @@ def s:GetFilenameChecks(): dict<list<string>>
msidl: ['file.odl', 'file.mof'],
msql: ['file.msql'],
mojo: ['file.mojo', 'file.🔥'],
+ msmtp: ['.msmtprc'],
mupad: ['file.mu'],
mush: ['file.mush'],
mustache: ['file.mustache'],
@@ -481,7 +493,7 @@ def s:GetFilenameChecks(): dict<list<string>>
'any/.muttng/muttrc', 'any/.muttng/muttrc-file',
'any/etc/Muttrc.d/file', 'muttngrc', 'muttngrc-file', 'muttrc',
'muttrc-file'],
- mysql: ['file.mysql'],
+ mysql: ['file.mysql', '.mysql_history'],
n1ql: ['file.n1ql', 'file.nql'],
named: ['namedfile.conf', 'rndcfile.conf', 'named-file.conf', 'named.conf', 'rndc-file.conf', 'rndc-file.key', 'rndc.conf', 'rndc.key'],
nanorc: ['/etc/nanorc', 'file.nanorc', 'any/etc/nanorc'],
@@ -503,9 +515,10 @@ def s:GetFilenameChecks(): dict<list<string>>
obse: ['file.obl', 'file.obse', 'file.oblivion', 'file.obscript'],
ocaml: ['file.ml', 'file.mli', 'file.mll', 'file.mly', '.ocamlinit', 'file.mlt', 'file.mlp', 'file.mlip', 'file.mli.cppo', 'file.ml.cppo'],
occam: ['file.occ'],
- octave: ['octaverc', '.octaverc', 'octave.conf'],
+ octave: ['octaverc', '.octaverc', 'octave.conf', 'any/.local/share/octave/history'],
odin: ['file.odin'],
omnimark: ['file.xom', 'file.xin'],
+ ondir: ['.ondirrc'],
opam: ['opam', 'file.opam', 'file.opam.template'],
openroad: ['file.or'],
openscad: ['file.scad'],
@@ -516,10 +529,11 @@ def s:GetFilenameChecks(): dict<list<string>>
pacmanlog: ['pacman.log'],
pamconf: ['/etc/pam.conf', '/etc/pam.d/file', 'any/etc/pam.conf', 'any/etc/pam.d/file'],
pamenv: ['/etc/security/pam_env.conf', '/home/user/.pam_environment', '.pam_environment', 'pam_env.conf'],
+ pandoc: ['file.pandoc', 'file.pdk', 'file.pd', 'file.pdc'],
papp: ['file.papp', 'file.pxml', 'file.pxsl'],
pascal: ['file.pas', 'file.dpr', 'file.lpr'],
passwd: ['any/etc/passwd', 'any/etc/passwd-', 'any/etc/passwd.edit', 'any/etc/shadow', 'any/etc/shadow-', 'any/etc/shadow.edit', 'any/var/backups/passwd.bak', 'any/var/backups/shadow.bak', '/etc/passwd', '/etc/passwd-', '/etc/passwd.edit', '/etc/shadow', '/etc/shadow-', '/etc/shadow.edit', '/var/backups/passwd.bak', '/var/backups/shadow.bak'],
- pbtxt: ['file.pbtxt'],
+ pbtxt: ['file.txtpb', 'file.textproto', 'file.textpb', 'file.pbtxt'],
pccts: ['file.g'],
pcmk: ['file.pcmk'],
pdf: ['file.pdf'],
@@ -563,13 +577,13 @@ def s:GetFilenameChecks(): dict<list<string>>
pymanifest: ['MANIFEST.in'],
pyret: ['file.arr'],
pyrex: ['file.pyx', 'file.pxd'],
- python: ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', 'file.ptl', 'file.pyi', 'SConstruct'],
+ python: ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', '.python_history', '.jline-jython.history', 'file.ptl', 'file.pyi', 'SConstruct'],
ql: ['file.ql', 'file.qll'],
qml: ['file.qml', 'file.qbs'],
qmldir: ['qmldir'],
quake: ['anybaseq2/file.cfg', 'anyid1/file.cfg', 'quake3/file.cfg', 'baseq2/file.cfg', 'id1/file.cfg', 'quake1/file.cfg', 'some-baseq2/file.cfg', 'some-id1/file.cfg', 'some-quake1/file.cfg'],
quarto: ['file.qmd'],
- r: ['file.r', '.Rprofile', 'Rprofile', 'Rprofile.site'],
+ r: ['file.r', '.Rhistory', '.Rprofile', 'Rprofile', 'Rprofile.site'],
racket: ['file.rkt', 'file.rktd', 'file.rktl'],
radiance: ['file.rad', 'file.mat'],
raku: ['file.pm6', 'file.p6', 'file.t6', 'file.pod6', 'file.raku', 'file.rakumod', 'file.rakudoc', 'file.rakutest'],
@@ -581,7 +595,7 @@ def s:GetFilenameChecks(): dict<list<string>>
readline: ['.inputrc', 'inputrc'],
rego: ['file.rego'],
remind: ['.reminders', 'file.remind', 'file.rem', '.reminders-file'],
- requirements: ['file.pip', 'requirements.txt'],
+ requirements: ['file.pip', 'requirements.txt', 'dev-requirements.txt', 'constraints.txt', 'requirements.in', 'requirements/dev.txt', 'requires/dev.txt'],
rescript: ['file.res', 'file.resi'],
resolv: ['resolv.conf'],
reva: ['file.frt'],
@@ -595,6 +609,7 @@ def s:GetFilenameChecks(): dict<list<string>>
rpgle: ['file.rpgle', 'file.rpgleinc'],
robot: ['file.robot', 'file.resource'],
robots: ['robots.txt'],
+ roc: ['file.roc'],
ron: ['file.ron'],
routeros: ['file.rsc'],
rpcgen: ['file.x'],
@@ -602,7 +617,7 @@ def s:GetFilenameChecks(): dict<list<string>>
rrst: ['file.rrst', 'file.srst'],
rst: ['file.rst'],
rtf: ['file.rtf'],
- ruby: ['.irbrc', 'irbrc', 'file.rb', 'file.rbw', 'file.gemspec', 'file.ru', 'Gemfile', 'file.builder', 'file.rxml', 'file.rjs', 'file.rant', 'file.rake', 'rakefile', 'Rakefile', 'rantfile', 'Rantfile', 'rakefile-file', 'Rakefile-file', 'Puppetfile', 'Vagrantfile'],
+ ruby: ['.irbrc', 'irbrc', '.irb_history', 'irb_history', 'file.rb', 'file.rbw', 'file.gemspec', 'file.ru', 'Gemfile', 'file.builder', 'file.rxml', 'file.rjs', 'file.rant', 'file.rake', 'rakefile', 'Rakefile', 'rantfile', 'Rantfile', 'rakefile-file', 'Rakefile-file', 'Puppetfile', 'Vagrantfile'],
rust: ['file.rs'],
samba: ['smb.conf'],
sas: ['file.sas'],
@@ -622,7 +637,10 @@ def s:GetFilenameChecks(): dict<list<string>>
services: ['/etc/services', 'any/etc/services'],
setserial: ['/etc/serial.conf', 'any/etc/serial.conf'],
sexplib: ['file.sexp'],
- sh: ['.bashrc', '.bash_profile', '.bash-profile', '.bash_logout', '.bash-logout', '.bash_aliases', '.bash-aliases', '/tmp/bash-fc-3Ozjlw', '/tmp/bash-fc.3Ozjlw', 'PKGBUILD', 'APKBUILD', 'file.bash', '/usr/share/doc/bash-completion/filter.sh', '/etc/udev/cdsymlinks.conf', 'any/etc/udev/cdsymlinks.conf', 'file.bats'],
+ sh: ['.bashrc', '.bash_profile', '.bash-profile', '.bash_logout', '.bash-logout', '.bash_aliases', '.bash-aliases', '.bash_history', '.bash-history',
+ '/tmp/bash-fc-3Ozjlw', '/tmp/bash-fc.3Ozjlw', 'PKGBUILD', 'APKBUILD', 'file.bash', '/usr/share/doc/bash-completion/filter.sh',
+ '/etc/udev/cdsymlinks.conf', 'any/etc/udev/cdsymlinks.conf', 'file.bats', '.ash_history', 'any/etc/neofetch/config.conf', '.xprofile',
+ 'user-dirs.defaults', 'user-dirs.dirs', 'makepkg.conf', '.makepkg.conf'],
sieve: ['file.siv', 'file.sieve'],
sil: ['file.sil'],
simula: ['file.sim'],
@@ -653,7 +671,7 @@ def s:GetFilenameChecks(): dict<list<string>>
spice: ['file.sp', 'file.spice'],
spup: ['file.speedup', 'file.spdata', 'file.spd'],
spyce: ['file.spy', 'file.spi'],
- sql: ['file.tyb', 'file.tyc', 'file.pkb', 'file.pks'],
+ sql: ['file.tyb', 'file.tyc', 'file.pkb', 'file.pks', '.sqlite_history'],
sqlj: ['file.sqlj'],
prql: ['file.prql'],
sqr: ['file.sqr', 'file.sqi'],
@@ -725,14 +743,14 @@ def s:GetFilenameChecks(): dict<list<string>>
tal: ['file.tal'],
taskdata: ['pending.data', 'completed.data', 'undo.data'],
taskedit: ['file.task'],
- tcl: ['file.tcl', 'file.tm', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl', '.tclshrc', 'tclsh.rc', '.wishrc'],
+ tcl: ['file.tcl', 'file.tm', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl', '.tclshrc', 'tclsh.rc', '.wishrc', '.tclsh-history', '.xsctcmdhistory', '.xsdbcmdhistory'],
tablegen: ['file.td'],
teal: ['file.tl'],
template: ['file.tmpl'],
teraterm: ['file.ttl'],
terminfo: ['file.ti'],
'terraform-vars': ['file.tfvars'],
- tex: ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl'],
+ tex: ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl', 'any/.texlive/texmf-config/tex/latex/file/file.cfg', 'file.pgf', 'file.nlo', 'file.nls', 'file.out', 'file.thm', 'file.eps_tex', 'file.pygtex', 'file.pygstyle', 'file.clo', 'file.aux', 'file.brf', 'file.ind', 'file.lof', 'file.loe', 'file.nav', 'file.vrb', 'file.ins', 'file.tikz', 'file.bbx', 'file.cbx', 'file.beamer'],
texinfo: ['file.texinfo', 'file.texi', 'file.txi'],
texmf: ['texmf.cnf'],
text: ['file.text', 'file.txt', 'README', 'LICENSE', 'COPYING', 'AUTHORS', '/usr/share/doc/bash-completion/AUTHORS', '/etc/apt/apt.conf.d/README', '/etc/Muttrc.d/README'],
@@ -743,7 +761,7 @@ def s:GetFilenameChecks(): dict<list<string>>
tla: ['file.tla'],
tli: ['file.tli'],
tmux: ['tmuxfile.conf', '.tmuxfile.conf', '.tmux-file.conf', '.tmux.conf', 'tmux-file.conf', 'tmux.conf', 'tmux.conf.local'],
- toml: ['file.toml', 'Gopkg.lock', 'Pipfile', '/home/user/.cargo/config'],
+ toml: ['file.toml', 'Gopkg.lock', 'Pipfile', '/home/user/.cargo/config', '.black'],
tpp: ['file.tpp'],
treetop: ['file.treetop'],
trustees: ['trustees.conf'],
@@ -753,9 +771,10 @@ def s:GetFilenameChecks(): dict<list<string>>
tssop: ['file.tssop'],
tsv: ['file.tsv'],
twig: ['file.twig'],
- typescript: ['file.mts', 'file.cts'],
+ typescript: ['file.mts', 'file.cts', '.ts_node_repl_history'],
'typescript.glimmer': ['file.gts'],
typescriptreact: ['file.tsx'],
+ typespec: ['file.tsp'],
ungrammar: ['file.ungram'],
uc: ['file.uc'],
udevconf: ['/etc/udev/udev.conf', 'any/etc/udev/udev.conf'],
@@ -785,7 +804,7 @@ def s:GetFilenameChecks(): dict<list<string>>
vgrindefs: ['vgrindefs'],
vhdl: ['file.hdl', 'file.vhd', 'file.vhdl', 'file.vbe', 'file.vst', 'file.vhdl_123', 'file.vho', 'some.vhdl_1', 'some.vhdl_1-file'],
vhs: ['file.tape'],
- vim: ['file.vim', '.exrc', '_exrc', 'some-vimrc', 'some-vimrc-file', 'vimrc', 'vimrc-file'],
+ vim: ['file.vim', '.exrc', '_exrc', 'some-vimrc', 'some-vimrc-file', 'vimrc', 'vimrc-file', '.netrwhist'],
viminfo: ['.viminfo', '_viminfo'],
vmasm: ['file.mar'],
voscm: ['file.cm'],
@@ -811,7 +830,7 @@ def s:GetFilenameChecks(): dict<list<string>>
xinetd: ['/etc/xinetd.conf', '/etc/xinetd.d/file', 'any/etc/xinetd.conf', 'any/etc/xinetd.d/file'],
xkb: ['/usr/share/X11/xkb/compat/pc', '/usr/share/X11/xkb/geometry/pc', '/usr/share/X11/xkb/keycodes/evdev', '/usr/share/X11/xkb/symbols/pc', '/usr/share/X11/xkb/types/pc'],
xmath: ['file.msc', 'file.msf'],
- xml: ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.fsproj', 'file.fsproj.user', 'file.vbproj', 'file.vbproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu', 'file.atom', 'file.rss', 'file.cdxml', 'file.psc1', 'file.mpd'],
+ xml: ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.fsproj', 'file.fsproj.user', 'file.vbproj', 'file.vbproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu', 'file.atom', 'file.rss', 'file.cdxml', 'file.psc1', 'file.mpd', 'fonts.conf', 'file.xcu', 'file.xlb', 'file.xlc', 'file.xba', 'file.xpr', 'file.xpfm', 'file.spfm', 'file.bxml'],
xmodmap: ['anyXmodmap', 'Xmodmap', 'some-Xmodmap', 'some-xmodmap', 'some-xmodmap-file', 'xmodmap', 'xmodmap-file'],
xpm: ['file.xpm'],
xpm2: ['file.xpm2'],
@@ -820,16 +839,17 @@ def s:GetFilenameChecks(): dict<list<string>>
xsd: ['file.xsd'],
xslt: ['file.xsl', 'file.xslt'],
yacc: ['file.yy', 'file.yxx', 'file.y++'],
- yaml: ['file.yaml', 'file.yml', 'file.eyaml', '.clangd', '.clang-format', '.clang-tidy'],
+ yaml: ['file.yaml', 'file.yml', 'file.eyaml', 'any/.bundle/config', '.clangd', '.clang-format', '.clang-tidy', 'file.mplstyle', 'matplotlibrc', 'yarn.lock'],
yang: ['file.yang'],
yuck: ['file.yuck'],
z8a: ['file.z8a'],
+ zathurarc: ['zathurarc'],
zig: ['file.zig', 'build.zig.zon'],
zimbu: ['file.zu'],
zimbutempl: ['file.zut'],
zserio: ['file.zs'],
- zsh: ['.zprofile', '/etc/zprofile', '.zfbfmarks', 'file.zsh',
- '.zcompdump', '.zlogin', '.zlogout', '.zshenv', '.zshrc',
+ zsh: ['.zprofile', '/etc/zprofile', '.zfbfmarks', 'file.zsh', 'file.zsh-theme', 'file.zunit',
+ '.zcompdump', '.zlogin', '.zlogout', '.zshenv', '.zshrc', '.zsh_history',
'.zcompdump-file', '.zlog', '.zlog-file', '.zsh', '.zsh-file',
'any/etc/zprofile', 'zlog', 'zlog-file', 'zsh', 'zsh-file'],
@@ -2422,4 +2442,26 @@ func Test_def_file()
filetype off
endfunc
+func Test_uci_file()
+ filetype on
+
+ call mkdir('any/etc/config', 'pR')
+ call writefile(['config firewall'], 'any/etc/config/firewall', 'D')
+ split any/etc/config/firewall
+ call assert_equal('uci', &filetype)
+ bwipe!
+
+ call writefile(['# config for nginx here'], 'any/etc/config/firewall', 'D')
+ split any/etc/config/firewall
+ call assert_notequal('uci', &filetype)
+ bwipe!
+
+ call writefile(['# Copyright Cool Cats 1997', 'config firewall'], 'any/etc/config/firewall', 'D')
+ split any/etc/config/firewall
+ call assert_equal('uci', &filetype)
+ bwipe!
+
+ filetype off
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index fecebc4..f0d7385 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -3794,6 +3794,43 @@ func Test_funcref_to_string()
call assert_equal("function('g:Test_funcref_to_string')", string(Fn))
endfunc
+" A funcref cannot start with an underscore (except when used as a protected
+" class or object variable)
+func Test_funcref_with_underscore()
+ " at script level
+ let lines =<< trim END
+ vim9script
+ var _Fn = () => 10
+ END
+ call v9.CheckSourceFailure(lines, 'E704: Funcref variable name must start with a capital: _Fn')
+
+ " inside a function
+ let lines =<< trim END
+ vim9script
+ def Func()
+ var _Fn = () => 10
+ enddef
+ defcompile
+ END
+ call v9.CheckSourceFailure(lines, 'E704: Funcref variable name must start with a capital: _Fn', 1)
+
+ " as a function argument
+ let lines =<< trim END
+ vim9script
+ def Func(_Fn: func)
+ enddef
+ defcompile
+ END
+ call v9.CheckSourceFailure(lines, 'E704: Funcref variable name must start with a capital: _Fn', 2)
+
+ " as a lambda argument
+ let lines =<< trim END
+ vim9script
+ var Fn = (_Farg: func) => 10
+ END
+ call v9.CheckSourceFailure(lines, 'E704: Funcref variable name must start with a capital: _Farg', 2)
+endfunc
+
" Test for isabsolutepath()
func Test_isabsolutepath()
call assert_false(isabsolutepath(''))
diff --git a/src/testdir/test_highlight.vim b/src/testdir/test_highlight.vim
index d6c9f50..9bc5f12 100644
--- a/src/testdir/test_highlight.vim
+++ b/src/testdir/test_highlight.vim
@@ -856,6 +856,15 @@ func Test_highlight_User()
hi clear
endfunc
+" Test for MsgArea highlighting
+func Test_highlight_MsgArea()
+ CheckNotGui
+ hi MsgArea ctermfg=20
+ redraw!
+ call assert_equal('20', synIDattr(synIDtrans(hlID('MsgArea')), 'fg'))
+ hi clear
+endfunc
+
" Test for using RGB color values in a highlight group
func Test_xxlast_highlight_RGB_color()
CheckCanRunGui
diff --git a/src/testdir/test_history.vim b/src/testdir/test_history.vim
index 482328a..19490f2 100644
--- a/src/testdir/test_history.vim
+++ b/src/testdir/test_history.vim
@@ -254,7 +254,7 @@ func Test_history_crypt_key()
set key& bs& ts&
endfunc
-" The following used to overflow and causing an use-after-free
+" The following used to overflow and causing a use-after-free
func Test_history_max_val()
set history=10
diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim
index 52306e8..eb89a15 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -1130,7 +1130,7 @@ func Test_complete_wholeline_unlistedbuf()
edit Xfile1
enew
set complete=U
- " completing from a unloaded buffer should fail
+ " completing from an unloaded buffer should fail
exe "normal! ia\<C-X>\<C-L>\<C-P>"
call assert_equal('a', getline(1))
%d
@@ -2429,4 +2429,26 @@ func Test_complete_changed_complete_info()
call StopVimInTerminal(buf)
endfunc
+func Test_completefunc_first_call_complete_add()
+ new
+
+ func Complete(findstart, base) abort
+ if a:findstart
+ let col = col('.')
+ call complete_add('#')
+ return col - 1
+ else
+ return []
+ endif
+ endfunc
+
+ set completeopt=longest completefunc=Complete
+ " This used to cause heap-buffer-overflow
+ call assert_fails('call feedkeys("ifoo#\<C-X>\<C-U>", "xt")', 'E840:')
+
+ delfunc Complete
+ set completeopt& completefunc&
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
diff --git a/src/testdir/test_let.vim b/src/testdir/test_let.vim
index c99207c..2aba1d3 100644
--- a/src/testdir/test_let.vim
+++ b/src/testdir/test_let.vim
@@ -396,6 +396,45 @@ func Test_let_heredoc_fails()
call assert_report('Caught exception: ' .. v:exception)
endtry
+ try
+ let @- =<< trim TEXT
+ change
+ insert
+ append
+ TEXT
+ call assert_report('No exception thrown')
+ catch /E730:/
+ catch
+ call assert_report('Caught exception: ' .. v:exception)
+ endtry
+
+ try
+ let [] =<< trim TEXT
+ TEXT
+ call assert_report('No exception thrown')
+ catch /E475:/
+ catch
+ call assert_report('Caught exception: ' .. v:exception)
+ endtry
+
+ try
+ let [a b c] =<< trim TEXT
+ TEXT
+ call assert_report('No exception thrown')
+ catch /E475:/
+ catch
+ call assert_report('Caught exception: ' .. v:exception)
+ endtry
+
+ try
+ let [a; b; c] =<< trim TEXT
+ TEXT
+ call assert_report('No exception thrown')
+ catch /E452:/
+ catch
+ call assert_report('Caught exception: ' .. v:exception)
+ endtry
+
let text =<< trim END
func WrongSyntax()
let v =<< that there
@@ -497,6 +536,13 @@ END
XX
call assert_equal(['Line1'], var1)
+ let var1 =<< trim XX " comment
+ Line1
+ Line2
+ Line3
+ XX
+ call assert_equal(['Line1', ' Line2', 'Line3'], var1)
+
" ignore "endfunc"
let var1 =<< END
something
@@ -571,6 +617,22 @@ append
END
call assert_equal(['change', 'insert', 'append'], [a, b, c])
+ " unpack assignment with semicolon
+ let [a; b] =<< END
+change
+insert
+append
+END
+ call assert_equal(['change', ['insert', 'append']], [a, b])
+
+ " unpack assignment with registers
+ let [@/, @", @-] =<< END
+change
+insert
+append
+END
+ call assert_equal(['change', 'insert', 'append'], [@/, @", @-])
+
" curly braces name and list slice assignment
let foo_3_bar = ['', '', '']
let foo_{1 + 2}_bar[ : ] =<< END
@@ -627,6 +689,48 @@ END
END
call assert_equal(['let a = {abc}', 'let b = X', 'let c = {'], code)
+ " Evaluate a dictionary
+ let d1 = #{a: 10, b: 'ss', c: {}}
+ let code =<< eval trim END
+ let d2 = {d1}
+ END
+ call assert_equal(["let d2 = {'a': 10, 'b': 'ss', 'c': {}}"], code)
+
+ " Empty dictionary
+ let d1 = {}
+ let code =<< eval trim END
+ let d2 = {d1}
+ END
+ call assert_equal(["let d2 = {}"], code)
+
+ " null dictionary
+ let d1 = test_null_dict()
+ let code =<< eval trim END
+ let d2 = {d1}
+ END
+ call assert_equal(["let d2 = {}"], code)
+
+ " Evaluate a List
+ let l1 = ['a', 'b', 'c']
+ let code =<< eval trim END
+ let l2 = {l1}
+ END
+ call assert_equal(["let l2 = ['a', 'b', 'c']"], code)
+
+ " Empty List
+ let l1 = []
+ let code =<< eval trim END
+ let l2 = {l1}
+ END
+ call assert_equal(["let l2 = []"], code)
+
+ " Null List
+ let l1 = test_null_list()
+ let code =<< eval trim END
+ let l2 = {l1}
+ END
+ call assert_equal(["let l2 = []"], code)
+
let code = 'xxx'
let code =<< eval trim END
let n = {5 +
@@ -660,6 +764,34 @@ END
LINES
call v9.CheckScriptFailure(lines, 'E15:')
+ " Test for using heredoc in a single string using :execute or execute()
+ for [cmd, res] in items({
+ \ "let x =<< trim END\n one\n two\nEND": ['one', 'two'],
+ \ "let x =<< trim END\n one\n two\nEND": ['one', ' two'],
+ \ " let x =<< trim END\n one\n two\n END": ['one', 'two'],
+ \ " let x =<< trim END\n one\n two\n END": ['one', ' two'],
+ \ "let x =<< END\n one\n two\nEND": [' one', ' two'],
+ \ "let x =<< END\none\ntwo\nEND": ['one', 'two'],
+ \ "let x =<< END \" comment\none\ntwo\nEND": ['one', 'two'],
+ \ })
+ execute cmd
+ call assert_equal(res, x)
+ unlet x
+ call assert_equal($"\n{string(res)}", execute($"{cmd}\necho x"))
+ unlet x
+ endfor
+ for [cmd, err] in items({
+ \ "let x =<<\none\ntwo": "E172:",
+ \ "let x =<< trim\n one\n two": "E172:",
+ \ "let x =<< end\none\ntwo\nend": "E221:",
+ \ "let x =<< END\none\ntwo": "E990: Missing end marker 'END'",
+ \ "let x =<< END !\none\ntwo\nEND": "E488: Trailing characters: !",
+ \ "let x =<< eval END\none\ntwo{y}\nEND": "E121: Undefined variable: y",
+ \ })
+ call assert_fails('execute cmd', err)
+ call assert_fails('call execute(cmd)', err)
+ endfor
+
" skipped heredoc
if 0
let msg =<< trim eval END
diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim
index 8b2c27a..4c69476 100644
--- a/src/testdir/test_listdict.vim
+++ b/src/testdir/test_listdict.vim
@@ -1530,4 +1530,10 @@ func Test_indexof()
delfunc TestIdx
endfunc
+func Test_extendnew_leak()
+ " This used to leak memory
+ for i in range(100) | silent! call extendnew([], [], []) | endfor
+ for i in range(100) | silent! call extendnew({}, {}, {}) | endfor
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim
index 71d9046..1175310 100644
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -248,21 +248,25 @@ func Test_map_meta_multibyte()
endfunc
func Test_map_super_quotes()
- if has('gui_gtk') || has('gui_gtk3') || has("macos")
- imap <D-"> foo
- call feedkeys("Go-\<*D-\">-\<Esc>", "xt")
- call assert_equal("-foo-", getline('$'))
- set nomodified
- iunmap <D-">
+ if "\<D-j>"[-1:] == '>'
+ throw 'Skipped: <D- modifier not supported'
endif
+
+ imap <D-"> foo
+ call feedkeys("Go-\<*D-\">-\<Esc>", "xt")
+ call assert_equal("-foo-", getline('$'))
+ set nomodified
+ iunmap <D-">
endfunc
func Test_map_super_multibyte()
- if has('gui_gtk') || has('gui_gtk3') || has("macos")
- imap <D-á> foo
- call assert_match('i <D-á>\s*foo', execute('imap'))
- iunmap <D-á>
+ if "\<D-j>"[-1:] == '>'
+ throw 'Skipped: <D- modifier not supported'
endif
+
+ imap <D-á> foo
+ call assert_match('i <D-á>\s*foo', execute('imap'))
+ iunmap <D-á>
endfunc
func Test_abbr_after_line_join()
@@ -1807,6 +1811,49 @@ func Test_map_after_timed_out_nop()
call StopVimInTerminal(buf)
endfunc
+" Test 'showcmd' behavior with a partial mapping
+func Test_showcmd_part_map()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ set notimeout showcmd
+ nnoremap ,a <Ignore>
+ nnoremap ;a <Ignore>
+ nnoremap Àa <Ignore>
+ nnoremap Ëa <Ignore>
+ nnoremap βa <Ignore>
+ nnoremap ωa <Ignore>
+ nnoremap …a <Ignore>
+ nnoremap <C-W>a <Ignore>
+ END
+ call writefile(lines, 'Xtest_showcmd_part_map', 'D')
+ let buf = RunVimInTerminal('-S Xtest_showcmd_part_map', #{rows: 6})
+
+ call term_sendkeys(buf, ":set noruler | echo\<CR>")
+ call WaitForAssert({-> assert_equal('', term_getline(buf, 6))})
+
+ for c in [',', ';', 'À', 'Ë', 'β', 'ω', '…']
+ call term_sendkeys(buf, c)
+ call WaitForAssert({-> assert_equal(c, trim(term_getline(buf, 6)))})
+ call term_sendkeys(buf, 'a')
+ call WaitForAssert({-> assert_equal('', trim(term_getline(buf, 6)))})
+ endfor
+
+ call term_sendkeys(buf, "\<C-W>")
+ call WaitForAssert({-> assert_equal('^W', trim(term_getline(buf, 6)))})
+ call term_sendkeys(buf, 'a')
+ call WaitForAssert({-> assert_equal('', trim(term_getline(buf, 6)))})
+
+ " Use feedkeys() as terminal buffer cannot forward unsimplified Ctrl-W.
+ " This is like typing Ctrl-W with modifyOtherKeys enabled.
+ call term_sendkeys(buf, ':call feedkeys("\<*C-W>", "m")' .. " | echo\<CR>")
+ call WaitForAssert({-> assert_equal('^W', trim(term_getline(buf, 6)))})
+ call term_sendkeys(buf, 'a')
+ call WaitForAssert({-> assert_equal('', trim(term_getline(buf, 6)))})
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_using_past_typeahead()
nnoremap :00 0
exe "norm :set \x80\xfb0=0\<CR>"
diff --git a/src/testdir/test_match.vim b/src/testdir/test_match.vim
index 1896158..eb77791 100644
--- a/src/testdir/test_match.vim
+++ b/src/testdir/test_match.vim
@@ -307,6 +307,7 @@ func Test_matchaddpos_error()
" Why doesn't the following error have an error code E...?
call assert_fails("call matchaddpos('Error', [{}])", 'E290:')
call assert_equal(-1, matchaddpos('Error', test_null_list()))
+ call assert_equal(-1, matchaddpos('Error', []))
call assert_fails("call matchaddpos('Error', [1], [], 1)", 'E745:')
call assert_equal(-1, matchaddpos('Search', [[]]))
call assert_fails("call matchaddpos('Search', [[{}]])", 'E728:')
@@ -433,5 +434,4 @@ func Test_match_tab_with_linebreak()
call StopVimInTerminal(buf)
endfunc
-
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_mksession.vim b/src/testdir/test_mksession.vim
index 78d301f..914d1e3 100644
--- a/src/testdir/test_mksession.vim
+++ b/src/testdir/test_mksession.vim
@@ -708,11 +708,11 @@ endfunc
func Test_mkview_no_file_name()
new
- " :mkview or :mkview {nr} should fail in a unnamed buffer.
+ " :mkview or :mkview {nr} should fail in an unnamed buffer.
call assert_fails('mkview', 'E32:')
call assert_fails('mkview 1', 'E32:')
- " :mkview {file} should succeed in a unnamed buffer.
+ " :mkview {file} should succeed in an unnamed buffer.
mkview Xview
help
source Xview
diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim
index b180637..4b7e5e6 100644
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -130,7 +130,7 @@ func Test_normal01_keymodel()
call assert_equal([0, 1, 1, 0], getpos("'<"))
call assert_equal([0, 3, 1, 0], getpos("'>"))
call feedkeys("Gz\<CR>8|\<S-PageUp>y", 'xt')
- call assert_equal([0, 2, 1, 0], getpos("'<"))
+ call assert_equal([0, 3, 1, 0], getpos("'<"))
call assert_equal([0, 3, 8, 0], getpos("'>"))
" Test for <S-C-Home> and <S-C-End>
call cursor(2, 12)
@@ -912,12 +912,10 @@ func Test_normal14_page()
set scrolloff=0
100
exe "norm! $\<c-b>"
- call assert_equal('92', getline('.'))
call assert_equal([0, 92, 1, 0, 1], getcurpos())
100
set nostartofline
exe "norm! $\<c-b>"
- call assert_equal('92', getline('.'))
call assert_equal([0, 92, 2, 0, v:maxcol], getcurpos())
" cleanup
set startofline
@@ -1284,7 +1282,7 @@ func Test_vert_scroll_cmds()
exe "normal \<C-U>"
call assert_equal(36, line('.'))
exe "normal \<C-U>"
- call assert_equal(10, line('.'))
+ call assert_equal(1, line('.'))
exe "normal \<C-U>"
call assert_equal(1, line('.'))
set scroll&
@@ -3815,8 +3813,8 @@ func Test_normal_vert_scroll_longline()
call assert_equal(11, line('.'))
call assert_equal(1, winline())
exe "normal \<C-B>"
- call assert_equal(10, line('.'))
- call assert_equal(3, winline())
+ call assert_equal(11, line('.'))
+ call assert_equal(5, winline())
exe "normal \<C-B>\<C-B>"
call assert_equal(5, line('.'))
call assert_equal(5, winline())
@@ -4174,12 +4172,8 @@ endfunc
" Test for { and } paragraph movements in a single line
func Test_brace_single_line()
- let text =<< trim [DATA]
- foobar one two three
- [DATA]
-
new
- call setline(1, text)
+ call setline(1, ['foobar one two three'])
1
norm! 0}
@@ -4189,4 +4183,81 @@ func Test_brace_single_line()
bw!
endfunc
+" Test for Ctrl-B/Ctrl-U in buffer with a single line
+func Test_single_line_scroll()
+ CheckFeature textprop
+
+ new
+ call setline(1, ['foobar one two three'])
+ let vt = 'virt_above'
+ call prop_type_add(vt, {'highlight': 'IncSearch'})
+ call prop_add(1, 0, {'type': vt, 'text': '---', 'text_align': 'above'})
+ call cursor(1, 1)
+
+ " Ctrl-B/Ctrl-U scroll up with hidden "above" virtual text.
+ set smoothscroll
+ exe "normal \<C-E>"
+ call assert_notequal(0, winsaveview().skipcol)
+ exe "normal \<C-B>"
+ call assert_equal(0, winsaveview().skipcol)
+ exe "normal \<C-E>"
+ call assert_notequal(0, winsaveview().skipcol)
+ exe "normal \<C-U>"
+ call assert_equal(0, winsaveview().skipcol)
+
+ set smoothscroll&
+ bw!
+ call prop_type_delete(vt)
+endfunc
+
+" Test for zb in buffer with a single line and filler lines
+func Test_single_line_filler_zb()
+ call setline(1, ['', 'foobar one two three'])
+ diffthis
+ new
+ call setline(1, ['foobar one two three'])
+ diffthis
+
+ " zb scrolls to reveal filler lines at the start of the buffer.
+ exe "normal \<C-E>zb"
+ call assert_equal(1, winsaveview().topfill)
+
+ bw!
+endfunc
+
+" Test for Ctrl-U not getting stuck at end of buffer with 'scrolloff'.
+func Test_halfpage_scrolloff_eob()
+ set scrolloff=5
+
+ call setline(1, range(1, 100))
+ exe "norm! Gzz\<C-U>zz"
+ call assert_notequal(100, line('.'))
+
+ set scrolloff&
+ bwipe!
+endfunc
+
+" Test for Ctrl-U/D moving the cursor at the buffer boundaries.
+func Test_halfpage_cursor_startend()
+ call setline(1, range(1, 100))
+ exe "norm! jztj\<C-U>"
+ call assert_equal(1, line('.'))
+ exe "norm! G\<C-Y>k\<C-D>"
+ call assert_equal(100, line('.'))
+ bwipe!
+endfunc
+
+" Test for Ctrl-F/B moving the cursor to the window boundaries.
+func Test_page_cursor_topbot()
+ 10new
+ call setline(1, range(1, 100))
+ exe "norm! gg2\<C-F>"
+ call assert_equal(17, line('.'))
+ exe "norm! \<C-B>"
+ call assert_equal(18, line('.'))
+ exe "norm! \<C-B>\<C-F>"
+ call assert_equal(9, line('.'))
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
diff --git a/src/testdir/test_put.vim b/src/testdir/test_put.vim
index 5b5c354..69c2943 100644
--- a/src/testdir/test_put.vim
+++ b/src/testdir/test_put.vim
@@ -319,4 +319,21 @@ func Test_put_visual_replace_fold_marker()
bwipe!
endfunc
+func Test_put_dict()
+ new
+ let d = #{a: #{b: 'abc'}, c: [1, 2], d: 0z10}
+ put! =d
+ call assert_equal(["{'a': {'b': 'abc'}, 'c': [1, 2], 'd': 0z10}", ''],
+ \ getline(1, '$'))
+ bw!
+endfunc
+
+func Test_put_list()
+ new
+ let l = ['a', 'b', 'c']
+ put! =l
+ call assert_equal(['a', 'b', 'c', ''], getline(1, '$'))
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_recover.vim b/src/testdir/test_recover.vim
index a084ef4..e85b2e9 100644
--- a/src/testdir/test_recover.vim
+++ b/src/testdir/test_recover.vim
@@ -380,7 +380,7 @@ func Test_recover_encrypted_swap_file()
call delete('Xfile1')
endfunc
-" Test for :recover using a unreadable swap file
+" Test for :recover using an unreadable swap file
func Test_recover_unreadable_swap_file()
CheckUnix
CheckNotRoot
diff --git a/src/testdir/test_regexp_latin.vim b/src/testdir/test_regexp_latin.vim
index 9acb12b..63f093a 100644
--- a/src/testdir/test_regexp_latin.vim
+++ b/src/testdir/test_regexp_latin.vim
@@ -874,12 +874,26 @@ func Regex_Mark()
%d
endfunc
+" Same test as above, but use verymagic
+func Regex_Mark_Verymagic()
+ call append(0, ['', '', '', 'Marks:', 'asdfSasdfsadfEasdf', 'asdfSas',
+ \ 'dfsadfEasdf', '', '', '', '', ''])
+ call cursor(4, 1)
+ exe "normal jfSmsfEme:.-4,.+6s/\\v.%>'s.*%<'e../here/\<CR>"
+ exe "normal jfSmsj0fEme:.-4,.+6s/\\v.%>'s\\_.*%<'e../again/\<CR>"
+ call assert_equal(['', '', '', 'Marks:', 'asdfhereasdf', 'asdfagainasdf',
+ \ '', '', '', '', '', ''], getline(1, '$'))
+ %d
+endfunc
+
func Test_matching_marks()
new
set regexpengine=1
call Regex_Mark()
+ call Regex_Mark_Verymagic()
set regexpengine=2
call Regex_Mark()
+ call Regex_Mark_Verymagic()
bwipe!
endfunc
diff --git a/src/testdir/test_regexp_utf8.vim b/src/testdir/test_regexp_utf8.vim
index 6669dee..bc70544 100644
--- a/src/testdir/test_regexp_utf8.vim
+++ b/src/testdir/test_regexp_utf8.vim
@@ -342,7 +342,7 @@ func Test_multibyte_chars()
endfunc
" check that 'ambiwidth' does not change the meaning of \p
-func Test_ambiwidth()
+func Test_regexp_ambiwidth()
set regexpengine=1 ambiwidth=single
call assert_equal(0, match("\u00EC", '\p'))
set regexpengine=1 ambiwidth=double
diff --git a/src/testdir/test_registers.vim b/src/testdir/test_registers.vim
index cb4cee7..b2261d4 100644
--- a/src/testdir/test_registers.vim
+++ b/src/testdir/test_registers.vim
@@ -209,6 +209,71 @@ func Test_recording_with_select_mode()
bwipe!
endfunc
+func Run_test_recording_with_select_mode_utf8()
+ new
+
+ " Test with different text lengths: 5, 7, 9, 11, 13, 15, to check that
+ " a character isn't split between two buffer blocks.
+ for s in ['12345', 'å£=å£', 'å£å£å£', 'å£=å£=å£', 'å£å£=å£å£', 'å£å£å£å£å£']
+ " 0x80 is K_SPECIAL
+ " 0x9B is CSI
+ " 哦: 0xE5 0x93 0xA6
+ " æ´›: 0xE6 0xB4 0x9B
+ " 固: 0xE5 0x9B 0xBA
+ " å››: 0xE5 0x9B 0x9B
+ " 最: 0xE6 0x9C 0x80
+ " 倒: 0xE5 0x80 0x92
+ " 倀: 0xE5 0x80 0x80
+ for c in ['哦', '洛', '固', '四', '最', '倒', '倀']
+ call setline(1, 'asdf')
+ call feedkeys($"qacc{s}\<Esc>gH{c}\<Esc>q", "tx")
+ call assert_equal(c, getline(1))
+ call assert_equal($"cc{s}\<Esc>gH{c}\<Esc>", @a)
+ call setline(1, 'asdf')
+ normal! @a
+ call assert_equal(c, getline(1))
+
+ " Test with Shift modifier.
+ let shift_c = eval($'"\<S-{c}>"')
+ call setline(1, 'asdf')
+ call feedkeys($"qacc{s}\<Esc>gH{shift_c}\<Esc>q", "tx")
+ call assert_equal(c, getline(1))
+ call assert_equal($"cc{s}\<Esc>gH{shift_c}\<Esc>", @a)
+ call setline(1, 'asdf')
+ normal! @a
+ call assert_equal(c, getline(1))
+ endfor
+ endfor
+
+ bwipe!
+endfunc
+
+func Test_recording_with_select_mode_utf8()
+ call Run_test_recording_with_select_mode_utf8()
+endfunc
+
+" This must be done as one of the last tests, because it starts the GUI, which
+" cannot be undone.
+func Test_zz_recording_with_select_mode_utf8_gui()
+ CheckCanRunGui
+
+ gui -f
+ call Run_test_recording_with_select_mode_utf8()
+endfunc
+
+func Test_recording_with_super_mod()
+ if "\<D-j>"[-1:] == '>'
+ throw 'Skipped: <D- modifier not supported'
+ endif
+
+ nnoremap <D-j> <Ignore>
+ let s = repeat("\<D-j>", 1000)
+ " This used to crash Vim
+ call feedkeys($'qr{s}q', 'tx')
+ call assert_equal(s, @r)
+ nunmap <D-j>
+endfunc
+
" Test for executing the last used register (@)
func Test_last_used_exec_reg()
" Test for the @: command
@@ -745,13 +810,13 @@ func Test_ve_blockpaste()
call cursor(1,1)
exe ":norm! \<C-V>3ljdP"
call assert_equal(1, col('.'))
- call assert_equal(getline(1, 2), ['QWERTZ', 'ASDFGH'])
+ call assert_equal(['QWERTZ', 'ASDFGH'], getline(1, 2))
call cursor(1,1)
exe ":norm! \<C-V>3ljd"
call cursor(1,1)
norm! $3lP
call assert_equal(5, col('.'))
- call assert_equal(getline(1, 2), ['TZ QWER', 'GH ASDF'])
+ call assert_equal(['TZ QWER', 'GH ASDF'], getline(1, 2))
set ve&vim
bwipe!
endfunc
diff --git a/src/testdir/test_remote.vim b/src/testdir/test_remote.vim
index ae931fd..1475052 100644
--- a/src/testdir/test_remote.vim
+++ b/src/testdir/test_remote.vim
@@ -76,4 +76,49 @@ func Test_remote_servername()
close
endfunc
+func Test_remote_servername_shellslash()
+ " Note this test does not currently run on Windows
+ " because:
+ " 1) we cannot run the gui version of Vim inside a terminal
+ " 2) Running Windows vim.exe inside a terminal would work, but is
+ " disabled because of the limited colors inside the default Windows
+ " console (see CanRunVimInTerminal in term_util.vim)
+ CheckRunVimInTerminal
+ CheckMSWindows
+
+ " That is the file we want the server to open,
+ " despite the wildignore setting
+ call mkdir(expand('~/remote/'), 'pD')
+ call writefile(range(1, 20), expand('~/remote/XTEST.txt'), 'D')
+ " just a dummy file, so that the ':wq' further down is successful
+ call writefile(range(1, 20), 'Xdummy.log', 'D')
+
+ " Run Vim in a terminal and open a terminal window to run Vim in.
+ let lines =<< trim END
+ set shellslash
+ cd ~/remote
+ END
+ call writefile(lines, 'XRemoteEditing1.vim', 'D')
+ let buf = RunVimInTerminal('--servername XVIMTEST -S XRemoteEditing1.vim Xdummy.log', {'rows': 10})
+ call TermWait(buf)
+
+ " wildignore setting should be ignored and the XVIMTEST server should now
+ " open XTEST.txt, if wildignore setting is not ignored, the server
+ " will continue with the Xdummy.log file
+ let buf2 = RunVimInTerminal('--servername XVIMTEST --remote-silent ~/remote/XTEST.txt', {'rows': 5, 'wait_for_ruler': 0})
+ " job should be no-longer running, so we can just close it
+ exe buf2 .. 'bw!'
+
+ call term_sendkeys(buf, ":pwd\<CR>")
+ call WaitForAssert({-> assert_match('remote/$', term_getline(buf, 10))}, 1000)
+ call TermWait(buf)
+ call term_sendkeys(buf, ":q!\<CR>")
+ call TermWait(buf)
+ if term_getstatus(buf) == 'running'
+ call StopVimInTerminal(buf)
+ endif
+ bw!
+ close
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index 3467760..cda9bf0 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -552,11 +552,11 @@ func Test_smoothscroll_cursor_position()
" Test "g0/g<Home>"
exe "normal gg\<C-E>"
norm $gkg0
- call s:check_col_calc(1, 2, 21)
+ call s:check_col_calc(4, 1, 24)
" Test moving the cursor behind the <<< display with 'virtualedit'
set virtualedit=all
- exe "normal \<C-E>3lgkh"
+ exe "normal \<C-E>gkh"
call s:check_col_calc(3, 2, 23)
set virtualedit&
@@ -738,6 +738,7 @@ func Test_smoothscroll_mouse_pos()
let &mouse = save_mouse
let &term = save_term
let &ttymouse = save_ttymouse
+ bwipe!
endfunc
" this was dividing by zero
@@ -829,7 +830,7 @@ func Test_smoothscroll_eob()
call VerifyScreenDump(buf, 'Test_smooth_eob_1', {})
" cursor is not placed below window
- call term_sendkeys(buf, ":call setline(92, 'a'->repeat(100))\<CR>\<C-B>G")
+ call term_sendkeys(buf, ":call setline(92, 'a'->repeat(100))\<CR>\<C-L>\<C-B>G")
call VerifyScreenDump(buf, 'Test_smooth_eob_2', {})
call StopVimInTerminal(buf)
@@ -998,4 +999,113 @@ func Test_smoothscroll_textoff_small_winwidth()
set smoothscroll& number&
endfunc
+func Test_smoothscroll_page()
+ call NewWindow(10, 40)
+ setlocal smoothscroll
+ call setline(1, 'abcde '->repeat(150))
+
+ exe "norm! \<C-F>"
+ call assert_equal(400, winsaveview().skipcol)
+ exe "norm! \<C-F>"
+ call assert_equal(800, winsaveview().skipcol)
+ exe "norm! \<C-F>"
+ call assert_equal(880, winsaveview().skipcol)
+ exe "norm! \<C-B>"
+ call assert_equal(480, winsaveview().skipcol)
+ exe "norm! \<C-B>"
+ call assert_equal(80, winsaveview().skipcol)
+ exe "norm! \<C-B>"
+ call assert_equal(0, winsaveview().skipcol)
+
+ " Half-page scrolling does not go beyond end of buffer and moves the cursor.
+ " Even with 'nostartofline', the correct amount of lines is scrolled.
+ setl nostartofline
+ exe "norm! 15|\<C-D>"
+ call assert_equal(200, winsaveview().skipcol)
+ call assert_equal(215, col('.'))
+ exe "norm! \<C-D>"
+ call assert_equal(400, winsaveview().skipcol)
+ call assert_equal(415, col('.'))
+ exe "norm! \<C-D>"
+ call assert_equal(520, winsaveview().skipcol)
+ call assert_equal(615, col('.'))
+ exe "norm! \<C-D>"
+ call assert_equal(520, winsaveview().skipcol)
+ call assert_equal(815, col('.'))
+ exe "norm! \<C-D>"
+ call assert_equal(520, winsaveview().skipcol)
+ call assert_equal(895, col('.'))
+ exe "norm! \<C-U>"
+ call assert_equal(320, winsaveview().skipcol)
+ call assert_equal(695, col('.'))
+ exe "norm! \<C-U>"
+ call assert_equal(120, winsaveview().skipcol)
+ call assert_equal(495, col('.'))
+ exe "norm! \<C-U>"
+ call assert_equal(0, winsaveview().skipcol)
+ call assert_equal(295, col('.'))
+ exe "norm! \<C-U>"
+ call assert_equal(0, winsaveview().skipcol)
+ call assert_equal(95, col('.'))
+ exe "norm! \<C-U>"
+ call assert_equal(0, winsaveview().skipcol)
+ call assert_equal(15, col('.'))
+
+ bwipe!
+endfunc
+
+func Test_smoothscroll_next_topline()
+ call NewWindow(10, 40)
+ setlocal smoothscroll
+ call setline(1, ['abcde '->repeat(150)]->repeat(2))
+
+ " Scrolling a screenline that causes the cursor to move to the next buffer
+ " line should not skip part of that line to bring the cursor into view.
+ exe "norm! 22\<C-E>"
+ call assert_equal(880, winsaveview().skipcol)
+ exe "norm! \<C-E>"
+ redraw
+ call assert_equal(0, winsaveview().skipcol)
+
+ " Also when scrolling back.
+ exe "norm! G\<C-Y>"
+ redraw
+ call assert_equal(880, winsaveview().skipcol)
+
+ " Cursor in correct place when not in the first screenline of a buffer line.
+ exe "norm! gg4gj20\<C-D>\<C-D>"
+ redraw
+ call assert_equal(2, line('w0'))
+
+ " Cursor does not end up above topline, adjusting topline later.
+ setlocal nu cpo+=n
+ exe "norm! G$g013\<C-Y>"
+ redraw
+ call assert_equal(2, line('.'))
+ call assert_equal(0, winsaveview().skipcol)
+
+ set cpo-=n
+ bwipe!
+endfunc
+
+func Test_smoothscroll_long_line_zb()
+ call NewWindow(10, 40)
+ call setline(1, 'abcde '->repeat(150))
+
+ " Also works without 'smoothscroll' when last line of buffer doesn't fit.
+ " Used to set topline to buffer line count plus one, causing an empty screen.
+ norm zb
+ redraw
+ call assert_equal(1, winsaveview().topline)
+
+ " Moving cursor to bottom works on line that doesn't fit with 'smoothscroll'.
+ " Skipcol was adjusted later for cursor being on not visible part of line.
+ setlocal smoothscroll
+ norm zb
+ redraw
+ call assert_equal(520, winsaveview().skipcol)
+
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_sound.vim b/src/testdir/test_sound.vim
index e97ac61..401753e 100644
--- a/src/testdir/test_sound.vim
+++ b/src/testdir/test_sound.vim
@@ -15,6 +15,7 @@ func Test_play_event()
if has('win32')
throw 'Skipped: Playing event with callback is not supported on Windows'
endif
+ let g:result = 0
let g:playcallback_count = 0
let g:id = 0
let event_name = 'bell'
@@ -37,6 +38,7 @@ endfunc
func Test_play_silent()
let fname = fnamemodify('silent.wav', '%p')
let g:playcallback_count = 0
+ let g:result = -1
" play without callback
let id1 = sound_playfile(fname)
diff --git a/src/testdir/test_tabpage.vim b/src/testdir/test_tabpage.vim
index a531f19..3624790 100644
--- a/src/testdir/test_tabpage.vim
+++ b/src/testdir/test_tabpage.vim
@@ -117,10 +117,16 @@ function Test_tabpage()
call assert_equal(3, tabpagenr())
+3tabmove
call assert_equal(6, tabpagenr())
+ silent -tabmove
+ call assert_equal(5, tabpagenr())
+ silent -2 tabmove
+ call assert_equal(3, tabpagenr())
+ silent -2 tabmove
+ call assert_equal(1, tabpagenr())
- " The following are a no-op
norm! 2gt
call assert_equal(2, tabpagenr())
+ " The following are a no-op
tabmove 2
call assert_equal(2, tabpagenr())
2tabmove
diff --git a/src/testdir/test_taglist.vim b/src/testdir/test_taglist.vim
index 39e78bc..2dd2366 100644
--- a/src/testdir/test_taglist.vim
+++ b/src/testdir/test_taglist.vim
@@ -100,7 +100,10 @@ func Test_tagfiles()
help
let tf = tagfiles()
- call assert_equal(1, len(tf))
+ " if 'helplang includes another language, then we may find
+ " 2 tagfiles (e.g.: for EN and RU)
+ " we may need to adjust this, if further translated help files are included
+ call assert_inrange(1, 2, len(tf))
call assert_equal(fnamemodify(expand('$VIMRUNTIME/doc/tags'), ':p:gs?\\?/?'),
\ fnamemodify(tf[0], ':p:gs?\\?/?'))
helpclose
diff --git a/src/testdir/test_terminal3.vim b/src/testdir/test_terminal3.vim
index 96a9e63..223bcc5 100644
--- a/src/testdir/test_terminal3.vim
+++ b/src/testdir/test_terminal3.vim
@@ -931,5 +931,25 @@ func Test_terminal_term_start_error()
delfunc s:term_start_error
endfunc
+func Test_terminal_vt420()
+ CheckRunVimInTerminal
+ " For Termcap
+ CheckUnix
+ let rows=15
+ call writefile([':set term=vt420'], 'Xterm420', 'D')
+
+ let buf = RunVimInTerminal('-S Xterm420', #{rows: rows})
+ call TermWait(buf, 100)
+ call term_sendkeys(buf, ":set t_xo?\<CR>")
+ call WaitForAssert({-> assert_match('t_xo=y', term_getline(buf, rows))})
+ call StopVimInTerminal(buf)
+
+ call writefile([''], 'Xterm420')
+ let buf = RunVimInTerminal('-S Xterm420', #{rows: rows})
+ call TermWait(buf, 100)
+ call term_sendkeys(buf, ":set t_xo?\<CR>")
+ call WaitForAssert({-> assert_match('t_xo=\s\+', term_getline(buf, rows))})
+ call StopVimInTerminal(buf)
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_textformat.vim b/src/testdir/test_textformat.vim
index c5f5975..a9cffd0 100644
--- a/src/testdir/test_textformat.vim
+++ b/src/testdir/test_textformat.vim
@@ -1303,4 +1303,13 @@ func Test_correct_cursor_position()
set encoding=utf8
endfunc
+" This was crashing Vim
+func Test_textwdith_overflow()
+ new
+ setl tw=999999999
+ normal 10ig
+ call feedkeys('a ab cd ef', 'xt')
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim
index a06f733..2bf2834 100644
--- a/src/testdir/test_textprop.vim
+++ b/src/testdir/test_textprop.vim
@@ -2690,6 +2690,48 @@ func Test_prop_inserts_text_normal_gj_gk()
call Run_test_prop_inserts_text_normal_gj_gk('set virtualedit=all')
endfunc
+func Test_prop_normal_gj_gk_gM_with_outer_virtual_text()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ vim9script
+ setlocal number
+ setline(1, ['First line fits on screen line.', '', 'Third line fits on screen line.'])
+
+ var vt = 'test'
+ prop_type_add(vt, {highlight: 'ToDo'})
+ for ln in range(1, line('$'))
+ prop_add(ln, 0, {type: vt, text: 'Above', text_align: 'above'})
+ prop_add(ln, 0, {type: vt, text: 'After text wraps to next line.', text_align: 'after', text_wrap: 'wrap'})
+ prop_add(ln, 0, {type: vt, text: 'Right text wraps to next line.', text_align: 'right', text_wrap: 'wrap'})
+ prop_add(ln, 0, {type: vt, text: 'Below', text_align: 'below'})
+ endfor
+ normal 3l
+ END
+ call writefile(lines, 'XscriptPropsNormal_gj_gk_gM_with_outer_text', 'D')
+ let buf = RunVimInTerminal('-S XscriptPropsNormal_gj_gk_gM_with_outer_text', #{rows: 16, cols: 40})
+ call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_gM_with_outer_virtual_text_1', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_gM_with_outer_virtual_text_2', {})
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_gM_with_outer_virtual_text_3', {})
+ call term_sendkeys(buf, "gk")
+ call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_gM_with_outer_virtual_text_2', {})
+ call term_sendkeys(buf, "gk")
+ call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_gM_with_outer_virtual_text_1', {})
+
+ call term_sendkeys(buf, "2gj")
+ call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_gM_with_outer_virtual_text_3', {})
+ call term_sendkeys(buf, "2gk")
+ call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_gM_with_outer_virtual_text_1', {})
+
+ call term_sendkeys(buf, "gM")
+ call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_gM_with_outer_virtual_text_4', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_prop_inserts_text_visual_block()
CheckRunVimInTerminal
@@ -3026,6 +3068,43 @@ func Test_props_with_text_after_below_trunc()
call StopVimInTerminal(buf)
endfunc
+func Test_props_with_text_truncated_just_before_after()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ vim9script
+ set showbreak=+++
+ set list listchars=extends:>
+ set nowrap
+
+ setline(1, [
+ 'here is text long enough to fill the row',
+ 'second line',
+ ])
+
+ prop_type_add("test", {"highlight": "Error"})
+ prop_add(1, 0, {type: "test", text_align: "right", text: "right text"})
+ def g:AddPropBelow()
+ prop_add(1, 0, {type: "test", text_align: "below", text: "below text"})
+ enddef
+ def g:AddPropAfter()
+ prop_add(1, 0, {type: "test", text: "after text", text_padding_left: 1})
+ enddef
+ normal G$
+ END
+ call writefile(lines, 'XscriptPropsWithTextTruncatedJustBeforeAfter', 'D')
+ let buf = RunVimInTerminal('-S XscriptPropsWithTextTruncatedJustBeforeAfter', #{rows: 8, cols: 40})
+ call VerifyScreenDump(buf, 'Test_props_with_text_truncated_just_before_after_1', {})
+
+ call term_sendkeys(buf, ":call AddPropBelow()\<CR>")
+ call VerifyScreenDump(buf, 'Test_props_with_text_truncated_just_before_after_2', {})
+
+ call term_sendkeys(buf, ":call AddPropAfter()\<CR>:\<Esc>")
+ call VerifyScreenDump(buf, 'Test_props_with_text_truncated_just_before_after_2', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_prop_with_text_below_after_empty()
CheckRunVimInTerminal
diff --git a/src/testdir/test_utf8.vim b/src/testdir/test_utf8.vim
index 3bb7459..0f46240 100644
--- a/src/testdir/test_utf8.vim
+++ b/src/testdir/test_utf8.vim
@@ -62,6 +62,9 @@ func Test_customlist_completion()
call assert_equal('"Test3 N', getreg(':'))
call garbagecollect(1)
+ delcommand Test1
+ delcommand Test2
+ delcommand Test3
endfunc
" Yank one 3 byte character and check the mark columns.
@@ -170,6 +173,7 @@ func Test_screenchar_utf8()
endfunc
func Test_setcellwidths()
+ new
call setcellwidths([
\ [0x1330, 0x1330, 2],
\ [9999, 10000, 1],
@@ -212,6 +216,18 @@ func Test_setcellwidths()
" Ambiguous width chars
call assert_equal(2, strwidth("\u00A1"))
call assert_equal(2, strwidth("\u2010"))
+
+ call setcellwidths([])
+ call setline(1, repeat("\u2103", 10))
+ normal! $
+ redraw
+ call assert_equal((aw == 'single') ? 10 : 19, wincol())
+ call setcellwidths([[0x2103, 0x2103, 1]])
+ redraw
+ call assert_equal(10, wincol())
+ call setcellwidths([[0x2103, 0x2103, 2]])
+ redraw
+ call assert_equal(19, wincol())
endfor
set ambiwidth& isprint&
@@ -245,6 +261,7 @@ func Test_setcellwidths()
set listchars&
set fillchars&
call setcellwidths([])
+ bwipe!
endfunc
func Test_getcellwidths()
@@ -283,64 +300,66 @@ func Test_setcellwidths_dump()
call StopVimInTerminal(buf)
endfunc
-func Test_print_overlong()
- " Text with more composing characters than MB_MAXBYTES.
- new
- call setline(1, 'axxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
- s/x/\=nr2char(1629)/g
- print
- bwipe!
-endfunc
+" Test setcellwidths() on characters that are not targets of 'ambiwidth'.
+func Test_setcellwidths_with_non_ambiwidth_character_dump()
+ CheckRunVimInTerminal
-func Test_recording_with_select_mode_utf8()
- call Run_test_recording_with_select_mode_utf8()
+ let lines =<< trim END
+ call setline(1, [repeat("\u279c", 60), repeat("\u279c", 60)])
+ set ambiwidth=single
+ END
+ call writefile(lines, 'XCellwidthsWithNonAmbiwidthCharacter', 'D')
+ let buf = RunVimInTerminal('-S XCellwidthsWithNonAmbiwidthCharacter', {'rows': 6, 'cols': 50})
+ call term_sendkeys(buf, ":call setcellwidths([[0x279c, 0x279c, 1]])\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_setcellwidths_with_non_ambiwidth_character_dump_1', {})
+
+ call term_sendkeys(buf, ":call setcellwidths([[0x279c, 0x279c, 2]])\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_setcellwidths_with_non_ambiwidth_character_dump_2', {})
+
+ call StopVimInTerminal(buf)
endfunc
-func Run_test_recording_with_select_mode_utf8()
- new
+" For some reason this test causes Test_customlist_completion() to fail on CI,
+" so run it as the last test.
+func Test_zz_ambiwidth_hl_dump()
+ CheckRunVimInTerminal
- " No escaping
- call feedkeys("qacc12345\<Esc>gH哦\<Esc>q", "tx")
- call assert_equal("哦", getline(1))
- call assert_equal("cc12345\<Esc>gH哦\<Esc>", @a)
- call setline(1, 'asdf')
- normal! @a
- call assert_equal("哦", getline(1))
-
- " 固 is 0xE5 0x9B 0xBA where 0x9B is CSI
- call feedkeys("qacc12345\<Esc>gH固\<Esc>q", "tx")
- call assert_equal("固", getline(1))
- call assert_equal("cc12345\<Esc>gH固\<Esc>", @a)
- call setline(1, 'asdf')
- normal! @a
- call assert_equal("固", getline(1))
-
- " å›› is 0xE5 0x9B 0x9B where 0x9B is CSI
- call feedkeys("qacc12345\<Esc>gHå››\<Esc>q", "tx")
- call assert_equal("å››", getline(1))
- call assert_equal("cc12345\<Esc>gHå››\<Esc>", @a)
- call setline(1, 'asdf')
- normal! @a
- call assert_equal("å››", getline(1))
-
- " 倒 is 0xE5 0x80 0x92 where 0x80 is K_SPECIAL
- call feedkeys("qacc12345\<Esc>gH倒\<Esc>q", "tx")
- call assert_equal("倒", getline(1))
- call assert_equal("cc12345\<Esc>gH倒\<Esc>", @a)
- call setline(1, 'asdf')
- normal! @a
- call assert_equal("倒", getline(1))
+ let lines =<< trim END
+ call setline(1, [repeat("\u2103", 60), repeat("\u2103", 60)])
+ set ambiwidth=single cursorline list display=lastline
+ END
+ call writefile(lines, 'XAmbiwidthHl', 'D')
+ let buf = RunVimInTerminal('-S XAmbiwidthHl', {'rows': 6, 'cols': 50})
+ call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_1', {})
- bwipe!
-endfunc
+ call term_sendkeys(buf, ":set ambiwidth=double\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_2', {})
+
+ call term_sendkeys(buf, ":set ambiwidth=single\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_1', {})
+
+ call term_sendkeys(buf, ":call setcellwidths([[0x2103, 0x2103, 2]])\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_2', {})
+
+ call term_sendkeys(buf, ":call setcellwidths([[0x2103, 0x2103, 1]])\<CR>")
+ call term_sendkeys(buf, ":echo\<CR>")
+ call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_1', {})
-" This must be done as one of the last tests, because it starts the GUI, which
-" cannot be undone.
-func Test_zz_recording_with_select_mode_utf8_gui()
- CheckCanRunGui
+ call StopVimInTerminal(buf)
+endfunc
- gui -f
- call Run_test_recording_with_select_mode_utf8()
+func Test_print_overlong()
+ " Text with more composing characters than MB_MAXBYTES.
+ new
+ call setline(1, 'axxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
+ s/x/\=nr2char(1629)/g
+ print
+ bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index 4414f55..4296c37 100644
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -1104,6 +1104,27 @@ def Test_assignment_partial()
Ref(0)
END
v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected string but got number')
+
+ lines =<< trim END
+ var Fn1 = () => {
+ return 10
+ }
+ assert_equal('func(): number', typename(Fn1))
+ var Fn2 = () => {
+ return "a"
+ }
+ assert_equal('func(): string', typename(Fn2))
+ var Fn3 = () => {
+ return {a: [1]}
+ }
+ assert_equal('func(): dict<list<number>>', typename(Fn3))
+ var Fn4 = (...l: list<string>) => {
+ return []
+ }
+ assert_equal('func(...list<string>): list<any>', typename(Fn4))
+ END
+ v9.CheckSourceSuccess(['vim9script'] + lines)
+ v9.CheckSourceSuccess(['def Xfunc()'] + lines + ['enddef', 'defcompile'])
enddef
def Test_assignment_list_any_index()
@@ -1997,6 +2018,31 @@ def Test_heredoc()
END
v9.CheckScriptSuccess(lines)
+ # commented out heredoc assignment without space after '#'
+ lines =<< trim END
+ vim9script
+ def Func()
+ #x =<< trim [CODE]
+ #[CODE]
+ enddef
+ Func()
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # heredoc start should not be recognized in string
+ lines =<< trim END
+ vim9script
+ def Func()
+ new
+ @" = 'bar'
+ ['foo', @"]->setline("]=<<"->count('='))
+ assert_equal(['foo', 'bar'], getline(1, '$'))
+ bwipe!
+ enddef
+ Func()
+ END
+ v9.CheckScriptSuccess(lines)
+
v9.CheckDefFailure(['var lines =<< trim END X', 'END'], 'E488:')
v9.CheckDefFailure(['var lines =<< trim END " comment', 'END'], 'E488:')
@@ -2938,6 +2984,66 @@ def Test_heredoc_expr()
CODE
v9.CheckDefAndScriptSuccess(lines)
+ # Evaluate a dictionary
+ lines =<< trim CODE
+ var d1 = {'a': 10, 'b': [1, 2]}
+ var code =<< trim eval END
+ var d2 = {d1}
+ END
+ assert_equal(["var d2 = {'a': 10, 'b': [1, 2]}"], code)
+ CODE
+ v9.CheckDefAndScriptSuccess(lines)
+
+ # Evaluate an empty dictionary
+ lines =<< trim CODE
+ var d1 = {}
+ var code =<< trim eval END
+ var d2 = {d1}
+ END
+ assert_equal(["var d2 = {}"], code)
+ CODE
+ v9.CheckDefAndScriptSuccess(lines)
+
+ # Evaluate a null dictionary
+ lines =<< trim CODE
+ var d1 = test_null_dict()
+ var code =<< trim eval END
+ var d2 = {d1}
+ END
+ assert_equal(["var d2 = {}"], code)
+ CODE
+ v9.CheckDefAndScriptSuccess(lines)
+
+ # Evaluate a List
+ lines =<< trim CODE
+ var l1 = ['a', 'b', 'c']
+ var code =<< trim eval END
+ var l2 = {l1}
+ END
+ assert_equal(["var l2 = ['a', 'b', 'c']"], code)
+ CODE
+ v9.CheckDefAndScriptSuccess(lines)
+
+ # Evaluate an empty List
+ lines =<< trim CODE
+ var l1 = []
+ var code =<< trim eval END
+ var l2 = {l1}
+ END
+ assert_equal(["var l2 = []"], code)
+ CODE
+ v9.CheckDefAndScriptSuccess(lines)
+
+ # Evaluate a null List
+ lines =<< trim CODE
+ var l1 = test_null_list()
+ var code =<< trim eval END
+ var l2 = {l1}
+ END
+ assert_equal(["var l2 = []"], code)
+ CODE
+ v9.CheckDefAndScriptSuccess(lines)
+
lines =<< trim CODE
var code =<< eval trim END
var s = "{$SOME_ENV_VAR}"
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index 442d375..42d09fe 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -66,16 +66,16 @@ def Test_abs()
assert_equal(0, abs(0))
assert_equal(2, abs(-2))
assert_equal(3, abs(3))
- v9.CheckDefAndScriptFailure(['abs("text")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['abs("text")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal(0, abs(0))
assert_equal(2.0, abs(-2.0))
assert_equal(3.0, abs(3.0))
enddef
def Test_add()
- v9.CheckDefAndScriptFailure(['add({}, 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1226: List or Blob required for argument 1'])
- v9.CheckDefAndScriptFailure(['add([])'], 'E119:')
- v9.CheckDefExecFailure([
+ v9.CheckSourceDefAndScriptFailure(['add({}, 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1226: List or Blob required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['add([])'], 'E119:')
+ v9.CheckSourceDefExecFailure([
'var ln: list<number> = [1]',
'add(ln, "a")'],
'E1012: Type mismatch; expected number but got string')
@@ -91,7 +91,7 @@ def Test_add()
enddef
TryChange()
END
- v9.CheckScriptFailure(lines, 'E741:')
+ v9.CheckSourceScriptFailure(lines, 'E741:')
enddef
def Test_add_blob()
@@ -107,18 +107,18 @@ def Test_add_blob()
var b: blob
add(b, "x")
END
- v9.CheckDefFailure(lines, 'E1012:', 2)
+ v9.CheckSourceDefFailure(lines, 'E1012:', 2)
lines =<< trim END
add(test_null_blob(), 123)
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1131:', 1)
+ v9.CheckSourceDefExecAndScriptFailure(lines, 'E1131:', 1)
lines =<< trim END
var b: blob = test_null_blob()
add(b, 123)
END
- v9.CheckDefExecFailure(lines, 'E1131:', 2)
+ v9.CheckSourceDefExecFailure(lines, 'E1131:', 2)
# Getting variable with NULL blob fails
lines =<< trim END
@@ -126,7 +126,7 @@ def Test_add_blob()
var b: blob = test_null_blob()
add(b, 123)
END
- v9.CheckScriptFailure(lines, 'E1131:', 3)
+ v9.CheckSourceScriptFailure(lines, 'E1131:', 3)
enddef
def Test_add_list()
@@ -138,18 +138,18 @@ def Test_add_list()
var l: list<number>
add(l, "x")
END
- v9.CheckDefFailure(lines, 'E1012:', 2)
+ v9.CheckSourceDefFailure(lines, 'E1012:', 2)
lines =<< trim END
add(test_null_list(), 123)
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1130:', 1)
+ v9.CheckSourceDefExecAndScriptFailure(lines, 'E1130:', 1)
lines =<< trim END
var l: list<number> = test_null_list()
add(l, 123)
END
- v9.CheckDefExecFailure(lines, 'E1130:', 2)
+ v9.CheckSourceDefExecFailure(lines, 'E1130:', 2)
# Getting an uninitialized variable allocates a new list at script level
lines =<< trim END
@@ -157,7 +157,7 @@ def Test_add_list()
var l: list<number>
add(l, 123)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceScriptSuccess(lines)
# Adding to a variable set to a NULL list fails
lines =<< trim END
@@ -165,21 +165,21 @@ def Test_add_list()
var l: list<number> = test_null_list()
add(l, 123)
END
- v9.CheckScriptFailure(lines, 'E1130:', 3)
+ v9.CheckSourceScriptFailure(lines, 'E1130:', 3)
lines =<< trim END
vim9script
var l: list<string> = ['a']
l->add(123)
END
- v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 3)
+ v9.CheckSourceScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 3)
lines =<< trim END
vim9script
var l: list<string>
l->add(123)
END
- v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 3)
+ v9.CheckSourceScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 3)
enddef
def Test_add_const()
@@ -187,26 +187,26 @@ def Test_add_const()
const l = [1, 2]
add(l, 3)
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
lines =<< trim END
final l = [1, 2]
add(l, 3)
assert_equal([1, 2, 3], l)
END
- v9.CheckDefSuccess(lines)
+ v9.CheckSourceDefSuccess(lines)
lines =<< trim END
const b = 0z0102
add(b, 0z03)
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob')
enddef
def Test_and()
- v9.CheckDefAndScriptFailure(['and("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['and(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['and("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['and(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_append()
@@ -224,12 +224,12 @@ def Test_append()
assert_equal("{'a': 10}", getline(1))
append(0, function('min'))
assert_equal("function('min')", getline(1))
- v9.CheckDefAndScriptFailure(['append([1], "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['append("", "x")'], 'E1209: Invalid value for a line number')
- v9.CheckDefExecAndScriptFailure(['append(".a", "x")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['append([1], "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['append("", "x")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefExecAndScriptFailure(['append(".a", "x")'], 'E1209: Invalid value for a line number')
# only get one error
assert_fails('append("''aa", "x")', ['E1209: Invalid value for a line number: "''aa"', 'E1209:'])
- v9.CheckDefExecAndScriptFailure(['append(-1, "x")'], 'E966: Invalid line number: -1')
+ v9.CheckSourceDefExecAndScriptFailure(['append(-1, "x")'], 'E966: Invalid line number: -1')
bwipe!
enddef
@@ -245,12 +245,12 @@ def Test_appendbufline()
assert_equal(['0', 'one', '1', 'two', '2', ''], getbufline(bnum, 1, '$'))
appendbufline(bnum, 0, 'zero')
assert_equal(['zero'], getbufline(bnum, 1))
- v9.CheckDefAndScriptFailure(['appendbufline([1], 1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['appendbufline(1, [1], "x")'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['appendbufline(' .. bnum .. ', -1, "x")'], 'E966: Invalid line number: -1')
- v9.CheckDefExecAndScriptFailure(['appendbufline(' .. bnum .. ', "$a", "x")'], 'E1030: Using a String as a Number: "$a"')
+ v9.CheckSourceDefAndScriptFailure(['appendbufline([1], 1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['appendbufline(1, [1], "x")'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['appendbufline(' .. bnum .. ', -1, "x")'], 'E966: Invalid line number: -1')
+ v9.CheckSourceDefExecAndScriptFailure(['appendbufline(' .. bnum .. ', "$a", "x")'], 'E1030: Using a String as a Number: "$a"')
assert_fails('appendbufline(' .. bnum .. ', "$a", "x")', ['E1030: Using a String as a Number: "$a"', 'E1030:'])
- v9.CheckDefAndScriptFailure(['appendbufline(1, 1, {"a": 10})'], ['E1013: Argument 3: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['appendbufline(1, 1, {"a": 10})'], ['E1013: Argument 3: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 3'])
bnum->bufwinid()->win_gotoid()
appendbufline('', 0, 'numbers')
getline(1)->assert_equal('numbers')
@@ -258,80 +258,80 @@ def Test_appendbufline()
enddef
def Test_argc()
- v9.CheckDefAndScriptFailure(['argc("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['argc("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_arglistid()
- v9.CheckDefAndScriptFailure(['arglistid("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['arglistid(1, "y")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['arglistid("x", "y")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['arglistid("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['arglistid(1, "y")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['arglistid("x", "y")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_argv()
- v9.CheckDefAndScriptFailure(['argv("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['argv(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['argv("x", "y")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['argv("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['argv(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['argv("x", "y")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_assert_beeps()
- v9.CheckDefAndScriptFailure(['assert_beeps(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['assert_beeps(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
enddef
def Test_assert_equalfile()
- v9.CheckDefAndScriptFailure(['assert_equalfile(1, "f2")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['assert_equalfile("f1", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['assert_equalfile("f1", "f2", ["a"])'], ['E1013: Argument 3: type mismatch, expected string but got list<string>', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['assert_equalfile(1, "f2")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['assert_equalfile("f1", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['assert_equalfile("f1", "f2", ["a"])'], ['E1013: Argument 3: type mismatch, expected string but got list<string>', 'E1174: String required for argument 3'])
enddef
def Test_assert_exception()
- v9.CheckDefAndScriptFailure(['assert_exception({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['assert_exception("E1:", v:null)'], ['E1013: Argument 2: type mismatch, expected string but got special', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['assert_exception({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['assert_exception("E1:", v:null)'], ['E1013: Argument 2: type mismatch, expected string but got special', 'E1174: String required for argument 2'])
enddef
def Test_assert_fails()
- v9.CheckDefAndScriptFailure(['assert_fails([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['assert_fails("a", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1222: String or List required for argument 2'])
- v9.CheckDefAndScriptFailure(['assert_fails("a", "b", "c", "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
- v9.CheckDefAndScriptFailure(['assert_fails("a", "b", "c", 4, 5)'], ['E1013: Argument 5: type mismatch, expected string but got number', 'E1174: String required for argument 5'])
+ v9.CheckSourceDefAndScriptFailure(['assert_fails([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['assert_fails("a", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1222: String or List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['assert_fails("a", "b", "c", "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['assert_fails("a", "b", "c", 4, 5)'], ['E1013: Argument 5: type mismatch, expected string but got number', 'E1174: String required for argument 5'])
enddef
def Test_assert_inrange()
- v9.CheckDefAndScriptFailure(['assert_inrange("a", 2, 3)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['assert_inrange(1, "b", 3)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['assert_inrange(1, 2, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['assert_inrange(1, 2, 3, 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['assert_inrange("a", 2, 3)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['assert_inrange(1, "b", 3)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['assert_inrange(1, 2, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['assert_inrange(1, 2, 3, 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4'])
enddef
def Test_assert_match()
- v9.CheckDefAndScriptFailure(['assert_match({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', ''])
- v9.CheckDefAndScriptFailure(['assert_match("a", 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', ''])
- v9.CheckDefAndScriptFailure(['assert_match("a", "b", null)'], ['E1013: Argument 3: type mismatch, expected string but got special', ''])
+ v9.CheckSourceDefAndScriptFailure(['assert_match({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', ''])
+ v9.CheckSourceDefAndScriptFailure(['assert_match("a", 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', ''])
+ v9.CheckSourceDefAndScriptFailure(['assert_match("a", "b", null)'], ['E1013: Argument 3: type mismatch, expected string but got special', ''])
enddef
def Test_assert_nobeep()
- v9.CheckDefAndScriptFailure(['assert_nobeep(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['assert_nobeep(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
enddef
def Test_assert_notmatch()
- v9.CheckDefAndScriptFailure(['assert_notmatch({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', ''])
- v9.CheckDefAndScriptFailure(['assert_notmatch("a", 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', ''])
- v9.CheckDefAndScriptFailure(['assert_notmatch("a", "b", null)'], ['E1013: Argument 3: type mismatch, expected string but got special', ''])
+ v9.CheckSourceDefAndScriptFailure(['assert_notmatch({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', ''])
+ v9.CheckSourceDefAndScriptFailure(['assert_notmatch("a", 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', ''])
+ v9.CheckSourceDefAndScriptFailure(['assert_notmatch("a", "b", null)'], ['E1013: Argument 3: type mismatch, expected string but got special', ''])
enddef
def Test_assert_report()
- v9.CheckDefAndScriptFailure(['assert_report([1, 2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['assert_report([1, 2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
enddef
def Test_autocmd_add()
- v9.CheckDefAndScriptFailure(['autocmd_add({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['autocmd_add({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
enddef
def Test_autocmd_delete()
- v9.CheckDefAndScriptFailure(['autocmd_delete({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['autocmd_delete({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
enddef
def Test_autocmd_get()
- v9.CheckDefAndScriptFailure(['autocmd_get(10)'], ['E1013: Argument 1: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['autocmd_get(10)'], ['E1013: Argument 1: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 1'])
enddef
def Test_balloon_show()
@@ -341,8 +341,8 @@ def Test_balloon_show()
assert_fails('balloon_show(10)', 'E1222:')
assert_fails('balloon_show(true)', 'E1222:')
- v9.CheckDefAndScriptFailure(['balloon_show(1.2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['balloon_show({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['balloon_show(1.2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['balloon_show({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
enddef
def Test_balloon_split()
@@ -354,22 +354,22 @@ enddef
def Test_blob2list()
assert_equal(['x', 'x'], blob2list(0z1234)->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['blob2list(10)'], ['E1013: Argument 1: type mismatch, expected blob but got number', 'E1238: Blob required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['blob2list(10)'], ['E1013: Argument 1: type mismatch, expected blob but got number', 'E1238: Blob required for argument 1'])
enddef
def Test_browse()
CheckFeature browse
- v9.CheckDefAndScriptFailure(['browse(2, "title", "dir", "file")'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
- v9.CheckDefAndScriptFailure(['browse(true, 2, "dir", "file")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['browse(true, "title", 3, "file")'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
- v9.CheckDefAndScriptFailure(['browse(true, "title", "dir", 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['browse(2, "title", "dir", "file")'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['browse(true, 2, "dir", "file")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['browse(true, "title", 3, "file")'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['browse(true, "title", "dir", 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4'])
enddef
def Test_browsedir()
if has('browse')
- v9.CheckDefAndScriptFailure(['browsedir({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['browsedir("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['browsedir({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['browsedir("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
endif
enddef
@@ -425,8 +425,8 @@ def Test_bufnr()
buf = bufnr('Xdummy', true)
buf->assert_notequal(-1)
exe 'bwipe! ' .. buf
- v9.CheckDefAndScriptFailure(['bufnr([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['bufnr(1, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['bufnr([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['bufnr(1, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
enddef
def Test_bufwinid()
@@ -452,23 +452,23 @@ def Test_bufwinnr()
enddef
def Test_byte2line()
- v9.CheckDefAndScriptFailure(['byte2line("1")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['byte2line([])'], ['E1013: Argument 1: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['byte2line("1")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['byte2line([])'], ['E1013: Argument 1: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 1'])
byte2line(0)->assert_equal(-1)
enddef
def Test_byteidx()
- v9.CheckDefAndScriptFailure(['byteidx(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['byteidx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['byteidx("a", 0, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['byteidx(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['byteidx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['byteidx("a", 0, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
byteidx('', 0)->assert_equal(0)
byteidx('', 1)->assert_equal(-1)
enddef
def Test_byteidxcomp()
- v9.CheckDefAndScriptFailure(['byteidxcomp(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['byteidxcomp("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['byteidxcomp("a", 0, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['byteidxcomp(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['byteidxcomp("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['byteidxcomp("a", 0, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
enddef
def Test_call_call()
@@ -488,20 +488,20 @@ def Test_call_call()
assert_equal('Inner', g:done)
unlet g:done
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceScriptSuccess(lines)
delfunc g:Inner
- v9.CheckDefExecAndScriptFailure(['call(123, [2])'], 'E1256: String or function required for argument 1')
- v9.CheckDefExecAndScriptFailure(['call(true, [2])'], 'E1256: String or function required for argument 1')
- v9.CheckDefAndScriptFailure(['call("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
- v9.CheckDefAndScriptFailure(['call("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefExecAndScriptFailure(['call(123, [2])'], 'E1256: String or function required for argument 1')
+ v9.CheckSourceDefExecAndScriptFailure(['call(true, [2])'], 'E1256: String or function required for argument 1')
+ v9.CheckSourceDefAndScriptFailure(['call("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['call("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
enddef
def Test_ch_canread()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_canread(10)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_canread(10)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
endif
enddef
@@ -509,7 +509,7 @@ def Test_ch_close()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_close("c")'], ['E1013: Argument 1: type mismatch, expected channel but got string', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_close("c")'], ['E1013: Argument 1: type mismatch, expected channel but got string', 'E1217: Channel or Job required for argument 1'])
endif
enddef
@@ -517,7 +517,7 @@ def Test_ch_close_in()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_close_in(true)'], ['E1013: Argument 1: type mismatch, expected channel but got bool', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_close_in(true)'], ['E1013: Argument 1: type mismatch, expected channel but got bool', 'E1217: Channel or Job required for argument 1'])
endif
enddef
@@ -525,8 +525,8 @@ def Test_ch_evalexpr()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_evalexpr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_evalexpr(test_null_channel(), 1, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['ch_evalexpr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_evalexpr(test_null_channel(), 1, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
endif
enddef
@@ -534,9 +534,9 @@ def Test_ch_evalraw()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_evalraw(1, "")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_evalraw(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1221: String or Blob required for argument 2'])
- v9.CheckDefAndScriptFailure(['ch_evalraw(test_null_channel(), "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['ch_evalraw(1, "")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_evalraw(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1221: String or Blob required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['ch_evalraw(test_null_channel(), "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
endif
enddef
@@ -544,8 +544,8 @@ def Test_ch_getbufnr()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_getbufnr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_getbufnr(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['ch_getbufnr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_getbufnr(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
# test empty string argument for ch_getbufnr()
var job: job = job_start(&shell)
g:WaitForAssert(() => assert_equal('run', job_status(job)))
@@ -558,8 +558,8 @@ def Test_ch_getjob()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_getjob(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_getjob({"a": 10})'], ['E1013: Argument 1: type mismatch, expected channel but got dict<number>', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_getjob(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_getjob({"a": 10})'], ['E1013: Argument 1: type mismatch, expected channel but got dict<number>', 'E1217: Channel or Job required for argument 1'])
assert_equal(0, ch_getjob(test_null_channel()))
endif
enddef
@@ -568,7 +568,7 @@ def Test_ch_info()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_info([1])'], ['E1013: Argument 1: type mismatch, expected channel but got list<number>', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_info([1])'], ['E1013: Argument 1: type mismatch, expected channel but got list<number>', 'E1217: Channel or Job required for argument 1'])
endif
enddef
@@ -576,8 +576,8 @@ def Test_ch_log()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_log(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_log("a", 1)'], ['E1013: Argument 2: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['ch_log(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_log("a", 1)'], ['E1013: Argument 2: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 2'])
endif
enddef
@@ -589,8 +589,8 @@ def Test_ch_logfile()
assert_fails('ch_logfile("foo", true)', 'E1174:')
ch_logfile('', '')->assert_equal(0)
- v9.CheckDefAndScriptFailure(['ch_logfile(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_logfile("a", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['ch_logfile(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_logfile("a", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2'])
endif
enddef
@@ -598,9 +598,9 @@ def Test_ch_open()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_open({"a": 10}, "a")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_open("a", [1])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['ch_open("")'], 'E475: Invalid argument')
+ v9.CheckSourceDefAndScriptFailure(['ch_open({"a": 10}, "a")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_open("a", [1])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['ch_open("")'], 'E475: Invalid argument')
endif
enddef
@@ -608,8 +608,8 @@ def Test_ch_read()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_read(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_read(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['ch_read(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_read(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
endif
enddef
@@ -617,8 +617,8 @@ def Test_ch_readblob()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_readblob(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_readblob(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['ch_readblob(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_readblob(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
endif
enddef
@@ -626,8 +626,8 @@ def Test_ch_readraw()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_readraw(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_readraw(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['ch_readraw(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_readraw(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
endif
enddef
@@ -635,8 +635,8 @@ def Test_ch_sendexpr()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_sendexpr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_sendexpr(test_null_channel(), 1, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['ch_sendexpr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_sendexpr(test_null_channel(), 1, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
endif
enddef
@@ -644,9 +644,9 @@ def Test_ch_sendraw()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_sendraw(1, "")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_sendraw(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1221: String or Blob required for argument 2'])
- v9.CheckDefAndScriptFailure(['ch_sendraw(test_null_channel(), "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['ch_sendraw(1, "")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_sendraw(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1221: String or Blob required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['ch_sendraw(test_null_channel(), "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
endif
enddef
@@ -654,8 +654,8 @@ def Test_ch_setoptions()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_setoptions(1, {})'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_setoptions(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['ch_setoptions(1, {})'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_setoptions(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
endif
enddef
@@ -663,8 +663,8 @@ def Test_ch_status()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['ch_status(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['ch_status(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['ch_status(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ch_status(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
endif
enddef
@@ -672,8 +672,8 @@ def Test_char2nr()
char2nr('ã‚', true)->assert_equal(12354)
assert_fails('char2nr(true)', 'E1174:')
- v9.CheckDefAndScriptFailure(['char2nr(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['char2nr("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['char2nr(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['char2nr("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
assert_equal(97, char2nr('a', 1))
assert_equal(97, char2nr('a', 0))
assert_equal(97, char2nr('a', true))
@@ -687,10 +687,10 @@ def Test_charclass()
enddef
def Test_charcol()
- v9.CheckDefAndScriptFailure(['charcol(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['charcol({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['charcol(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['charcol("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['charcol(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['charcol({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['charcol(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['charcol("")'], 'E1209: Invalid value for a line number')
new
setline(1, ['abcdefgh'])
cursor(1, 4)
@@ -701,10 +701,10 @@ def Test_charcol()
enddef
def Test_charidx()
- v9.CheckDefAndScriptFailure(['charidx(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['charidx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['charidx("a", 1, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
- v9.CheckDefAndScriptFailure(['charidx("a", 1, 0, "")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['charidx(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['charidx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['charidx("a", 1, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['charidx("a", 1, 0, "")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4'])
charidx('', 0)->assert_equal(0)
charidx('', 1)->assert_equal(-1)
enddef
@@ -714,15 +714,15 @@ def Test_chdir()
enddef
def Test_cindent()
- v9.CheckDefAndScriptFailure(['cindent([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['cindent(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['cindent("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['cindent([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['cindent(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['cindent("")'], 'E1209: Invalid value for a line number')
assert_equal(-1, cindent(0))
assert_equal(0, cindent('.'))
enddef
def Test_clearmatches()
- v9.CheckDefAndScriptFailure(['clearmatches("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['clearmatches("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_col()
@@ -735,26 +735,26 @@ def Test_col()
assert_fails('col(true)', 'E1222:')
- v9.CheckDefAndScriptFailure(['col(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['col({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['col(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['col(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['col("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['col(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['col({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['col(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['col(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['col("")'], 'E1209: Invalid value for a line number')
bw!
enddef
def Test_complete()
- v9.CheckDefAndScriptFailure(['complete("1", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['complete(1, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['complete("1", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['complete(1, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2'])
enddef
def Test_complete_add()
- v9.CheckDefAndScriptFailure(['complete_add([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1223: String or Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['complete_add([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1223: String or Dictionary required for argument 1'])
enddef
def Test_complete_info()
- v9.CheckDefAndScriptFailure(['complete_info("")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['complete_info({})'], ['E1013: Argument 1: type mismatch, expected list<string> but got dict<any>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['complete_info("")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['complete_info({})'], ['E1013: Argument 1: type mismatch, expected list<string> but got dict<any>', 'E1211: List required for argument 1'])
assert_equal({'pum_visible': 0, 'mode': '', 'selected': -1, 'items': []}, complete_info())
assert_equal({'mode': '', 'items': []}, complete_info(['mode', 'items']))
enddef
@@ -767,10 +767,10 @@ def Test_confirm()
assert_fails('confirm(true)', 'E1174:')
assert_fails('confirm("yes", true)', 'E1174:')
assert_fails('confirm("yes", "maybe", 2, true)', 'E1174:')
- v9.CheckDefAndScriptFailure(['confirm(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['confirm("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['confirm("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['confirm("a", "b", 3, 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['confirm(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['confirm("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['confirm("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['confirm("a", "b", 3, 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4'])
enddef
def Test_copy_return_type()
@@ -798,7 +798,7 @@ def Test_copy_return_type()
var nll: list<list<number>> = [[1, 2]]
nll->copy()[0]->extend(['x'])
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<number> but got list<string> in extend()')
+ v9.CheckSourceDefExecAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<number> but got list<string> in extend()')
var nd: dict<number> = {a: 1, b: 2}
assert_equal({a: 1, b: 2, c: 'x'}, nd->copy()->extend({c: 'x'}))
@@ -806,7 +806,7 @@ def Test_copy_return_type()
var ndd: dict<dict<number>> = {a: {x: 1, y: 2}}
ndd->copy()['a']->extend({z: 'x'})
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<number> but got dict<string> in extend()')
+ v9.CheckSourceDefExecAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<number> but got dict<string> in extend()')
# after a deepcopy() the item type can also change
var nll: list<list<number>> = [[1, 2]]
@@ -822,9 +822,9 @@ enddef
def Test_count()
count('ABC ABC ABC', 'b', true)->assert_equal(3)
count('ABC ABC ABC', 'b', false)->assert_equal(0)
- v9.CheckDefAndScriptFailure(['count(10, 1)'], 'E1225: String, List or Dictionary required for argument 1')
- v9.CheckDefAndScriptFailure(['count("a", [1], 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
- v9.CheckDefAndScriptFailure(['count("a", [1], 0, "b")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['count(10, 1)'], 'E1225: String, List or Dictionary required for argument 1')
+ v9.CheckSourceDefAndScriptFailure(['count("a", [1], 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['count("a", [1], 0, "b")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
count([1, 2, 2, 3], 2)->assert_equal(2)
count([1, 2, 2, 3], 2, false, 2)->assert_equal(1)
count({a: 1.1, b: 2.2, c: 1.1}, 1.1)->assert_equal(2)
@@ -833,9 +833,9 @@ enddef
def Test_cscope_connection()
CheckFeature cscope
assert_equal(0, cscope_connection())
- v9.CheckDefAndScriptFailure(['cscope_connection("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['cscope_connection(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['cscope_connection(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['cscope_connection("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['cscope_connection(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['cscope_connection(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
enddef
def Test_cursor()
@@ -851,35 +851,35 @@ def Test_cursor()
var lines =<< trim END
cursor('2', 1)
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1209:')
- v9.CheckDefAndScriptFailure(['cursor(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected number but got blob', 'E1224: String, Number or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['cursor(1, "2")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['cursor(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefExecAndScriptFailure(['cursor("", 2)'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefExecAndScriptFailure(lines, 'E1209:')
+ v9.CheckSourceDefAndScriptFailure(['cursor(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected number but got blob', 'E1224: String, Number or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['cursor(1, "2")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['cursor(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefExecAndScriptFailure(['cursor("", 2)'], 'E1209: Invalid value for a line number')
enddef
def Test_debugbreak()
CheckMSWindows
- v9.CheckDefAndScriptFailure(['debugbreak("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['debugbreak("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_deepcopy()
- v9.CheckDefAndScriptFailure(['deepcopy({}, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['deepcopy({}, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
enddef
def Test_delete()
var res: bool = delete('doesnotexist')
assert_equal(true, res)
- v9.CheckDefAndScriptFailure(['delete(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['delete("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['delete("")'], 'E474: Invalid argument')
+ v9.CheckSourceDefAndScriptFailure(['delete(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['delete("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['delete("")'], 'E474: Invalid argument')
enddef
def Test_deletebufline()
- v9.CheckDefAndScriptFailure(['deletebufline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['deletebufline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['deletebufline("a", 2, 0z10)'], ['E1013: Argument 3: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['deletebufline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['deletebufline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['deletebufline("a", 2, 0z10)'], ['E1013: Argument 3: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 3'])
new
setline(1, ['one', 'two'])
deletebufline('', 1)
@@ -892,58 +892,58 @@ def Test_deletebufline()
enddef
def Test_diff_filler()
- v9.CheckDefAndScriptFailure(['diff_filler([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['diff_filler(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['diff_filler("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['diff_filler([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['diff_filler(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['diff_filler("")'], 'E1209: Invalid value for a line number')
assert_equal(0, diff_filler(1))
assert_equal(0, diff_filler('.'))
enddef
def Test_diff_hlID()
- v9.CheckDefAndScriptFailure(['diff_hlID(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['diff_hlID(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['diff_hlID("", 10)'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['diff_hlID(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['diff_hlID(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['diff_hlID("", 10)'], 'E1209: Invalid value for a line number')
enddef
def Test_digraph_get()
- v9.CheckDefAndScriptFailure(['digraph_get(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['digraph_get("")'], 'E1214: Digraph must be just two characters')
+ v9.CheckSourceDefAndScriptFailure(['digraph_get(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['digraph_get("")'], 'E1214: Digraph must be just two characters')
enddef
def Test_digraph_getlist()
- v9.CheckDefAndScriptFailure(['digraph_getlist(10)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
- v9.CheckDefAndScriptFailure(['digraph_getlist("")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['digraph_getlist(10)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['digraph_getlist("")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
enddef
def Test_digraph_set()
- v9.CheckDefAndScriptFailure(['digraph_set(10, "a")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['digraph_set("ab", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['digraph_set("", "a")'], 'E1214: Digraph must be just two characters')
+ v9.CheckSourceDefAndScriptFailure(['digraph_set(10, "a")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['digraph_set("ab", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['digraph_set("", "a")'], 'E1214: Digraph must be just two characters')
enddef
def Test_digraph_setlist()
- v9.CheckDefAndScriptFailure(['digraph_setlist("a")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1216: digraph_setlist() argument must be a list of lists with two items'])
- v9.CheckDefAndScriptFailure(['digraph_setlist({})'], ['E1013: Argument 1: type mismatch, expected list<string> but got dict<any>', 'E1216: digraph_setlist() argument must be a list of lists with two items'])
+ v9.CheckSourceDefAndScriptFailure(['digraph_setlist("a")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1216: digraph_setlist() argument must be a list of lists with two items'])
+ v9.CheckSourceDefAndScriptFailure(['digraph_setlist({})'], ['E1013: Argument 1: type mismatch, expected list<string> but got dict<any>', 'E1216: digraph_setlist() argument must be a list of lists with two items'])
enddef
def Test_echoraw()
- v9.CheckDefAndScriptFailure(['echoraw(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['echoraw(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['echoraw(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['echoraw(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
enddef
def Test_escape()
- v9.CheckDefAndScriptFailure(['escape(10, " ")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['escape(true, false)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['escape("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['escape(10, " ")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['escape(true, false)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['escape("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
assert_equal('a\:b', escape("a:b", ":"))
escape('abc', '')->assert_equal('abc')
escape('', ':')->assert_equal('')
enddef
def Test_eval()
- v9.CheckDefAndScriptFailure(['eval(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['eval(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['eval("")'], 'E15: Invalid expression')
+ v9.CheckSourceDefAndScriptFailure(['eval(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['eval(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['eval("")'], 'E15: Invalid expression')
assert_equal(2, eval('1 + 1'))
enddef
@@ -951,8 +951,8 @@ def Test_executable()
assert_false(executable(""))
assert_false(executable(test_null_string()))
- v9.CheckDefExecFailure(['echo executable(123)'], 'E1013:')
- v9.CheckDefExecFailure(['echo executable(true)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo executable(123)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo executable(true)'], 'E1013:')
enddef
def Test_execute()
@@ -961,22 +961,22 @@ def Test_execute()
res = execute(["echo 'here'", "echo 'there'"])
assert_equal("\nhere\nthere", res)
- v9.CheckDefAndScriptFailure(['execute(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1'])
- v9.CheckDefFailure(['execute([123])'], 'E1013: Argument 1: type mismatch, expected list<string> but got list<number>')
- v9.CheckDefExecFailure(['echo execute(["xx", 123])'], 'E492')
- v9.CheckDefAndScriptFailure(['execute("xx", 123)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['execute(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefFailure(['execute([123])'], 'E1013: Argument 1: type mismatch, expected list<string> but got list<number>')
+ v9.CheckSourceDefExecFailure(['echo execute(["xx", 123])'], 'E492')
+ v9.CheckSourceDefAndScriptFailure(['execute("xx", 123)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
enddef
def Test_exepath()
- v9.CheckDefExecFailure(['echo exepath(true)'], 'E1013:')
- v9.CheckDefExecFailure(['echo exepath(v:null)'], 'E1013:')
- v9.CheckDefExecFailure(['echo exepath("")'], 'E1175:')
+ v9.CheckSourceDefExecFailure(['echo exepath(true)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo exepath(v:null)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo exepath("")'], 'E1175:')
enddef
command DoSomeCommand let g:didSomeCommand = 4
def Test_exists()
- v9.CheckDefAndScriptFailure(['exists(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['exists(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
call assert_equal(1, exists('&tabstop'))
var lines =<< trim END
@@ -985,14 +985,14 @@ def Test_exists()
endif
endif
END
- v9.CheckDefFailure(lines, 'E113:')
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceDefFailure(lines, 'E113:')
+ v9.CheckSourceScriptSuccess(lines)
enddef
def Test_exists_compiled()
call assert_equal(1, exists_compiled('&tabstop'))
- v9.CheckDefAndScriptFailure(['exists_compiled(10)'], ['E1232:', 'E1233:'])
- v9.CheckDefAndScriptFailure(['exists_compiled(v:progname)'], ['E1232:', 'E1233:'])
+ v9.CheckSourceDefAndScriptFailure(['exists_compiled(10)'], ['E1232:', 'E1233:'])
+ v9.CheckSourceDefAndScriptFailure(['exists_compiled(v:progname)'], ['E1232:', 'E1233:'])
if exists_compiled('+newoption')
if &newoption == 'ok'
@@ -1044,9 +1044,9 @@ def Test_expand()
split SomeFile
expand('%', true, true)->assert_equal(['SomeFile'])
close
- v9.CheckDefAndScriptFailure(['expand(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['expand("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
- v9.CheckDefAndScriptFailure(['expand("a", true, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['expand(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['expand("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['expand("a", true, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
expand('')->assert_equal('')
var caught = false
@@ -1065,8 +1065,8 @@ def Test_expandcmd()
assert_equal("yes", expandcmd("`={a: 'yes'}['a']`"))
expandcmd('')->assert_equal('')
- v9.CheckDefAndScriptFailure(['expandcmd([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['expandcmd("abc", [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['expandcmd([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['expandcmd("abc", [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_extend_arg_types()
@@ -1093,7 +1093,7 @@ def Test_extend_arg_types()
dany->extend({b: 'x'})
assert_equal({a: 0, b: 'x'}, dany)
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
lines =<< trim END
assert_equal([1, 2, "x"], extend([1, 2], ["x"]))
@@ -1101,17 +1101,17 @@ def Test_extend_arg_types()
assert_equal({a: 1, b: "x"}, extend({a: 1}, {b: "x"}))
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
- v9.CheckDefAndScriptFailure(['extend("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E712: Argument of extend() must be a List or Dictionary'])
- v9.CheckDefAndScriptFailure(['extend([1, 2], 3)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E712: Argument of extend() must be a List or Dictionary'])
- v9.CheckDefAndScriptFailure(['var ll = [1, 2]', 'extend(ll, ["x"])'], ['E1013: Argument 2: type mismatch, expected list<number> but got list<string>', 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>'])
- v9.CheckDefFailure(['extend([1, 2], [3], "x")'], 'E1013: Argument 3: type mismatch, expected number but got string')
+ v9.CheckSourceDefAndScriptFailure(['extend("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E712: Argument of extend() must be a List or Dictionary'])
+ v9.CheckSourceDefAndScriptFailure(['extend([1, 2], 3)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E712: Argument of extend() must be a List or Dictionary'])
+ v9.CheckSourceDefAndScriptFailure(['var ll = [1, 2]', 'extend(ll, ["x"])'], ['E1013: Argument 2: type mismatch, expected list<number> but got list<string>', 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>'])
+ v9.CheckSourceDefFailure(['extend([1, 2], [3], "x")'], 'E1013: Argument 3: type mismatch, expected number but got string')
- v9.CheckDefFailure(['extend({a: 1}, 42)'], 'E1013: Argument 2: type mismatch, expected dict<any> but got number')
- v9.CheckDefFailure(['extend({a: 1}, {b: 2}, 1)'], 'E1013: Argument 3: type mismatch, expected string but got number')
+ v9.CheckSourceDefFailure(['extend({a: 1}, 42)'], 'E1013: Argument 2: type mismatch, expected dict<any> but got number')
+ v9.CheckSourceDefFailure(['extend({a: 1}, {b: 2}, 1)'], 'E1013: Argument 3: type mismatch, expected string but got number')
- v9.CheckScriptFailure(['vim9script', 'var l = [1]', 'extend(l, ["b", 1])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<any> in extend()')
+ v9.CheckSourceScriptFailure(['vim9script', 'var l = [1]', 'extend(l, ["b", 1])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<any> in extend()')
enddef
func g:ExtendDict(d)
@@ -1123,26 +1123,26 @@ def Test_extend_dict_item_type()
var d: dict<number> = {a: 1}
extend(d, {b: 2})
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
lines =<< trim END
var d: dict<number> = {a: 1}
extend(d, {b: 'x'})
END
- v9.CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<number> but got dict<string>', 2)
+ v9.CheckSourceDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<number> but got dict<string>', 2)
lines =<< trim END
var d: dict<number> = {a: 1}
g:ExtendDict(d)
END
- v9.CheckDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string', 0)
- v9.CheckScriptFailure(['vim9script'] + lines, 'E1012:', 1)
+ v9.CheckSourceDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string', 0)
+ v9.CheckSourceScriptFailure(['vim9script'] + lines, 'E1012:', 1)
lines =<< trim END
var d: dict<bool>
extend(d, {b: 0})
END
- v9.CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<bool> but got dict<number>', 2)
+ v9.CheckSourceDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<bool> but got dict<number>', 2)
enddef
func g:ExtendList(l)
@@ -1154,26 +1154,26 @@ def Test_extend_list_item_type()
var l: list<number> = [1]
extend(l, [2])
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
lines =<< trim END
var l: list<number> = [1]
extend(l, ['x'])
END
- v9.CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>', 2)
+ v9.CheckSourceDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>', 2)
lines =<< trim END
var l: list<number> = [1]
g:ExtendList(l)
END
- v9.CheckDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string', 0)
- v9.CheckScriptFailure(['vim9script'] + lines, 'E1012:', 1)
+ v9.CheckSourceDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string', 0)
+ v9.CheckSourceScriptFailure(['vim9script'] + lines, 'E1012:', 1)
lines =<< trim END
var l: list<bool>
extend(l, [0])
END
- v9.CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<bool> but got list<number>', 2)
+ v9.CheckSourceDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<bool> but got list<number>', 2)
enddef
def Test_extend_return_type()
@@ -1203,7 +1203,7 @@ def Test_extend_with_error_function()
Test()
END
- v9.CheckScriptFailure(lines, 'E1001: Variable not found: m')
+ v9.CheckSourceScriptFailure(lines, 'E1001: Variable not found: m')
enddef
def Test_extend_const()
@@ -1211,20 +1211,20 @@ def Test_extend_const()
const l = [1, 2]
extend(l, [3])
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
lines =<< trim END
const d = {a: 1, b: 2}
extend(d, {c: 3})
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>')
lines =<< trim END
final d = {a: 1, b: 2}
extend(d, {c: 3})
assert_equal({a: 1, b: 2, c: 3}, d)
END
- v9.CheckDefSuccess(lines)
+ v9.CheckSourceDefSuccess(lines)
# item in a for loop is final
lines =<< trim END
@@ -1233,23 +1233,23 @@ def Test_extend_const()
item->extend({x: 2})
endfor
END
- v9.CheckDefSuccess(lines)
+ v9.CheckSourceDefSuccess(lines)
enddef
def Test_extendnew()
assert_equal([1, 2, 'a'], extendnew([1, 2], ['a']))
assert_equal({one: 1, two: 'a'}, extendnew({one: 1}, {two: 'a'}))
- v9.CheckDefAndScriptFailure(['extendnew({a: 1}, 42)'], ['E1013: Argument 2: type mismatch, expected dict<number> but got number', 'E712: Argument of extendnew() must be a List or Dictionary'])
- v9.CheckDefAndScriptFailure(['extendnew({a: 1}, [42])'], ['E1013: Argument 2: type mismatch, expected dict<number> but got list<number>', 'E712: Argument of extendnew() must be a List or Dictionary'])
- v9.CheckDefAndScriptFailure(['extendnew([1, 2], "x")'], ['E1013: Argument 2: type mismatch, expected list<number> but got string', 'E712: Argument of extendnew() must be a List or Dictionary'])
- v9.CheckDefAndScriptFailure(['extendnew([1, 2], {x: 1})'], ['E1013: Argument 2: type mismatch, expected list<number> but got dict<number>', 'E712: Argument of extendnew() must be a List or Dictionary'])
+ v9.CheckSourceDefAndScriptFailure(['extendnew({a: 1}, 42)'], ['E1013: Argument 2: type mismatch, expected dict<number> but got number', 'E712: Argument of extendnew() must be a List or Dictionary'])
+ v9.CheckSourceDefAndScriptFailure(['extendnew({a: 1}, [42])'], ['E1013: Argument 2: type mismatch, expected dict<number> but got list<number>', 'E712: Argument of extendnew() must be a List or Dictionary'])
+ v9.CheckSourceDefAndScriptFailure(['extendnew([1, 2], "x")'], ['E1013: Argument 2: type mismatch, expected list<number> but got string', 'E712: Argument of extendnew() must be a List or Dictionary'])
+ v9.CheckSourceDefAndScriptFailure(['extendnew([1, 2], {x: 1})'], ['E1013: Argument 2: type mismatch, expected list<number> but got dict<number>', 'E712: Argument of extendnew() must be a List or Dictionary'])
enddef
def Test_feedkeys()
- v9.CheckDefAndScriptFailure(['feedkeys(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['feedkeys("x", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['feedkeys([], {})'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['feedkeys(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['feedkeys("x", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['feedkeys([], {})'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
g:TestVar = 1
feedkeys(":g:TestVar = 789\n", 'xt')
assert_equal(789, g:TestVar)
@@ -1260,16 +1260,16 @@ def Test_filereadable()
assert_false(filereadable(""))
assert_false(filereadable(test_null_string()))
- v9.CheckDefExecFailure(['echo filereadable(123)'], 'E1013:')
- v9.CheckDefExecFailure(['echo filereadable(true)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo filereadable(123)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo filereadable(true)'], 'E1013:')
enddef
def Test_filewritable()
assert_false(filewritable(""))
assert_false(filewritable(test_null_string()))
- v9.CheckDefExecFailure(['echo filewritable(123)'], 'E1013:')
- v9.CheckDefExecFailure(['echo filewritable(true)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo filewritable(123)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo filewritable(true)'], 'E1013:')
enddef
def Test_finddir()
@@ -1278,20 +1278,20 @@ def Test_finddir()
var lines =<< trim END
var l: list<string> = finddir('nothing', '*;', -1)
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
delete('Xtestdir', 'rf')
- v9.CheckDefAndScriptFailure(['finddir(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['finddir(v:null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1'])
- v9.CheckDefExecFailure(['echo finddir("")'], 'E1175:')
- v9.CheckDefAndScriptFailure(['finddir("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['finddir("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['finddir(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['finddir(v:null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefExecFailure(['echo finddir("")'], 'E1175:')
+ v9.CheckSourceDefAndScriptFailure(['finddir("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['finddir("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
finddir('abc', '')->assert_equal('')
- v9.CheckDefFailure(['var s: list<string> = finddir("foo")'], 'E1012: Type mismatch; expected list<string> but got string')
- v9.CheckDefFailure(['var s: list<string> = finddir("foo", "path")'], 'E1012: Type mismatch; expected list<string> but got string')
+ v9.CheckSourceDefFailure(['var s: list<string> = finddir("foo")'], 'E1012: Type mismatch; expected list<string> but got string')
+ v9.CheckSourceDefFailure(['var s: list<string> = finddir("foo", "path")'], 'E1012: Type mismatch; expected list<string> but got string')
# with third argument only runtime type checking
- v9.CheckDefCompileSuccess(['var s: list<string> = finddir("foo", "path", 1)'])
+ v9.CheckSourceDefCompileSuccess(['var s: list<string> = finddir("foo", "path", 1)'])
enddef
def Test_findfile()
@@ -1299,13 +1299,13 @@ def Test_findfile()
var lines =<< trim END
var l: list<string> = findfile('nothing', '*;', -1)
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
- v9.CheckDefExecFailure(['findfile(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool')
- v9.CheckDefExecFailure(['findfile(v:null)'], 'E1013: Argument 1: type mismatch, expected string but got special')
- v9.CheckDefExecFailure(['findfile("")'], 'E1175:')
- v9.CheckDefAndScriptFailure(['findfile("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['findfile("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefExecFailure(['findfile(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool')
+ v9.CheckSourceDefExecFailure(['findfile(v:null)'], 'E1013: Argument 1: type mismatch, expected string but got special')
+ v9.CheckSourceDefExecFailure(['findfile("")'], 'E1175:')
+ v9.CheckSourceDefAndScriptFailure(['findfile("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['findfile("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
findfile('abc', '')->assert_equal('')
enddef
@@ -1313,7 +1313,7 @@ def Test_flatten()
var lines =<< trim END
echo flatten([1, 2, 3])
END
- v9.CheckDefAndScriptFailure(lines, 'E1158:')
+ v9.CheckSourceDefAndScriptFailure(lines, 'E1158:')
enddef
def Test_flattennew()
@@ -1328,106 +1328,106 @@ def Test_flattennew()
var ll: list<list<string>> = [['a', 'b', 'c']]
assert_equal(['a', 'b', 'c'], ll->flattennew())
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
- v9.CheckDefAndScriptFailure(['flattennew({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['flattennew([], "1")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['flattennew({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['flattennew([], "1")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
" Test for float functions argument type
def Test_float_funcs_args()
# acos()
- v9.CheckDefAndScriptFailure(['acos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['acos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('1.570796', string(acos(0.0)))
# asin()
- v9.CheckDefAndScriptFailure(['asin("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['asin("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(asin(0.0)))
# atan()
- v9.CheckDefAndScriptFailure(['atan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['atan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(atan(0.0)))
# atan2()
- v9.CheckDefAndScriptFailure(['atan2("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['atan2("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('-2.356194', string(atan2(-1, -1)))
- v9.CheckDefAndScriptFailure(['atan2(1.2, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['atan2(1.2)'], ['E119:', 'E119:'])
+ v9.CheckSourceDefAndScriptFailure(['atan2(1.2, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['atan2(1.2)'], ['E119:', 'E119:'])
# ceil()
- v9.CheckDefAndScriptFailure(['ceil("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['ceil("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('2.0', string(ceil(2.0)))
# cos()
- v9.CheckDefAndScriptFailure(['cos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['cos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('1.0', string(cos(0.0)))
# cosh()
- v9.CheckDefAndScriptFailure(['cosh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['cosh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('1.0', string(cosh(0.0)))
# exp()
- v9.CheckDefAndScriptFailure(['exp("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['exp("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('1.0', string(exp(0.0)))
# float2nr()
- v9.CheckDefAndScriptFailure(['float2nr("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['float2nr("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal(1, float2nr(1.234))
# floor()
- v9.CheckDefAndScriptFailure(['floor("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['floor("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('2.0', string(floor(2.0)))
# fmod()
- v9.CheckDefAndScriptFailure(['fmod(1.1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['fmod("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['fmod(1.1)'], ['E119:', 'E119:'])
+ v9.CheckSourceDefAndScriptFailure(['fmod(1.1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['fmod("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['fmod(1.1)'], ['E119:', 'E119:'])
assert_equal('0.13', string(fmod(12.33, 1.22)))
# isinf()
- v9.CheckDefAndScriptFailure(['isinf("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['isinf("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal(1, isinf(1.0 / 0.0))
# isnan()
- v9.CheckDefAndScriptFailure(['isnan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['isnan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_true(isnan(0.0 / 0.0))
# log()
- v9.CheckDefAndScriptFailure(['log("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['log("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(log(1.0)))
# log10()
- v9.CheckDefAndScriptFailure(['log10("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['log10("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(log10(1.0)))
# pow()
- v9.CheckDefAndScriptFailure(['pow("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['pow(1.1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['pow(1.1)'], ['E119:', 'E119:'])
+ v9.CheckSourceDefAndScriptFailure(['pow("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['pow(1.1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['pow(1.1)'], ['E119:', 'E119:'])
assert_equal('1.0', string(pow(0.0, 0.0)))
# round()
- v9.CheckDefAndScriptFailure(['round("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['round("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('2.0', string(round(2.1)))
# sin()
- v9.CheckDefAndScriptFailure(['sin("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sin("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(sin(0.0)))
# sinh()
- v9.CheckDefAndScriptFailure(['sinh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sinh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(sinh(0.0)))
# sqrt()
- v9.CheckDefAndScriptFailure(['sqrt("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sqrt("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(sqrt(0.0)))
# tan()
- v9.CheckDefAndScriptFailure(['tan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['tan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(tan(0.0)))
# tanh()
- v9.CheckDefAndScriptFailure(['tanh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['tanh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(tanh(0.0)))
# trunc()
- v9.CheckDefAndScriptFailure(['trunc("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['trunc("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('2.0', string(trunc(2.1)))
enddef
def Test_fnameescape()
- v9.CheckDefAndScriptFailure(['fnameescape(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['fnameescape(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_equal('\+a\%b\|', fnameescape('+a%b|'))
fnameescape('')->assert_equal('')
enddef
def Test_fnamemodify()
- v9.CheckDefSuccess(['echo fnamemodify(test_null_string(), ":p")'])
- v9.CheckDefSuccess(['echo fnamemodify("", ":p")'])
- v9.CheckDefSuccess(['echo fnamemodify("file", test_null_string())'])
- v9.CheckDefSuccess(['echo fnamemodify("file", "")'])
+ v9.CheckSourceDefSuccess(['echo fnamemodify(test_null_string(), ":p")'])
+ v9.CheckSourceDefSuccess(['echo fnamemodify("", ":p")'])
+ v9.CheckSourceDefSuccess(['echo fnamemodify("file", test_null_string())'])
+ v9.CheckSourceDefSuccess(['echo fnamemodify("file", "")'])
- v9.CheckDefExecFailure(['echo fnamemodify(true, ":p")'], 'E1013: Argument 1: type mismatch, expected string but got bool')
- v9.CheckDefExecFailure(['echo fnamemodify(v:null, ":p")'], 'E1013: Argument 1: type mismatch, expected string but got special')
- v9.CheckDefExecFailure(['echo fnamemodify("file", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool')
+ v9.CheckSourceDefExecFailure(['echo fnamemodify(true, ":p")'], 'E1013: Argument 1: type mismatch, expected string but got bool')
+ v9.CheckSourceDefExecFailure(['echo fnamemodify(v:null, ":p")'], 'E1013: Argument 1: type mismatch, expected string but got special')
+ v9.CheckSourceDefExecFailure(['echo fnamemodify("file", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool')
enddef
def Wrong_dict_key_type(items: list<number>): list<number>
@@ -1454,10 +1454,10 @@ def Test_filter()
enddef
assert_equal(['xxx'], Func())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceScriptSuccess(lines)
- v9.CheckDefAndScriptFailure(['filter(1.1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got float', 'E1251: List, Dictionary, Blob or String required for argument 1'])
- v9.CheckDefAndScriptFailure(['filter([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String'])
+ v9.CheckSourceDefAndScriptFailure(['filter(1.1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got float', 'E1251: List, Dictionary, Blob or String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['filter([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String'])
lines =<< trim END
def F(i: number, v: any): string
@@ -1465,51 +1465,51 @@ def Test_filter()
enddef
echo filter([1, 2, 3], F)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool but got func(number, any): string', 'E1135: Using a String as a Bool:'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool but got func(number, any): string', 'E1135: Using a String as a Bool:'])
# check first function argument type
lines =<< trim END
var l = [1, 2, 3]
filter(l, (i: string, v: number) => true)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(string, number): bool', 'E1013: Argument 1: type mismatch, expected string but got number'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(string, number): bool', 'E1013: Argument 1: type mismatch, expected string but got number'])
lines =<< trim END
var d = {a: 1}
filter(d, (i: number, v: number) => true)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): bool but got func(number, number): bool', 'E1013: Argument 1: type mismatch, expected number but got string'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): bool but got func(number, number): bool', 'E1013: Argument 1: type mismatch, expected number but got string'])
lines =<< trim END
var b = 0z1122
filter(b, (i: string, v: number) => true)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(string, number): bool', 'E1013: Argument 1: type mismatch, expected string but got number'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(string, number): bool', 'E1013: Argument 1: type mismatch, expected string but got number'])
lines =<< trim END
var s = 'text'
filter(s, (i: string, v: string) => true)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?string): bool but got func(string, string): bool', 'E1013: Argument 1: type mismatch, expected string but got number'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?string): bool but got func(string, string): bool', 'E1013: Argument 1: type mismatch, expected string but got number'])
# check second function argument type
lines =<< trim END
var l = [1, 2, 3]
filter(l, (i: number, v: string) => true)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(number, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(number, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number'])
lines =<< trim END
var d = {a: 1}
filter(d, (i: string, v: string) => true)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): bool but got func(string, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): bool but got func(string, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number'])
lines =<< trim END
var b = 0z1122
filter(b, (i: number, v: string) => true)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(number, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(number, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number'])
lines =<< trim END
var s = 'text'
filter(s, (i: number, v: number) => true)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?string): bool but got func(number, number): bool', 'E1013: Argument 2: type mismatch, expected number but got string'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?string): bool but got func(number, number): bool', 'E1013: Argument 2: type mismatch, expected number but got string'])
enddef
def Test_filter_wrong_dict_key_type()
@@ -1536,39 +1536,39 @@ def Test_filter_const()
const l = [1, 2, 3]
filter(l, 'v:val == 2')
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
lines =<< trim END
const d = {a: 1, b: 2}
filter(d, 'v:val == 2')
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>')
enddef
def Test_foldclosed()
- v9.CheckDefAndScriptFailure(['foldclosed(function("min"))'], ['E1013: Argument 1: type mismatch, expected string but got func(...): unknown', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['foldclosed("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['foldclosed(function("min"))'], ['E1013: Argument 1: type mismatch, expected string but got func(...): unknown', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['foldclosed("")'], 'E1209: Invalid value for a line number')
assert_equal(-1, foldclosed(1))
assert_equal(-1, foldclosed('$'))
enddef
def Test_foldclosedend()
- v9.CheckDefAndScriptFailure(['foldclosedend(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['foldclosedend("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['foldclosedend(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['foldclosedend("")'], 'E1209: Invalid value for a line number')
assert_equal(-1, foldclosedend(1))
assert_equal(-1, foldclosedend('w0'))
enddef
def Test_foldlevel()
- v9.CheckDefAndScriptFailure(['foldlevel(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['foldlevel("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['foldlevel(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['foldlevel("")'], 'E1209: Invalid value for a line number')
assert_equal(0, foldlevel(1))
assert_equal(0, foldlevel('.'))
enddef
def Test_foldtextresult()
- v9.CheckDefAndScriptFailure(['foldtextresult(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['foldtextresult("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['foldtextresult(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['foldtextresult("")'], 'E1209: Invalid value for a line number')
assert_equal('', foldtextresult(1))
assert_equal('', foldtextresult('.'))
enddef
@@ -1605,8 +1605,8 @@ def Test_fullcommand()
enddef
def Test_funcref()
- v9.CheckDefAndScriptFailure(['funcref("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
- v9.CheckDefAndScriptFailure(['funcref("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['funcref("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['funcref("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
var lines =<< trim END
vim9script
@@ -1623,7 +1623,7 @@ def Test_funcref()
defcompile
GetRefOk()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceScriptSuccess(lines)
lines =<< trim END
vim9script
@@ -1635,14 +1635,14 @@ def Test_funcref()
enddef
GetRefBad()
END
- v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(bool)')
+ v9.CheckSourceScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(bool)')
enddef
def Test_function()
- v9.CheckDefExecAndScriptFailure(['function(123)'], 'E1256: String or function required for argument 1')
+ v9.CheckSourceDefExecAndScriptFailure(['function(123)'], 'E1256: String or function required for argument 1')
- v9.CheckDefAndScriptFailure(['function("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
- v9.CheckDefAndScriptFailure(['function("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['function("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['function("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
var lines =<< trim END
vim9script
@@ -1659,7 +1659,7 @@ def Test_function()
defcompile
GetRefOk()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceScriptSuccess(lines)
lines =<< trim END
vim9script
@@ -1671,17 +1671,17 @@ def Test_function()
enddef
GetRefBad()
END
- v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(bool)')
+ v9.CheckSourceScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(bool)')
enddef
def Test_garbagecollect()
garbagecollect(true)
- v9.CheckDefAndScriptFailure(['garbagecollect("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
- v9.CheckDefAndScriptFailure(['garbagecollect(20)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['garbagecollect("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['garbagecollect(20)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
enddef
def Test_get()
- v9.CheckDefAndScriptFailure(['get("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E896: Argument of get() must be a List, Dictionary or Blob'])
+ v9.CheckSourceDefAndScriptFailure(['get("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E896: Argument of get() must be a List, Dictionary or Blob'])
[3, 5, 2]->get(1)->assert_equal(5)
[3, 5, 2]->get(3)->assert_equal(0)
[3, 5, 2]->get(3, 9)->assert_equal(9)
@@ -1701,7 +1701,7 @@ def Test_get()
enddef
assert_equal(0, DoThat())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceScriptSuccess(lines)
enddef
def Test_getbufinfo()
@@ -1714,7 +1714,7 @@ def Test_getbufinfo()
getbufinfo({bufloaded: true, buflisted: true, bufmodified: false})
->len()->assert_equal(3)
bwipe Xtestfile1 Xtestfile2
- v9.CheckDefAndScriptFailure(['getbufinfo(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getbufinfo(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
enddef
def Test_getbufline()
@@ -1738,17 +1738,17 @@ def Test_getbufline()
assert_fails('getbufoneline("", "$a")', ['E1030: Using a String as a Number: "$a"', 'E1030: Using a String as a Number: "$a"'])
bwipe!
- v9.CheckDefAndScriptFailure(['getbufline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['getbufline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['getbufline("a", 2, 0z10)'], ['E1013: Argument 3: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['getbufline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getbufline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['getbufline("a", 2, 0z10)'], ['E1013: Argument 3: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['getbufoneline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['getbufoneline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['getbufoneline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getbufoneline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2'])
enddef
def Test_getbufvar()
- v9.CheckDefAndScriptFailure(['getbufvar(true, "v")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['getbufvar(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['getbufvar(true, "v")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getbufvar(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
enddef
def Test_getchangelist()
@@ -1764,21 +1764,21 @@ def Test_getchar()
endwhile
getchar(true)->assert_equal(0)
getchar(1)->assert_equal(0)
- v9.CheckDefAndScriptFailure(['getchar(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
- v9.CheckDefAndScriptFailure(['getchar("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getchar(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getchar("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
enddef
def Test_getcharpos()
assert_equal(['x', 'x', 'x', 'x'], getcharpos('.')->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['getcharpos(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['getcharpos(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['getcharpos("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['getcharpos(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getcharpos(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['getcharpos("")'], 'E1209: Invalid value for a line number')
enddef
def Test_getcharstr()
- v9.CheckDefAndScriptFailure(['getcharstr(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
- v9.CheckDefAndScriptFailure(['getcharstr("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getcharstr(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getcharstr("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
enddef
def Test_getcompletion()
@@ -1786,29 +1786,29 @@ def Test_getcompletion()
var l = getcompletion('run', 'file', true)
l->assert_equal([])
set wildignore&
- v9.CheckDefAndScriptFailure(['getcompletion(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['getcompletion("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['getcompletion("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
- v9.CheckDefExecAndScriptFailure(['getcompletion("a", "")'], 'E475: Invalid argument')
+ v9.CheckSourceDefAndScriptFailure(['getcompletion(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getcompletion("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['getcompletion("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefExecAndScriptFailure(['getcompletion("a", "")'], 'E475: Invalid argument')
getcompletion('', 'messages')->assert_equal(['clear'])
enddef
def Test_getcurpos()
assert_equal(['x', 'x', 'x', 'x', 'x'], getcurpos()->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['getcurpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getcurpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_getcursorcharpos()
assert_equal(['x', 'x', 'x', 'x', 'x'], getcursorcharpos()->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['getcursorcharpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getcursorcharpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_getcwd()
- v9.CheckDefAndScriptFailure(['getcwd("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['getcwd("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['getcwd(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['getcwd("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getcwd("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getcwd(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_getenv()
@@ -1827,7 +1827,7 @@ def Test_getenv()
enddef
def Test_getfontname()
- v9.CheckDefAndScriptFailure(['getfontname(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getfontname(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
#getfontname('')->assert_equal('')
enddef
@@ -1835,38 +1835,38 @@ def Test_getfperm()
assert_equal('', getfperm(""))
assert_equal('', getfperm(test_null_string()))
- v9.CheckDefExecFailure(['echo getfperm(true)'], 'E1013:')
- v9.CheckDefExecFailure(['echo getfperm(v:null)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo getfperm(true)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo getfperm(v:null)'], 'E1013:')
enddef
def Test_getfsize()
assert_equal(-1, getfsize(""))
assert_equal(-1, getfsize(test_null_string()))
- v9.CheckDefExecFailure(['echo getfsize(true)'], 'E1013:')
- v9.CheckDefExecFailure(['echo getfsize(v:null)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo getfsize(true)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo getfsize(v:null)'], 'E1013:')
enddef
def Test_getftime()
assert_equal(-1, getftime(""))
assert_equal(-1, getftime(test_null_string()))
- v9.CheckDefExecFailure(['echo getftime(true)'], 'E1013:')
- v9.CheckDefExecFailure(['echo getftime(v:null)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo getftime(true)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo getftime(v:null)'], 'E1013:')
enddef
def Test_getftype()
assert_equal('', getftype(""))
assert_equal('', getftype(test_null_string()))
- v9.CheckDefExecFailure(['echo getftype(true)'], 'E1013:')
- v9.CheckDefExecFailure(['echo getftype(v:null)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo getftype(true)'], 'E1013:')
+ v9.CheckSourceDefExecFailure(['echo getftype(v:null)'], 'E1013:')
enddef
def Test_getjumplist()
- v9.CheckDefAndScriptFailure(['getjumplist("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['getjumplist("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['getjumplist(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['getjumplist("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getjumplist("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getjumplist(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_getline()
@@ -1882,20 +1882,20 @@ def Test_getline()
assert_equal([3, 3, 3], getline(1, 3)->map((_, _) => 3))
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
lines =<< trim END
echo getline('1')
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1209:')
- v9.CheckDefAndScriptFailure(['getline(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['getline(1, true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['getline("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefExecAndScriptFailure(lines, 'E1209:')
+ v9.CheckSourceDefAndScriptFailure(['getline(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getline(1, true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['getline("")'], 'E1209: Invalid value for a line number')
enddef
def Test_getloclist()
- v9.CheckDefAndScriptFailure(['getloclist("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['getloclist(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['getloclist("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getloclist(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_getloclist_return_type()
@@ -1907,26 +1907,26 @@ def Test_getloclist_return_type()
enddef
def Test_getmarklist()
- v9.CheckDefAndScriptFailure(['getmarklist([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getmarklist([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
assert_equal([], getmarklist(10000))
assert_fails('getmarklist("a%b@#")', 'E94:')
enddef
def Test_getmatches()
- v9.CheckDefAndScriptFailure(['getmatches("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getmatches("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_getpos()
assert_equal(['x', 'x', 'x', 'x'], getpos('.')->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['getpos(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getpos(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_equal([0, 1, 1, 0], getpos('.'))
- v9.CheckDefExecFailure(['getpos("a")'], 'E1209:')
- v9.CheckDefExecAndScriptFailure(['getpos("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefExecFailure(['getpos("a")'], 'E1209:')
+ v9.CheckSourceDefExecAndScriptFailure(['getpos("")'], 'E1209: Invalid value for a line number')
enddef
def Test_getqflist()
- v9.CheckDefAndScriptFailure(['getqflist([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getqflist([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
call assert_equal({}, getqflist({}))
enddef
@@ -1945,9 +1945,9 @@ def Test_getreg()
assert_equal([7, 7, 7], getreg('a', true, true)->map((_, _) => 7))
assert_fails('getreg("ab")', 'E1162:')
- v9.CheckDefAndScriptFailure(['getreg(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['getreg(".", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
- v9.CheckDefAndScriptFailure(['getreg(".", 1, "b")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['getreg(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getreg(".", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['getreg(".", 1, "b")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
@" = 'A1B2C3'
getreg('')->assert_equal('A1B2C3')
enddef
@@ -1977,7 +1977,7 @@ def Test_getregtype()
enddef
def Test_getscriptinfo()
- v9.CheckDefAndScriptFailure(['getscriptinfo("x")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getscriptinfo("x")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 1'])
var lines1 =<< trim END
vim9script
@@ -2016,78 +2016,78 @@ def Test_getscriptinfo()
assert_true(index(l[0].functions, f) != -1)
endfor
END
- v9.CheckDefAndScriptSuccess(lines2)
+ v9.CheckSourceDefAndScriptSuccess(lines2)
enddef
def Test_gettabinfo()
- v9.CheckDefAndScriptFailure(['gettabinfo("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['gettabinfo("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_gettabvar()
- v9.CheckDefAndScriptFailure(['gettabvar("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['gettabvar(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['gettabvar("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['gettabvar(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
enddef
def Test_gettabwinvar()
- v9.CheckDefAndScriptFailure(['gettabwinvar("a", 2, "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['gettabwinvar(1, "b", "c", [])'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['gettabwinvar(1, 1, 3, {})'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['gettabwinvar("a", 2, "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['gettabwinvar(1, "b", "c", [])'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['gettabwinvar(1, 1, 3, {})'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
enddef
def Test_gettagstack()
- v9.CheckDefAndScriptFailure(['gettagstack("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['gettagstack("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_gettext()
- v9.CheckDefAndScriptFailure(['gettext(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['gettext("")'], 'E1175: Non-empty string required for argument 1')
+ v9.CheckSourceDefAndScriptFailure(['gettext(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['gettext("")'], 'E1175: Non-empty string required for argument 1')
assert_equal('abc', gettext("abc"))
assert_fails('gettext("")', 'E1175:')
enddef
def Test_getwininfo()
- v9.CheckDefAndScriptFailure(['getwininfo("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getwininfo("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_getwinpos()
assert_equal(['x', 'x'], getwinpos()->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['getwinpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getwinpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_getwinvar()
- v9.CheckDefAndScriptFailure(['getwinvar("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['getwinvar(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['getwinvar("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getwinvar(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
enddef
def Test_glob()
glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim'])
- v9.CheckDefAndScriptFailure(['glob(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['glob("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
- v9.CheckDefAndScriptFailure(['glob("a", 1, "b")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
- v9.CheckDefAndScriptFailure(['glob("a", 1, true, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['glob(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['glob("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['glob("a", 1, "b")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['glob("a", 1, true, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4'])
glob('')->assert_equal('')
enddef
def Test_glob2regpat()
- v9.CheckDefAndScriptFailure(['glob2regpat(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['glob2regpat(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1'])
glob2regpat('')->assert_equal('^$')
enddef
def Test_globpath()
globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim'])
- v9.CheckDefAndScriptFailure(['globpath(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['globpath("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['globpath("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
- v9.CheckDefAndScriptFailure(['globpath("a", "b", true, "d")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4'])
- v9.CheckDefAndScriptFailure(['globpath("a", "b", true, false, "e")'], ['E1013: Argument 5: type mismatch, expected bool but got string', 'E1212: Bool required for argument 5'])
+ v9.CheckSourceDefAndScriptFailure(['globpath(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['globpath("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['globpath("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['globpath("a", "b", true, "d")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['globpath("a", "b", true, false, "e")'], ['E1013: Argument 5: type mismatch, expected bool but got string', 'E1212: Bool required for argument 5'])
globpath('', '')->assert_equal('')
enddef
def Test_has()
has('eval', true)->assert_equal(1)
- v9.CheckDefAndScriptFailure(['has(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['has("a", "b")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['has(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['has("a", "b")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2'])
has('')->assert_equal(0)
enddef
@@ -2098,14 +2098,14 @@ def Test_has_key()
assert_false(has_key(d, 'x'))
assert_false(has_key(d, 99))
- v9.CheckDefAndScriptFailure(['has_key([1, 2], "k")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1'])
- v9.CheckDefAndScriptFailure(['has_key({"a": 10}, ["a"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['has_key([1, 2], "k")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['has_key({"a": 10}, ["a"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 2'])
enddef
def Test_haslocaldir()
- v9.CheckDefAndScriptFailure(['haslocaldir("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['haslocaldir("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['haslocaldir(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['haslocaldir("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['haslocaldir("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['haslocaldir(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_hasmapto()
@@ -2113,81 +2113,81 @@ def Test_hasmapto()
iabbrev foo foobar
hasmapto('foobar', 'i', true)->assert_equal(1)
iunabbrev foo
- v9.CheckDefAndScriptFailure(['hasmapto(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['hasmapto("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['hasmapto("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['hasmapto(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['hasmapto("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['hasmapto("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
hasmapto('', '')->assert_equal(0)
enddef
def Test_histadd()
- v9.CheckDefAndScriptFailure(['histadd(1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['histadd(":", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['histadd(1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['histadd(":", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
histadd("search", 'skyblue')
assert_equal('skyblue', histget('/', -1))
histadd("search", '')->assert_equal(0)
enddef
def Test_histdel()
- v9.CheckDefAndScriptFailure(['histdel(1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['histdel(":", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['histdel(1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['histdel(":", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2'])
histdel('search', '')->assert_equal(0)
enddef
def Test_histget()
- v9.CheckDefAndScriptFailure(['histget(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['histget("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['histget(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['histget("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_histnr()
- v9.CheckDefAndScriptFailure(['histnr(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['histnr(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_equal(-1, histnr('abc'))
enddef
def Test_hlID()
- v9.CheckDefAndScriptFailure(['hlID(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['hlID(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_equal(0, hlID('NonExistingHighlight'))
hlID('')->assert_equal(0)
enddef
def Test_hlexists()
- v9.CheckDefAndScriptFailure(['hlexists([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['hlexists([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
assert_equal(0, hlexists('NonExistingHighlight'))
hlexists('')->assert_equal(0)
enddef
def Test_hlget()
- v9.CheckDefAndScriptFailure(['hlget([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['hlget([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
hlget('')->assert_equal([])
enddef
def Test_hlset()
- v9.CheckDefAndScriptFailure(['hlset("id")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['hlset("id")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
hlset([])->assert_equal(0)
enddef
def Test_iconv()
- v9.CheckDefAndScriptFailure(['iconv(1, "from", "to")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['iconv("abc", 10, "to")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['iconv("abc", "from", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['iconv(1, "from", "to")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['iconv("abc", 10, "to")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['iconv("abc", "from", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
assert_equal('abc', iconv('abc', 'fromenc', 'toenc'))
iconv('', '', '')->assert_equal('')
enddef
def Test_indent()
- v9.CheckDefAndScriptFailure(['indent([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['indent(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['indent("")'], 'E1209: Invalid value for a line number')
- v9.CheckDefExecAndScriptFailure(['indent(-1)'], 'E966: Invalid line number: -1')
+ v9.CheckSourceDefAndScriptFailure(['indent([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['indent(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['indent("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefExecAndScriptFailure(['indent(-1)'], 'E966: Invalid line number: -1')
assert_equal(0, indent(1))
enddef
def Test_index()
index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3)
- v9.CheckDefAndScriptFailure(['index("a", "a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1226: List or Blob required for argument 1'])
- v9.CheckDefFailure(['index(["1"], 1)'], 'E1013: Argument 2: type mismatch, expected string but got number')
- v9.CheckDefAndScriptFailure(['index(0z10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['index([1], 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['index(0z1020, 10, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['index("a", "a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1226: List or Blob required for argument 1'])
+ v9.CheckSourceDefFailure(['index(["1"], 1)'], 'E1013: Argument 2: type mismatch, expected string but got number')
+ v9.CheckSourceDefAndScriptFailure(['index(0z10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['index([1], 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['index(0z1020, 10, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4'])
enddef
def Test_indexof()
@@ -2210,7 +2210,7 @@ def Test_indexof()
indexof([{color: "red"}], TestIdx)
END
- v9.CheckDefAndScriptFailure(lines, ['E176: Invalid number of arguments', 'E118: Too many arguments for function'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E176: Invalid number of arguments', 'E118: Too many arguments for function'])
lines =<< trim END
def TestIdx(k: number, v: dict<any>)
@@ -2218,7 +2218,7 @@ def Test_indexof()
indexof([{color: "red"}], TestIdx)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool', 'E1031: Cannot use void value'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool', 'E1031: Cannot use void value'])
lines =<< trim END
def TestIdx(k: number, v: dict<any>): string
@@ -2227,35 +2227,35 @@ def Test_indexof()
indexof([{color: "red"}], TestIdx)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool', 'E1135: Using a String as a Bool'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool', 'E1135: Using a String as a Bool'])
enddef
def Test_input()
- v9.CheckDefAndScriptFailure(['input(5)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['input(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['input("p", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['input("p", "q", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['input(5)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['input(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['input("p", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['input("p", "q", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
enddef
def Test_inputdialog()
- v9.CheckDefAndScriptFailure(['inputdialog(5)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['inputdialog(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['inputdialog("p", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['inputdialog("p", "q", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['inputdialog(5)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['inputdialog(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['inputdialog("p", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['inputdialog("p", "q", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
enddef
def Test_inputlist()
- v9.CheckDefAndScriptFailure(['inputlist(10)'], ['E1013: Argument 1: type mismatch, expected list<string> but got number', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['inputlist("abc")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1211: List required for argument 1'])
- v9.CheckDefFailure(['inputlist([1, 2, 3])'], 'E1013: Argument 1: type mismatch, expected list<string> but got list<number>')
+ v9.CheckSourceDefAndScriptFailure(['inputlist(10)'], ['E1013: Argument 1: type mismatch, expected list<string> but got number', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['inputlist("abc")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefFailure(['inputlist([1, 2, 3])'], 'E1013: Argument 1: type mismatch, expected list<string> but got list<number>')
feedkeys("2\<CR>", 't')
var r: number = inputlist(['a', 'b', 'c'])
assert_equal(2, r)
enddef
def Test_inputsecret()
- v9.CheckDefAndScriptFailure(['inputsecret(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['inputsecret("Pass:", 20)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['inputsecret(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['inputsecret("Pass:", 20)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
feedkeys("\<CR>", 't')
var ans: string = inputsecret('Pass:', '123')
assert_equal('123', ans)
@@ -2282,12 +2282,12 @@ def Test_insert()
var lines =<< trim END
insert(test_null_list(), 123)
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1130:', 1)
+ v9.CheckSourceDefExecAndScriptFailure(lines, 'E1130:', 1)
lines =<< trim END
insert(test_null_blob(), 123)
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1131:', 1)
+ v9.CheckSourceDefExecAndScriptFailure(lines, 'E1131:', 1)
assert_equal([1, 2, 3], insert([2, 3], 1))
assert_equal([1, 2, 3], insert([2, 3], number_one))
@@ -2296,9 +2296,9 @@ def Test_insert()
assert_equal(['a', 'b', 'c'], insert(['b', 'c'], 'a'))
assert_equal(0z1234, insert(0z34, 0x12))
- v9.CheckDefAndScriptFailure(['insert("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1226: List or Blob required for argument 1'])
- v9.CheckDefFailure(['insert([2, 3], "a")'], 'E1013: Argument 2: type mismatch, expected number but got string')
- v9.CheckDefAndScriptFailure(['insert([2, 3], 1, "x")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['insert("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1226: List or Blob required for argument 1'])
+ v9.CheckSourceDefFailure(['insert([2, 3], "a")'], 'E1013: Argument 2: type mismatch, expected number but got string')
+ v9.CheckSourceDefAndScriptFailure(['insert([2, 3], 1, "x")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
enddef
def Test_instanceof()
@@ -2308,7 +2308,7 @@ def Test_instanceof()
endclass
instanceof('hello', Foo)
END
- v9.CheckScriptFailure(lines, 'E616: Object required for argument 1')
+ v9.CheckSourceScriptFailure(lines, 'E616: Object required for argument 1')
lines =<< trim END
vim9script
@@ -2316,7 +2316,7 @@ def Test_instanceof()
endclass
instanceof(Foo.new(), 123)
END
- v9.CheckScriptFailure(lines, 'E693: Class or class typealias required for argument 2')
+ v9.CheckSourceScriptFailure(lines, 'E693: Class or class typealias required for argument 2')
lines =<< trim END
vim9script
@@ -2327,7 +2327,7 @@ def Test_instanceof()
enddef
Bar()
END
- v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected object<Unknown> but got string')
+ v9.CheckSourceScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected object<Unknown> but got string')
lines =<< trim END
vim9script
@@ -2338,7 +2338,7 @@ def Test_instanceof()
enddef
Bar()
END
- v9.CheckScriptFailure(lines, 'E693: Class or class typealias required for argument 2')
+ v9.CheckSourceScriptFailure(lines, 'E693: Class or class typealias required for argument 2')
lines =<< trim END
vim9script
@@ -2346,7 +2346,7 @@ def Test_instanceof()
endclass
instanceof(Foo.new(), [{}])
END
- v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 2')
+ v9.CheckSourceScriptFailure(lines, 'E693: Class or class typealias required for argument 2')
lines =<< trim END
vim9script
@@ -2357,22 +2357,22 @@ def Test_instanceof()
enddef
Bar()
END
- v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 2')
+ v9.CheckSourceScriptFailure(lines, 'E693: Class or class typealias required for argument 2')
enddef
def Test_invert()
- v9.CheckDefAndScriptFailure(['invert("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['invert("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_isdirectory()
- v9.CheckDefAndScriptFailure(['isdirectory(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['isdirectory(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1'])
assert_false(isdirectory('NonExistingDir'))
assert_false(isdirectory(''))
enddef
def Test_islocked()
- v9.CheckDefAndScriptFailure(['islocked(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['var n1: number = 10', 'islocked(n1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['islocked(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['var n1: number = 10', 'islocked(n1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
g:v1 = 10
assert_false(islocked('g:v1'))
lockvar g:v1
@@ -2382,7 +2382,7 @@ def Test_islocked()
enddef
def Test_items()
- v9.CheckDefFailure(['123->items()'], 'E1225:')
+ v9.CheckSourceDefFailure(['123->items()'], 'E1225:')
assert_equal([['a', 10], ['b', 20]], {'a': 10, 'b': 20}->items())
assert_equal([], {}->items())
assert_equal(['x', 'x'], {'a': 10, 'b': 20}->items()->map((_, _) => 'x'))
@@ -2400,7 +2400,7 @@ def Test_job_getchannel()
if !has('job')
CheckFeature job
else
- v9.CheckDefAndScriptFailure(['job_getchannel("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['job_getchannel("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1'])
assert_fails('job_getchannel(test_null_job())', 'E916: Not a valid job')
endif
enddef
@@ -2409,7 +2409,7 @@ def Test_job_info()
if !has('job')
CheckFeature job
else
- v9.CheckDefAndScriptFailure(['job_info("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['job_info("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1'])
assert_fails('job_info(test_null_job())', 'E916: Not a valid job')
endif
enddef
@@ -2420,8 +2420,8 @@ def Test_job_setoptions()
if !has('job')
CheckFeature job
else
- v9.CheckDefAndScriptFailure(['job_setoptions(test_null_channel(), {})'], ['E1013: Argument 1: type mismatch, expected job but got channel', 'E1218: Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['job_setoptions(test_null_job(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['job_setoptions(test_null_channel(), {})'], ['E1013: Argument 1: type mismatch, expected job but got channel', 'E1218: Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['job_setoptions(test_null_job(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
assert_equal('fail', job_status(test_null_job()))
endif
enddef
@@ -2430,7 +2430,7 @@ def Test_job_status()
if !has('job')
CheckFeature job
else
- v9.CheckDefAndScriptFailure(['job_status("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['job_status("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1'])
assert_equal('fail', job_status(test_null_job()))
endif
enddef
@@ -2439,25 +2439,25 @@ def Test_job_stop()
if !has('job')
CheckFeature job
else
- v9.CheckDefAndScriptFailure(['job_stop("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1'])
- v9.CheckDefAndScriptFailure(['job_stop(test_null_job(), true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['job_stop("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['job_stop(test_null_job(), true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2'])
endif
enddef
def Test_join()
- v9.CheckDefAndScriptFailure(['join("abc")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['join([], 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['join("abc")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['join([], 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
join([''], '')->assert_equal('')
enddef
def Test_js_decode()
- v9.CheckDefAndScriptFailure(['js_decode(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['js_decode(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_equal([1, 2], js_decode('[1,2]'))
js_decode('')->assert_equal(v:none)
enddef
def Test_json_decode()
- v9.CheckDefAndScriptFailure(['json_decode(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['json_decode(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1'])
assert_equal(1.0, json_decode('1.0'))
json_decode('')->assert_equal(v:none)
enddef
@@ -2465,7 +2465,7 @@ enddef
def Test_keys()
assert_equal([7, 7], keys({a: 1, b: 2})->map((_, _) => 7))
- v9.CheckDefAndScriptFailure(['keys([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['keys([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
assert_equal(['a'], {a: 'v'}->keys())
assert_equal([], {}->keys())
enddef
@@ -2476,7 +2476,7 @@ def Test_keys_return_type()
enddef
def Test_len()
- v9.CheckDefAndScriptFailure(['len(true)'], ['E1013: Argument 1: type mismatch, expected list<any> but got bool', 'E701: Invalid type for len()'])
+ v9.CheckSourceDefAndScriptFailure(['len(true)'], ['E1013: Argument 1: type mismatch, expected list<any> but got bool', 'E701: Invalid type for len()'])
assert_equal(2, "ab"->len())
assert_equal(3, 456->len())
assert_equal(0, []->len())
@@ -2486,42 +2486,42 @@ enddef
def Test_libcall()
CheckFeature libcall
- v9.CheckDefAndScriptFailure(['libcall(1, "b", 3)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['libcall("a", 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['libcall("a", "b", 1.1)'], ['E1013: Argument 3: type mismatch, expected string but got float', 'E1220: String or Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['libcall(1, "b", 3)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['libcall("a", 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['libcall("a", "b", 1.1)'], ['E1013: Argument 3: type mismatch, expected string but got float', 'E1220: String or Number required for argument 3'])
enddef
def Test_libcallnr()
CheckFeature libcall
- v9.CheckDefAndScriptFailure(['libcallnr(1, "b", 3)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['libcallnr("a", 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['libcallnr("a", "b", 1.1)'], ['E1013: Argument 3: type mismatch, expected string but got float', 'E1220: String or Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['libcallnr(1, "b", 3)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['libcallnr("a", 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['libcallnr("a", "b", 1.1)'], ['E1013: Argument 3: type mismatch, expected string but got float', 'E1220: String or Number required for argument 3'])
enddef
def Test_line()
assert_fails('line(true)', 'E1174:')
- v9.CheckDefAndScriptFailure(['line(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['line(".", "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['line("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['line(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['line(".", "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['line("")'], 'E1209: Invalid value for a line number')
enddef
def Test_line2byte()
- v9.CheckDefAndScriptFailure(['line2byte(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['line2byte("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['line2byte(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['line2byte("")'], 'E1209: Invalid value for a line number')
assert_equal(-1, line2byte(1))
assert_equal(-1, line2byte(10000))
enddef
def Test_lispindent()
- v9.CheckDefAndScriptFailure(['lispindent({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['lispindent("")'], 'E1209: Invalid value for a line number')
- v9.CheckDefExecAndScriptFailure(['lispindent(-1)'], 'E966: Invalid line number: -1')
+ v9.CheckSourceDefAndScriptFailure(['lispindent({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['lispindent("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefExecAndScriptFailure(['lispindent(-1)'], 'E966: Invalid line number: -1')
assert_equal(0, lispindent(1))
enddef
def Test_list2blob()
- v9.CheckDefAndScriptFailure(['list2blob(10)'], ['E1013: Argument 1: type mismatch, expected list<number> but got number', 'E1211: List required for argument 1'])
- v9.CheckDefFailure(['list2blob([0z10, 0z02])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<blob>')
+ v9.CheckSourceDefAndScriptFailure(['list2blob(10)'], ['E1013: Argument 1: type mismatch, expected list<number> but got number', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefFailure(['list2blob([0z10, 0z02])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<blob>')
enddef
def Test_list2str_str2list_utf8()
@@ -2532,8 +2532,8 @@ def Test_list2str_str2list_utf8()
enddef
def Test_list2str()
- v9.CheckDefAndScriptFailure(['list2str(".", true)'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['list2str([1], 0z10)'], ['E1013: Argument 2: type mismatch, expected bool but got blob', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['list2str(".", true)'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['list2str([1], 0z10)'], ['E1013: Argument 2: type mismatch, expected bool but got blob', 'E1212: Bool required for argument 2'])
enddef
def s:SID(): number
@@ -2543,22 +2543,22 @@ def s:SID(): number
enddef
def Test_listener_add()
- v9.CheckDefAndScriptFailure(['listener_add("1", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['listener_add("1", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2'])
enddef
def Test_listener_flush()
- v9.CheckDefAndScriptFailure(['listener_flush([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['listener_flush([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
enddef
def Test_listener_remove()
- v9.CheckDefAndScriptFailure(['listener_remove("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['listener_remove("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_luaeval()
if !has('lua')
CheckFeature lua
endif
- v9.CheckDefAndScriptFailure(['luaeval(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['luaeval(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
if exists_compiled('*luaeval')
luaeval('')->assert_equal(v:null)
endif
@@ -2566,10 +2566,10 @@ enddef
def Test_map()
if has('channel')
- v9.CheckDefAndScriptFailure(['map(test_null_channel(), "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got channel', 'E1251: List, Dictionary, Blob or String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['map(test_null_channel(), "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got channel', 'E1251: List, Dictionary, Blob or String required for argument 1'])
endif
- v9.CheckDefAndScriptFailure(['map(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1'])
- v9.CheckDefAndScriptFailure(['map([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String'])
+ v9.CheckSourceDefAndScriptFailure(['map(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['map([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String'])
# type of dict remains dict<any> even when type of values changes
# same for list
@@ -2599,7 +2599,7 @@ def Test_map()
assert_equal({a: 'x'}, {a: [1, 2]}->map((_, v) => 'x'))
assert_equal({a: 'x'}, {a: {b: 2}}->map((_, v) => 'x'))
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
enddef
def Test_map_failure()
@@ -2627,7 +2627,7 @@ def Test_map_failure()
g:gd = d
map(g:gd, (k, v) => true)
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got bool')
+ v9.CheckSourceDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got bool')
enddef
def Test_map_const()
@@ -2635,13 +2635,13 @@ def Test_map_const()
const l = [1, 2, 3]
map(l, 'SomeFunc')
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
lines =<< trim END
const d = {a: 1, b: 2}
map(d, 'SomeFunc')
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>')
enddef
def Test_map_function_arg()
@@ -2653,16 +2653,16 @@ def Test_map_function_arg()
map(l, MapOne)
assert_equal(['0:a', '1:b', '2:c'], l)
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
lines =<< trim END
range(3)->map((a, b, c) => a + b + c)
END
- v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1190: One argument too few'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E176:', 'E1190: One argument too few'])
lines =<< trim END
range(3)->map((a, b, c, d) => a + b + c + d)
END
- v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1190: 2 arguments too few'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E176:', 'E1190: 2 arguments too few'])
# declared list cannot change type
lines =<< trim END
@@ -2672,7 +2672,7 @@ def Test_map_function_arg()
var ll: list<number> = [1, 2, 3]
echo map(ll, Map)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, number): string', 'E1012: Type mismatch; expected number but got string'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, number): string', 'E1012: Type mismatch; expected number but got string'])
# not declared list can change type
echo [1, 2, 3]->map((..._) => 'x')
@@ -2684,25 +2684,25 @@ def Test_map_item_type()
map(l, (k, v) => k .. '/' .. v )
assert_equal(['0/a', '1/b', '2/c'], l)
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
lines =<< trim END
var l: list<number> = [0]
echo map(l, (_, v) => [])
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2)
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2)
lines =<< trim END
var l: list<number> = range(2)
echo map(l, (_, v) => [])
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2)
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2)
lines =<< trim END
var d: dict<number> = {key: 0}
echo map(d, (_, v) => [])
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2)
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2)
enddef
def Test_maparg()
@@ -2725,10 +2725,10 @@ def Test_maparg()
abbr: 0,
mode_bits: 0x47})
unmap foo
- v9.CheckDefAndScriptFailure(['maparg(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['maparg("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['maparg("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
- v9.CheckDefAndScriptFailure(['maparg("a", "b", true, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['maparg(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['maparg("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['maparg("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['maparg("a", "b", true, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4'])
maparg('')->assert_equal('')
# value argument type is checked at compile time
@@ -2736,46 +2736,46 @@ def Test_maparg()
var l = [123]
l->map((i: number, v: string) => 0)
END
- v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, string): number')
+ v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, string): number')
lines =<< trim END
var d = {a: 123}
d->map((i: string, v: string) => 0)
END
- v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?string, ?number): number but got func(string, string): number')
+ v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?string, ?number): number but got func(string, string): number')
lines =<< trim END
var s = 'abc'
s->map((i: number, v: number) => 'x')
END
- v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?string): string but got func(number, number): string')
+ v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?string): string but got func(number, number): string')
lines =<< trim END
var s = 0z1122
s->map((i: number, v: string) => 0)
END
- v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, string): number')
+ v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, string): number')
# index argument type is checked at compile time
lines =<< trim END
['x']->map((i: string, v: string) => 'y')
END
- v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?any): any but got func(string, string): string')
+ v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?any): any but got func(string, string): string')
lines =<< trim END
{a: 1}->map((i: number, v: number) => 0)
END
- v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?string, ?any): any but got func(number, number): number')
+ v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?string, ?any): any but got func(number, number): number')
lines =<< trim END
'abc'->map((i: string, v: string) => 'x')
END
- v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?string): string but got func(string, string): string')
+ v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?string): string but got func(string, string): string')
lines =<< trim END
0z1122->map((i: string, v: number) => 0)
END
- v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(string, number): number')
+ v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(string, number): number')
enddef
def Test_maparg_mapset()
@@ -2790,31 +2790,31 @@ def Test_mapcheck()
iabbrev foo foobar
mapcheck('foo', 'i', true)->assert_equal('foobar')
iunabbrev foo
- v9.CheckDefAndScriptFailure(['mapcheck(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['mapcheck("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['mapcheck("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['mapcheck(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['mapcheck("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['mapcheck("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
mapcheck('')->assert_equal('')
mapcheck('', '')->assert_equal('')
enddef
def Test_mapnew()
if has('channel')
- v9.CheckDefAndScriptFailure(['mapnew(test_null_job(), "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got job', 'E1251: List, Dictionary, Blob or String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['mapnew(test_null_job(), "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got job', 'E1251: List, Dictionary, Blob or String required for argument 1'])
endif
- v9.CheckDefAndScriptFailure(['mapnew(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['mapnew(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1'])
enddef
def Test_mapset()
- v9.CheckDefAndScriptFailure(['mapset(1, true, {})'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1223: String or Dictionary required for argument 1'])
- v9.CheckDefAndScriptFailure(['mapset("a", 2, {})'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
- v9.CheckDefAndScriptFailure(['mapset("a", false, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['mapset(1, true, {})'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1223: String or Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['mapset("a", 2, {})'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['mapset("a", false, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
enddef
def Test_match()
- v9.CheckDefAndScriptFailure(['match(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['match(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['match("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['match("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['match(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['match(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['match("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['match("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
assert_equal(2, match('ab12cd', '12'))
assert_equal(-1, match('ab12cd', '34'))
assert_equal(6, match('ab12cd12ef', '12', 4))
@@ -2829,39 +2829,39 @@ def Test_match()
enddef
def Test_matchadd()
- v9.CheckDefAndScriptFailure(['matchadd(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['matchadd("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['matchadd("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['matchadd("a", "b", 1, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
- v9.CheckDefAndScriptFailure(['matchadd("a", "b", 1, 1, [])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 5'])
+ v9.CheckSourceDefAndScriptFailure(['matchadd(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matchadd("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['matchadd("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['matchadd("a", "b", 1, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['matchadd("a", "b", 1, 1, [])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 5'])
matchadd('', 'a')->assert_equal(-1)
matchadd('Search', '')->assert_equal(-1)
enddef
def Test_matchaddpos()
- v9.CheckDefAndScriptFailure(['matchaddpos(1, [1])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['matchaddpos("a", "b")'], ['E1013: Argument 2: type mismatch, expected list<any> but got string', 'E1211: List required for argument 2'])
- v9.CheckDefAndScriptFailure(['matchaddpos("a", [1], "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['matchaddpos("a", [1], 1, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
- v9.CheckDefAndScriptFailure(['matchaddpos("a", [1], 1, 1, [])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 5'])
+ v9.CheckSourceDefAndScriptFailure(['matchaddpos(1, [1])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matchaddpos("a", "b")'], ['E1013: Argument 2: type mismatch, expected list<any> but got string', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['matchaddpos("a", [1], "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['matchaddpos("a", [1], 1, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['matchaddpos("a", [1], 1, 1, [])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 5'])
matchaddpos('', [1])->assert_equal(-1)
enddef
def Test_matcharg()
- v9.CheckDefAndScriptFailure(['matcharg("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matcharg("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_matchdelete()
- v9.CheckDefAndScriptFailure(['matchdelete("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['matchdelete("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['matchdelete(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['matchdelete("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matchdelete("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matchdelete(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_matchend()
- v9.CheckDefAndScriptFailure(['matchend(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['matchend(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['matchend("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['matchend("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['matchend(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matchend(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['matchend("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['matchend("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
assert_equal(4, matchend('ab12cd', '12'))
assert_equal(-1, matchend('ab12cd', '34'))
assert_equal(8, matchend('ab12cd12ef', '12', 4))
@@ -2876,9 +2876,9 @@ def Test_matchend()
enddef
def Test_matchfuzzy()
- v9.CheckDefAndScriptFailure(['matchfuzzy({}, "p")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['matchfuzzy([], 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['matchfuzzy([], "a", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['matchfuzzy({}, "p")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matchfuzzy([], 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['matchfuzzy([], "a", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
matchfuzzy(['abc', 'xyz'], '')->assert_equal([])
var lines =<< trim END
var items = [{name: 'xyz', id: 1}, {name: 'def', id: 2},
@@ -2888,13 +2888,13 @@ def Test_matchfuzzy()
var k: list<string> = matchfuzzy(['one', 'two', 'who'], 'o')
assert_equal(['one', 'two', 'who'], k)
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
enddef
def Test_matchfuzzypos()
- v9.CheckDefAndScriptFailure(['matchfuzzypos({}, "p")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['matchfuzzypos([], 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['matchfuzzypos([], "a", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['matchfuzzypos({}, "p")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matchfuzzypos([], 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['matchfuzzypos([], "a", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
matchfuzzypos(['abc', 'xyz'], '')->assert_equal([[], [], []])
var lines =<< trim END
var items = [{name: 'xyz', id: 1}, {name: 'def', id: 2},
@@ -2904,14 +2904,14 @@ def Test_matchfuzzypos()
var k: list<string> = matchfuzzypos(['one', 'two', 'who'], 'o')[0]
assert_equal(['one', 'two', 'who'], k)
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
enddef
def Test_matchlist()
- v9.CheckDefAndScriptFailure(['matchlist(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['matchlist(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['matchlist("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['matchlist("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['matchlist(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matchlist(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['matchlist("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['matchlist("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
var l: list<string> = ['12', '', '', '', '', '', '', '', '', '']
assert_equal(l, matchlist('ab12cd', '12'))
assert_equal([], matchlist('ab12cd', '34'))
@@ -2929,10 +2929,10 @@ def Test_matchlist()
enddef
def Test_matchstr()
- v9.CheckDefAndScriptFailure(['matchstr(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['matchstr(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['matchstr("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['matchstr("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['matchstr(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matchstr(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['matchstr("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['matchstr("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
assert_equal('12', matchstr('ab12cd', '12'))
assert_equal('', matchstr('ab12cd', '34'))
assert_equal('12', matchstr('ab12cd12ef', '12', 4))
@@ -2947,10 +2947,10 @@ def Test_matchstr()
enddef
def Test_matchstrpos()
- v9.CheckDefAndScriptFailure(['matchstrpos(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['matchstrpos(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['matchstrpos("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['matchstrpos("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['matchstrpos(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['matchstrpos(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['matchstrpos("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['matchstrpos("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
assert_equal(['12', 2, 4], matchstrpos('ab12cd', '12'))
assert_equal(['', -1, -1], matchstrpos('ab12cd', '34'))
assert_equal(['12', 6, 8], matchstrpos('ab12cd12ef', '12', 4))
@@ -2978,13 +2978,13 @@ def Test_max()
? [1, max([2, 3])]
: [4, 5]
assert_equal([4, 5], l2)
- v9.CheckDefAndScriptFailure(['max(5)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1227: List or Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['max(5)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1227: List or Dictionary required for argument 1'])
enddef
def Test_menu_info()
- v9.CheckDefAndScriptFailure(['menu_info(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['menu_info(10, "n")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['menu_info("File", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['menu_info(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['menu_info(10, "n")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['menu_info("File", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
assert_equal({}, menu_info('aMenu'))
enddef
@@ -3000,49 +3000,49 @@ def Test_min()
? [1, min([2, 3])]
: [4, 5]
assert_equal([4, 5], l2)
- v9.CheckDefAndScriptFailure(['min(5)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1227: List or Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['min(5)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1227: List or Dictionary required for argument 1'])
enddef
def Test_mkdir()
- v9.CheckDefAndScriptFailure(['mkdir(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['mkdir("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['mkdir("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefExecAndScriptFailure(['mkdir("")'], 'E1175: Non-empty string required for argument 1')
+ v9.CheckSourceDefAndScriptFailure(['mkdir(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['mkdir("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['mkdir("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefExecAndScriptFailure(['mkdir("")'], 'E1175: Non-empty string required for argument 1')
delete('a', 'rf')
enddef
def Test_mode()
- v9.CheckDefAndScriptFailure(['mode("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
- v9.CheckDefAndScriptFailure(['mode(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['mode("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['mode(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
enddef
def Test_mzeval()
if !has('mzscheme')
CheckFeature mzscheme
endif
- v9.CheckDefAndScriptFailure(['mzeval(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['mzeval(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
enddef
def Test_nextnonblank()
- v9.CheckDefAndScriptFailure(['nextnonblank(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['nextnonblank("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['nextnonblank(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['nextnonblank("")'], 'E1209: Invalid value for a line number')
assert_equal(0, nextnonblank(1))
enddef
def Test_nr2char()
nr2char(97, true)->assert_equal('a')
- v9.CheckDefAndScriptFailure(['nr2char("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['nr2char(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['nr2char("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['nr2char(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2'])
enddef
def Test_or()
- v9.CheckDefAndScriptFailure(['or("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['or(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['or("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['or(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_pathshorten()
- v9.CheckDefAndScriptFailure(['pathshorten(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['pathshorten("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['pathshorten(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['pathshorten("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
pathshorten('')->assert_equal('')
enddef
@@ -3050,12 +3050,12 @@ def Test_perleval()
if !has('perl')
CheckFeature perl
endif
- v9.CheckDefAndScriptFailure(['perleval(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['perleval(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
enddef
def Test_popup_atcursor()
- v9.CheckDefAndScriptFailure(['popup_atcursor({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_atcursor("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_atcursor({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_atcursor("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
# Pass variable of type 'any' to popup_atcursor()
var what: any = 'Hello'
@@ -3065,17 +3065,17 @@ def Test_popup_atcursor()
enddef
def Test_popup_beval()
- v9.CheckDefAndScriptFailure(['popup_beval({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_beval("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_beval({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_beval("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_popup_clear()
- v9.CheckDefAndScriptFailure(['popup_clear(["a"])'], ['E1013: Argument 1: type mismatch, expected bool but got list<string>', 'E1212: Bool required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_clear(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_clear(["a"])'], ['E1013: Argument 1: type mismatch, expected bool but got list<string>', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_clear(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
enddef
def Test_popup_close()
- v9.CheckDefAndScriptFailure(['popup_close("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_close("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_popup_create()
@@ -3087,81 +3087,81 @@ def Test_popup_create()
enddef
def Test_popup_dialog()
- v9.CheckDefAndScriptFailure(['popup_dialog({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_dialog("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_dialog({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_dialog("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_popup_filter_menu()
- v9.CheckDefAndScriptFailure(['popup_filter_menu("x", "")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_filter_menu(1, 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_filter_menu("x", "")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_filter_menu(1, 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
var id: number = popup_menu(["one", "two", "three"], {})
popup_filter_menu(id, '')
popup_close(id)
enddef
def Test_popup_filter_yesno()
- v9.CheckDefAndScriptFailure(['popup_filter_yesno("x", "")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_filter_yesno(1, 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_filter_yesno("x", "")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_filter_yesno(1, 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
enddef
def Test_popup_getoptions()
- v9.CheckDefAndScriptFailure(['popup_getoptions("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_getoptions(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_getoptions("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_getoptions(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
enddef
def Test_popup_getpos()
- v9.CheckDefAndScriptFailure(['popup_getpos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_getpos(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_getpos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_getpos(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
enddef
def Test_popup_hide()
- v9.CheckDefAndScriptFailure(['popup_hide("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_hide(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_hide("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_hide(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
enddef
def Test_popup_locate()
- v9.CheckDefAndScriptFailure(['popup_locate("a", 20)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_locate(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_locate("a", 20)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_locate(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_popup_menu()
- v9.CheckDefAndScriptFailure(['popup_menu({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_menu("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_menu({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_menu("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_popup_move()
- v9.CheckDefAndScriptFailure(['popup_move("x", {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_move(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_move("x", {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_move(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_popup_notification()
- v9.CheckDefAndScriptFailure(['popup_notification({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_notification("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_notification({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_notification("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_popup_setoptions()
- v9.CheckDefAndScriptFailure(['popup_setoptions("x", {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_setoptions(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_setoptions("x", {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_setoptions(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_popup_settext()
- v9.CheckDefAndScriptFailure(['popup_settext("x", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_settext(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1222: String or List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['popup_settext("x", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_settext(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1222: String or List required for argument 2'])
enddef
def Test_popup_show()
- v9.CheckDefAndScriptFailure(['popup_show("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['popup_show(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_show("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_show(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
enddef
def Test_prevnonblank()
- v9.CheckDefAndScriptFailure(['prevnonblank(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['prevnonblank("")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['prevnonblank(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['prevnonblank("")'], 'E1209: Invalid value for a line number')
assert_equal(0, prevnonblank(1))
enddef
def Test_printf()
- v9.CheckDefAndScriptFailure(['printf([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['printf([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
printf(0x10)->assert_equal('16')
assert_equal(" abc", "abc"->printf("%4s"))
enddef
@@ -3170,7 +3170,7 @@ def Test_prompt_getprompt()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['prompt_getprompt([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prompt_getprompt([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
assert_equal('', prompt_getprompt('NonExistingBuf'))
endif
enddef
@@ -3179,7 +3179,7 @@ def Test_prompt_setcallback()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['prompt_setcallback(true, "1")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prompt_setcallback(true, "1")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
endif
enddef
@@ -3187,7 +3187,7 @@ def Test_prompt_setinterrupt()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['prompt_setinterrupt(true, "1")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prompt_setinterrupt(true, "1")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
endif
enddef
@@ -3195,109 +3195,109 @@ def Test_prompt_setprompt()
if !has('channel')
CheckFeature channel
else
- v9.CheckDefAndScriptFailure(['prompt_setprompt([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['prompt_setprompt(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prompt_setprompt([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prompt_setprompt(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
endif
enddef
def Test_prop_add()
- v9.CheckDefAndScriptFailure(['prop_add("a", 2, {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_add(1, "b", {})'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['prop_add(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['prop_add("a", 2, {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_add(1, "b", {})'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prop_add(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
enddef
def Test_prop_add_list()
- v9.CheckDefAndScriptFailure(['prop_add_list([], [])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_add_list({}, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prop_add_list([], [])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_add_list({}, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2'])
enddef
def Test_prop_clear()
- v9.CheckDefAndScriptFailure(['prop_clear("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_clear(1, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['prop_clear(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['prop_clear("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_clear(1, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prop_clear(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
enddef
def Test_prop_find()
- v9.CheckDefAndScriptFailure(['prop_find([1, 2])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_find([1, 2], "k")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_find({"a": 10}, ["a"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prop_find([1, 2])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_find([1, 2], "k")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_find({"a": 10}, ["a"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1174: String required for argument 2'])
assert_fails("prop_find({}, '')", 'E474:')
enddef
def Test_prop_list()
- v9.CheckDefAndScriptFailure(['prop_list("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_list(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prop_list("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_list(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_prop_remove()
- v9.CheckDefAndScriptFailure(['prop_remove([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_remove({}, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['prop_remove({}, 1, "b")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['prop_remove([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_remove({}, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prop_remove({}, 1, "b")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
enddef
def Test_prop_type_add()
- v9.CheckDefAndScriptFailure(['prop_type_add({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_type_add("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_add({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_add("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
assert_fails("prop_type_add('', {highlight: 'Search'})", 'E475:')
enddef
def Test_prop_type_change()
- v9.CheckDefAndScriptFailure(['prop_type_change({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_type_change("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_change({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_change("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
assert_fails("prop_type_change('', {highlight: 'Search'})", 'E475:')
enddef
def Test_prop_type_delete()
- v9.CheckDefAndScriptFailure(['prop_type_delete({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_type_delete({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_type_delete("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_delete({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_delete({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_delete("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
assert_fails("prop_type_delete('')", 'E475:')
enddef
def Test_prop_type_get()
- v9.CheckDefAndScriptFailure(['prop_type_get({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_type_get({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_type_get("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_get({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_get({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_get("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
assert_fails("prop_type_get('')", 'E475:')
enddef
def Test_prop_type_list()
- v9.CheckDefAndScriptFailure(['prop_type_list(["a"])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 1'])
- v9.CheckDefAndScriptFailure(['prop_type_list(2)'], ['E1013: Argument 1: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_list(["a"])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['prop_type_list(2)'], ['E1013: Argument 1: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 1'])
enddef
def Test_py3eval()
if !has('python3')
CheckFeature python3
endif
- v9.CheckDefAndScriptFailure(['py3eval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['py3eval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
enddef
def Test_pyeval()
if !has('python')
CheckFeature python
endif
- v9.CheckDefAndScriptFailure(['pyeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['pyeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
enddef
def Test_pyxeval()
if !has('python') && !has('python3')
CheckFeature python
endif
- v9.CheckDefAndScriptFailure(['pyxeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['pyxeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
enddef
def Test_rand()
- v9.CheckDefAndScriptFailure(['rand(10)'], ['E1013: Argument 1: type mismatch, expected list<number> but got number', 'E1211: List required for argument 1'])
- v9.CheckDefFailure(['rand(["a"])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<string>')
+ v9.CheckSourceDefAndScriptFailure(['rand(10)'], ['E1013: Argument 1: type mismatch, expected list<number> but got number', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefFailure(['rand(["a"])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<string>')
assert_true(rand() >= 0)
assert_true(rand(srand()) >= 0)
enddef
def Test_range()
- v9.CheckDefAndScriptFailure(['range("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['range(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['range(10, 20, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['range("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['range(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['range(10, 20, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
# returns a list<number> but it's not declared as such
assert_equal(['x', 'x'], range(2)->map((i, v) => 'x'))
@@ -3306,8 +3306,8 @@ enddef
def Test_readdir()
eval expand('sautest')->readdir((e) => e[0] !=# '.')
eval expand('sautest')->readdirex((e) => e.name[0] !=# '.')
- v9.CheckDefAndScriptFailure(['readdir(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['readdir("a", "1", [3])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['readdir(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['readdir("a", "1", [3])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
if has('unix')
# only fails on Unix-like systems
assert_fails('readdir("")', 'E484: Can''t open file')
@@ -3315,8 +3315,8 @@ def Test_readdir()
enddef
def Test_readdirex()
- v9.CheckDefAndScriptFailure(['readdirex(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['readdirex("a", "1", [3])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['readdirex(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['readdirex("a", "1", [3])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
if has('unix')
# only fails on Unix-like systems
assert_fails('readdirex("")', 'E484: Can''t open file')
@@ -3332,8 +3332,8 @@ def Test_readblob()
var lines =<< trim END
var read: list<string> = readblob('Xreadblob')
END
- v9.CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list<string> but got blob', 1)
- v9.CheckDefExecAndScriptFailure(['readblob("")'], 'E484: Can''t open file <empty>')
+ v9.CheckSourceDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list<string> but got blob', 1)
+ v9.CheckSourceDefExecAndScriptFailure(['readblob("")'], 'E484: Can''t open file <empty>')
enddef
def Test_readfile()
@@ -3346,15 +3346,15 @@ def Test_readfile()
var lines =<< trim END
var read: dict<string> = readfile('Xreadfile')
END
- v9.CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected dict<string> but got list<string>', 1)
+ v9.CheckSourceDefAndScriptFailure(lines, 'E1012: Type mismatch; expected dict<string> but got list<string>', 1)
- v9.CheckDefAndScriptFailure(['readfile("a", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['readfile("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefExecAndScriptFailure(['readfile("")'], 'E1175: Non-empty string required for argument 1')
+ v9.CheckSourceDefAndScriptFailure(['readfile("a", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['readfile("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefExecAndScriptFailure(['readfile("")'], 'E1175: Non-empty string required for argument 1')
enddef
def Test_reduce()
- v9.CheckDefAndScriptFailure(['reduce({a: 10}, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1252: String, List or Blob required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['reduce({a: 10}, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1252: String, List or Blob required for argument 1'])
assert_equal(6, [1, 2, 3]->reduce((r, c) => r + c, 0))
assert_equal(11, 0z0506->reduce((r, c) => r + c, 0))
enddef
@@ -3362,13 +3362,13 @@ enddef
def Test_reltime()
CheckFeature reltime
- v9.CheckDefExecAndScriptFailure(['[]->reltime()'], 'E474:')
- v9.CheckDefExecAndScriptFailure(['[]->reltime([])'], 'E474:')
+ v9.CheckSourceDefExecAndScriptFailure(['[]->reltime()'], 'E474:')
+ v9.CheckSourceDefExecAndScriptFailure(['[]->reltime([])'], 'E474:')
- v9.CheckDefAndScriptFailure(['reltime("x")'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1'])
- v9.CheckDefFailure(['reltime(["x", "y"])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<string>')
- v9.CheckDefAndScriptFailure(['reltime([1, 2], 10)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2'])
- v9.CheckDefFailure(['reltime([1, 2], ["a", "b"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
+ v9.CheckSourceDefAndScriptFailure(['reltime("x")'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefFailure(['reltime(["x", "y"])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<string>')
+ v9.CheckSourceDefAndScriptFailure(['reltime([1, 2], 10)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefFailure(['reltime([1, 2], ["a", "b"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
var start: list<any> = reltime()
assert_true(type(reltime(start)) == v:t_list)
var end: list<any> = reltime()
@@ -3378,31 +3378,31 @@ enddef
def Test_reltimefloat()
CheckFeature reltime
- v9.CheckDefExecAndScriptFailure(['[]->reltimefloat()'], 'E474:')
+ v9.CheckSourceDefExecAndScriptFailure(['[]->reltimefloat()'], 'E474:')
- v9.CheckDefAndScriptFailure(['reltimefloat("x")'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1'])
- v9.CheckDefFailure(['reltimefloat([1.1])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<float>')
+ v9.CheckSourceDefAndScriptFailure(['reltimefloat("x")'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefFailure(['reltimefloat([1.1])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<float>')
assert_true(type(reltimefloat(reltime())) == v:t_float)
enddef
def Test_reltimestr()
CheckFeature reltime
- v9.CheckDefExecAndScriptFailure(['[]->reltimestr()'], 'E474:')
+ v9.CheckSourceDefExecAndScriptFailure(['[]->reltimestr()'], 'E474:')
- v9.CheckDefAndScriptFailure(['reltimestr(true)'], ['E1013: Argument 1: type mismatch, expected list<number> but got bool', 'E1211: List required for argument 1'])
- v9.CheckDefFailure(['reltimestr([true])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<bool>')
+ v9.CheckSourceDefAndScriptFailure(['reltimestr(true)'], ['E1013: Argument 1: type mismatch, expected list<number> but got bool', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefFailure(['reltimestr([true])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<bool>')
assert_true(type(reltimestr(reltime())) == v:t_string)
enddef
def Test_remote_expr()
CheckFeature clientserver
CheckEnv DISPLAY
- v9.CheckDefAndScriptFailure(['remote_expr(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['remote_expr("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['remote_expr("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
- v9.CheckDefAndScriptFailure(['remote_expr("a", "b", "c", "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
- v9.CheckDefExecAndScriptFailure(['remote_expr("", "")'], 'E241: Unable to send to ')
+ v9.CheckSourceDefAndScriptFailure(['remote_expr(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['remote_expr("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['remote_expr("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['remote_expr("a", "b", "c", "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefExecAndScriptFailure(['remote_expr("", "")'], 'E241: Unable to send to ')
enddef
def Test_remote_foreground()
@@ -3411,7 +3411,7 @@ def Test_remote_foreground()
CheckNotMSWindows
CheckX11
- v9.CheckDefAndScriptFailure(['remote_foreground(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['remote_foreground(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_fails('remote_foreground("NonExistingServer")', 'E241:')
assert_fails('remote_foreground("")', 'E241:')
enddef
@@ -3419,32 +3419,32 @@ enddef
def Test_remote_peek()
CheckFeature clientserver
CheckEnv DISPLAY
- v9.CheckDefAndScriptFailure(['remote_peek(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['remote_peek("a5b6c7", [1])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['remote_peek("")'], 'E573: Invalid server id used')
+ v9.CheckSourceDefAndScriptFailure(['remote_peek(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['remote_peek("a5b6c7", [1])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['remote_peek("")'], 'E573: Invalid server id used')
enddef
def Test_remote_read()
CheckFeature clientserver
CheckEnv DISPLAY
- v9.CheckDefAndScriptFailure(['remote_read(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['remote_read("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['remote_read("")'], 'E573: Invalid server id used')
+ v9.CheckSourceDefAndScriptFailure(['remote_read(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['remote_read("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['remote_read("")'], 'E573: Invalid server id used')
enddef
def Test_remote_send()
CheckFeature clientserver
CheckEnv DISPLAY
- v9.CheckDefAndScriptFailure(['remote_send(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['remote_send("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['remote_send("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['remote_send(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['remote_send("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['remote_send("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
assert_fails('remote_send("", "")', 'E241:')
enddef
def Test_remote_startserver()
CheckFeature clientserver
CheckEnv DISPLAY
- v9.CheckDefAndScriptFailure(['remote_startserver({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['remote_startserver({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1'])
enddef
def Test_remove_literal_list()
@@ -3458,28 +3458,28 @@ def Test_remove_const()
const l = [1, 2, 3, 4]
remove(l, 1)
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
lines =<< trim END
const d = {a: 1, b: 2}
remove(d, 'a')
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>')
lines =<< trim END
const b = 0z010203
remove(b, 1)
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob')
enddef
def Test_remove()
- v9.CheckDefAndScriptFailure(['remove("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1228: List, Dictionary or Blob required for argument 1'])
- v9.CheckDefAndScriptFailure(['remove([], "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['remove([], 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['remove({}, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['remove(0z10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['remove(0z20, 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['remove("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1228: List, Dictionary or Blob required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['remove([], "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['remove([], 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['remove({}, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['remove(0z10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['remove(0z20, 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
var l: any = [1, 2, 3, 4]
remove(l, 1)
assert_equal([1, 3, 4], l)
@@ -3511,14 +3511,14 @@ def Test_remove_return_type()
enddef
def Test_rename()
- v9.CheckDefAndScriptFailure(['rename(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['rename("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['rename(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['rename("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
rename('', '')->assert_equal(0)
enddef
def Test_repeat()
- v9.CheckDefAndScriptFailure(['repeat(1.1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1301: String, Number, List or Blob required for argument 1'])
- v9.CheckDefAndScriptFailure(['repeat({a: 10}, 2)'], ['E1013: Argument 1: type mismatch, expected string but got dict<', 'E1301: String, Number, List or Blob required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['repeat(1.1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1301: String, Number, List or Blob required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['repeat({a: 10}, 2)'], ['E1013: Argument 1: type mismatch, expected string but got dict<', 'E1301: String, Number, List or Blob required for argument 1'])
var lines =<< trim END
assert_equal('aaa', repeat('a', 3))
assert_equal('111', repeat(1, 3))
@@ -3529,17 +3529,17 @@ def Test_repeat()
s ..= repeat(5, 3)
assert_equal('-555', s)
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
enddef
def Test_resolve()
- v9.CheckDefAndScriptFailure(['resolve([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['resolve([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
assert_equal('SomeFile', resolve('SomeFile'))
resolve('')->assert_equal('')
enddef
def Test_reverse()
- v9.CheckDefAndScriptFailure(['reverse(10)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1252: String, List or Blob required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['reverse(10)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1252: String, List or Blob required for argument 1'])
enddef
def Test_reverse_return_type()
@@ -3556,49 +3556,49 @@ def Test_reverse_const()
const l = [1, 2, 3, 4]
reverse(l)
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
lines =<< trim END
const b = 0z010203
reverse(b)
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob')
enddef
def Test_rubyeval()
if !has('ruby')
CheckFeature ruby
endif
- v9.CheckDefAndScriptFailure(['rubyeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['rubyeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
enddef
def Test_screenattr()
- v9.CheckDefAndScriptFailure(['screenattr("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['screenattr(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['screenattr("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['screenattr(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_screenchar()
- v9.CheckDefAndScriptFailure(['screenchar("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['screenchar(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['screenchar("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['screenchar(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_screenchars()
assert_equal(['x'], screenchars(1, 1)->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['screenchars("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['screenchars(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['screenchars("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['screenchars(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_screenpos()
- v9.CheckDefAndScriptFailure(['screenpos("a", 1, 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['screenpos(1, "b", 1)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['screenpos(1, 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['screenpos("a", 1, 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['screenpos(1, "b", 1)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['screenpos(1, 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
assert_equal({col: 1, row: 1, endcol: 1, curscol: 1}, screenpos(1, 1, 1))
enddef
def Test_screenstring()
- v9.CheckDefAndScriptFailure(['screenstring("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['screenstring(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['screenstring("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['screenstring(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_search()
@@ -3630,13 +3630,13 @@ def Test_search()
normal 0
assert_equal([0, 0], searchpos('this', '', 0, 0, 'col(".") > col'))
bwipe!
- v9.CheckDefAndScriptFailure(['search(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['search("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['search("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['search("a", "b", 3, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['search(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['search("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['search("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['search("a", "b", 3, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
new
setline(1, "match this")
- v9.CheckDefAndScriptFailure(['search("a", "", 9, 0, [0])'], ['E1013: Argument 5: type mismatch, expected func(...): any but got list<number>', 'E730: Using a List as a String'])
+ v9.CheckSourceDefAndScriptFailure(['search("a", "", 9, 0, [0])'], ['E1013: Argument 5: type mismatch, expected func(...): any but got list<number>', 'E730: Using a List as a String'])
bwipe!
enddef
@@ -3652,14 +3652,14 @@ def Test_searchcount()
maxcount: 99,
incomplete: 0})
bwipe!
- v9.CheckDefAndScriptFailure(['searchcount([1])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['searchcount([1])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1'])
enddef
def Test_searchdecl()
searchdecl('blah', true, true)->assert_equal(1)
- v9.CheckDefAndScriptFailure(['searchdecl(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['searchdecl("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
- v9.CheckDefAndScriptFailure(['searchdecl("a", true, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['searchdecl(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['searchdecl("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['searchdecl("a", true, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
# search for an empty string declaration
var lines: list<string> =<< trim END
@@ -3719,7 +3719,7 @@ def Test_searchpair()
enddef
Fail()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceScriptSuccess(lines)
assert_equal('yes', g:caught)
unlet g:caught
bwipe!
@@ -3727,64 +3727,64 @@ def Test_searchpair()
lines =<< trim END
echo searchpair("a", "b", "c", "d", "f", 33)
END
- v9.CheckDefAndScriptFailure(lines, ['E1001: Variable not found: f', 'E475: Invalid argument: d'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1001: Variable not found: f', 'E475: Invalid argument: d'])
var errors = ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']
- v9.CheckDefAndScriptFailure(['searchpair(1, "b", "c")'], errors)
- v9.CheckDefAndScriptFailure(['searchpairpos(1, "b", "c")'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpair(1, "b", "c")'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpairpos(1, "b", "c")'], errors)
errors = ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']
- v9.CheckDefAndScriptFailure(['searchpair("a", 2, "c")'], errors)
- v9.CheckDefAndScriptFailure(['searchpairpos("a", 2, "c")'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpair("a", 2, "c")'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", 2, "c")'], errors)
errors = ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']
- v9.CheckDefAndScriptFailure(['searchpair("a", "b", 3)'], errors)
- v9.CheckDefAndScriptFailure(['searchpairpos("a", "b", 3)'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", 3)'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", "b", 3)'], errors)
errors = ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4']
- v9.CheckDefAndScriptFailure(['searchpair("a", "b", "c", 4)'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", "c", 4)'], errors)
new
setline(1, "match this")
errors = ['E1013: Argument 5: type mismatch, expected func(...): any but got list<number>', 'E730: Using a List as a String']
- v9.CheckDefAndScriptFailure(['searchpair("a", "b", "c", "r", [0])'], errors)
- v9.CheckDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", [0])'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", "c", "r", [0])'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", [0])'], errors)
bwipe!
errors = ['E1013: Argument 6: type mismatch, expected number but got string', 'E1210: Number required for argument 6']
- v9.CheckDefAndScriptFailure(['searchpair("a", "b", "c", "r", "1", "f")'], errors)
- v9.CheckDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", "1", "f")'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", "c", "r", "1", "f")'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", "1", "f")'], errors)
errors = ['E1013: Argument 7: type mismatch, expected number but got string', 'E1210: Number required for argument 7']
- v9.CheckDefAndScriptFailure(['searchpair("a", "b", "c", "r", "1", 3, "g")'], errors)
- v9.CheckDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", "1", 3, "g")'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", "c", "r", "1", 3, "g")'], errors)
+ v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", "1", 3, "g")'], errors)
enddef
def Test_searchpos()
assert_equal(['x', 'x'], searchpos('.')->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['searchpos(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['searchpos("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['searchpos("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['searchpos("a", "b", 3, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['searchpos(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['searchpos("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['searchpos("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['searchpos("a", "b", 3, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4'])
new
setline(1, "match this")
- v9.CheckDefAndScriptFailure(['searchpos("a", "", 9, 0, [0])'], ['E1013: Argument 5: type mismatch, expected func(...): any but got list<number>', 'E730: Using a List as a String'])
+ v9.CheckSourceDefAndScriptFailure(['searchpos("a", "", 9, 0, [0])'], ['E1013: Argument 5: type mismatch, expected func(...): any but got list<number>', 'E730: Using a List as a String'])
bwipe!
enddef
def Test_server2client()
CheckFeature clientserver
CheckEnv DISPLAY
- v9.CheckDefAndScriptFailure(['server2client(10, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['server2client("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['server2client("", "a")'], 'E573: Invalid server id used')
- v9.CheckDefExecAndScriptFailure(['server2client("", "")'], 'E573: Invalid server id used')
+ v9.CheckSourceDefAndScriptFailure(['server2client(10, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['server2client("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['server2client("", "a")'], 'E573: Invalid server id used')
+ v9.CheckSourceDefExecAndScriptFailure(['server2client("", "")'], 'E573: Invalid server id used')
enddef
def Test_shellescape()
- v9.CheckDefAndScriptFailure(['shellescape(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['shellescape("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['shellescape(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['shellescape("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
if has('unix')
assert_equal("''", shellescape(''))
endif
@@ -3837,7 +3837,7 @@ def Test_set_get_bufline()
exe 'bwipe! ' .. b
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
enddef
def Test_setbufvar()
@@ -3864,8 +3864,8 @@ def Test_setbufvar()
setbufvar('%', 'myvar', 123)
getbufvar('%', 'myvar')->assert_equal(123)
- v9.CheckDefAndScriptFailure(['setbufvar(true, "v", 3)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['setbufvar(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['setbufvar(true, "v", 3)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setbufvar(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
assert_fails('setbufvar("%", "", 10)', 'E461: Illegal variable name')
enddef
@@ -3878,10 +3878,10 @@ def Test_setbufline()
setbufline(bnum, 5, 10)
setbufline(bnum, 6, ['two', 11])
assert_equal(['1', '2', '3', 'one', '10', 'two', '11'], getbufline(bnum, 1, '$'))
- v9.CheckDefAndScriptFailure(['setbufline([1], 1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['setbufline(1, [1], "x")'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['setbufline(' .. bnum .. ', -1, "x")'], 'E966: Invalid line number: -1')
- v9.CheckDefAndScriptFailure(['setbufline(1, 1, {"a": 10})'], ['E1013: Argument 3: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['setbufline([1], 1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setbufline(1, [1], "x")'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['setbufline(' .. bnum .. ', -1, "x")'], 'E966: Invalid line number: -1')
+ v9.CheckSourceDefAndScriptFailure(['setbufline(1, 1, {"a": 10})'], ['E1013: Argument 3: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 3'])
bnum->bufwinid()->win_gotoid()
setbufline('', 1, 'nombres')
getline(1)->assert_equal('nombres')
@@ -3889,53 +3889,53 @@ def Test_setbufline()
enddef
def Test_setcellwidths()
- v9.CheckDefAndScriptFailure(['setcellwidths(1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['setcellwidths({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setcellwidths(1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setcellwidths({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1'])
enddef
def Test_setcharpos()
- v9.CheckDefAndScriptFailure(['setcharpos(1, [])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefFailure(['setcharpos(".", ["a"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
- v9.CheckDefAndScriptFailure(['setcharpos(".", 1)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['setcharpos("", [0, 1, 1, 1])'], 'E474: Invalid argument')
+ v9.CheckSourceDefAndScriptFailure(['setcharpos(1, [])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefFailure(['setcharpos(".", ["a"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
+ v9.CheckSourceDefAndScriptFailure(['setcharpos(".", 1)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['setcharpos("", [0, 1, 1, 1])'], 'E474: Invalid argument')
enddef
def Test_setcharsearch()
- v9.CheckDefAndScriptFailure(['setcharsearch("x")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 1'])
- v9.CheckDefAndScriptFailure(['setcharsearch([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setcharsearch("x")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setcharsearch([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
var d: dict<any> = {char: 'x', forward: 1, until: 1}
setcharsearch(d)
assert_equal(d, getcharsearch())
enddef
def Test_setcmdline()
- v9.CheckDefAndScriptSuccess(['setcmdline("ls", 2)'])
- v9.CheckDefAndScriptFailure(['setcmdline(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['setcmdline("ls", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptSuccess(['setcmdline("ls", 2)'])
+ v9.CheckSourceDefAndScriptFailure(['setcmdline(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setcmdline("ls", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_setcmdpos()
- v9.CheckDefAndScriptFailure(['setcmdpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setcmdpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_setcursorcharpos()
- v9.CheckDefAndScriptFailure(['setcursorcharpos(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected number but got blob', 'E1224: String, Number or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['setcursorcharpos(1, "2")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['setcursorcharpos(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefExecAndScriptFailure(['setcursorcharpos("", 10)'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['setcursorcharpos(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected number but got blob', 'E1224: String, Number or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setcursorcharpos(1, "2")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['setcursorcharpos(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefExecAndScriptFailure(['setcursorcharpos("", 10)'], 'E1209: Invalid value for a line number')
enddef
def Test_setenv()
- v9.CheckDefAndScriptFailure(['setenv(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setenv(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_equal(0, setenv('', ''))
assert_equal(0, setenv('', v:null))
enddef
def Test_setfperm()
- v9.CheckDefAndScriptFailure(['setfperm(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['setfperm("a", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['setfperm("Xfile", "")'], 'E475: Invalid argument')
- v9.CheckDefExecAndScriptFailure(['setfperm("", "")'], 'E475: Invalid argument')
+ v9.CheckSourceDefAndScriptFailure(['setfperm(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setfperm("a", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['setfperm("Xfile", "")'], 'E475: Invalid argument')
+ v9.CheckSourceDefExecAndScriptFailure(['setfperm("", "")'], 'E475: Invalid argument')
assert_equal(0, setfperm('', 'rw-r--r--'))
enddef
@@ -3949,9 +3949,9 @@ def Test_setline()
assert_equal(['one', 'b', 'c', 'd'], getline(1, '$'))
setline(1, 10)
assert_equal(['10', 'b', 'c', 'd'], getline(1, '$'))
- v9.CheckDefAndScriptFailure(['setline([1], "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['setline("", "x")'], 'E1209: Invalid value for a line number')
- v9.CheckDefExecAndScriptFailure(['setline(-1, "x")'], 'E966: Invalid line number: -1')
+ v9.CheckSourceDefAndScriptFailure(['setline([1], "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['setline("", "x")'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefExecAndScriptFailure(['setline(-1, "x")'], 'E966: Invalid line number: -1')
assert_fails('setline(".a", "x")', ['E1209:', 'E1209:'])
bw!
enddef
@@ -3961,28 +3961,28 @@ def Test_setloclist()
var what = {items: items}
setqflist([], ' ', what)
setloclist(0, [], ' ', what)
- v9.CheckDefAndScriptFailure(['setloclist("1", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['setloclist(1, 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
- v9.CheckDefAndScriptFailure(['setloclist(1, [], 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
- v9.CheckDefAndScriptFailure(['setloclist(1, [], "a", [])'], ['E1013: Argument 4: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['setloclist("1", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setloclist(1, 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['setloclist(1, [], 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['setloclist(1, [], "a", [])'], ['E1013: Argument 4: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 4'])
enddef
def Test_setmatches()
- v9.CheckDefAndScriptFailure(['setmatches({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['setmatches([], "1")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['setmatches({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setmatches([], "1")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_setpos()
- v9.CheckDefAndScriptFailure(['setpos(1, [])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefFailure(['setpos(".", ["a"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
- v9.CheckDefAndScriptFailure(['setpos(".", 1)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['setpos("", [0, 1, 1, 1])'], 'E474: Invalid argument')
+ v9.CheckSourceDefAndScriptFailure(['setpos(1, [])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefFailure(['setpos(".", ["a"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
+ v9.CheckSourceDefAndScriptFailure(['setpos(".", 1)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['setpos("", [0, 1, 1, 1])'], 'E474: Invalid argument')
enddef
def Test_setqflist()
- v9.CheckDefAndScriptFailure(['setqflist(1, "")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['setqflist([], 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['setqflist([], "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['setqflist(1, "")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setqflist([], 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['setqflist([], "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
enddef
def Test_setreg()
@@ -3991,111 +3991,111 @@ def Test_setreg()
setreg('a', reginfo)
getreginfo('a')->assert_equal(reginfo)
assert_fails('setreg("ab", 0)', 'E1162:')
- v9.CheckDefAndScriptFailure(['setreg(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['setreg("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['setreg(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setreg("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
setreg('', '1a2b3c')
assert_equal('1a2b3c', @")
enddef
def Test_settabvar()
- v9.CheckDefAndScriptFailure(['settabvar("a", "b", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['settabvar(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['settabvar("a", "b", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['settabvar(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
assert_fails('settabvar(1, "", 10)', 'E461: Illegal variable name')
enddef
def Test_settabwinvar()
- v9.CheckDefAndScriptFailure(['settabwinvar("a", 2, "c", true)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['settabwinvar(1, "b", "c", [])'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['settabwinvar(1, 1, 3, {})'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['settabwinvar("a", 2, "c", true)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['settabwinvar(1, "b", "c", [])'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['settabwinvar(1, 1, 3, {})'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
assert_fails('settabwinvar(1, 1, "", 10)', 'E461: Illegal variable name')
enddef
def Test_settagstack()
- v9.CheckDefAndScriptFailure(['settagstack(true, {})'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['settagstack(1, [1])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
- v9.CheckDefAndScriptFailure(['settagstack(1, {}, 2)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['settagstack(true, {})'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['settagstack(1, [1])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['settagstack(1, {}, 2)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
assert_fails('settagstack(1, {}, "")', 'E962: Invalid action')
enddef
def Test_setwinvar()
- v9.CheckDefAndScriptFailure(['setwinvar("a", "b", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['setwinvar(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['setwinvar("a", "b", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['setwinvar(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
assert_fails('setwinvar(1, "", 10)', 'E461: Illegal variable name')
assert_fails('setwinvar(0, "&rulerformat", true)', ['E928:', 'E928:'])
enddef
def Test_sha256()
- v9.CheckDefAndScriptFailure(['sha256(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['sha256(0zABCD)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sha256(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sha256(0zABCD)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1'])
assert_equal('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad', sha256('abc'))
assert_equal('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', sha256(''))
enddef
def Test_shiftwidth()
- v9.CheckDefAndScriptFailure(['shiftwidth("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['shiftwidth("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_sign_define()
- v9.CheckDefAndScriptFailure(['sign_define({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_define({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_define("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['sign_define({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_define({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_define("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_sign_getdefined()
- v9.CheckDefAndScriptFailure(['sign_getdefined(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_getdefined(2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_getdefined(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_getdefined(2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
sign_getdefined('')->assert_equal([])
enddef
def Test_sign_getplaced()
- v9.CheckDefAndScriptFailure(['sign_getplaced(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_getplaced(1, ["a"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2'])
- v9.CheckDefAndScriptFailure(['sign_getplaced("a", 1.1)'], ['E1013: Argument 2: type mismatch, expected dict<any> but got float', 'E1206: Dictionary required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['sign_getplaced(bufnr(), {lnum: ""})'], 'E1030: Using a String as a Number:')
+ v9.CheckSourceDefAndScriptFailure(['sign_getplaced(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_getplaced(1, ["a"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['sign_getplaced("a", 1.1)'], ['E1013: Argument 2: type mismatch, expected dict<any> but got float', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['sign_getplaced(bufnr(), {lnum: ""})'], 'E1030: Using a String as a Number:')
sign_getplaced('')->assert_equal([{signs: [], bufnr: bufnr()}])
enddef
def Test_sign_jump()
- v9.CheckDefAndScriptFailure(['sign_jump("a", "b", "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_jump(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['sign_jump(1, "b", true)'], ['E1013: Argument 3: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['sign_jump("a", "b", "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_jump(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['sign_jump(1, "b", true)'], ['E1013: Argument 3: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 3'])
enddef
def Test_sign_place()
- v9.CheckDefAndScriptFailure(['sign_place("a", "b", "c", "d")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_place(1, 2, "c", "d")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['sign_place(1, "b", 3, "d")'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
- v9.CheckDefAndScriptFailure(['sign_place(1, "b", "c", 1.1)'], ['E1013: Argument 4: type mismatch, expected string but got float', 'E1220: String or Number required for argument 4'])
- v9.CheckDefAndScriptFailure(['sign_place(1, "b", "c", "d", [1])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 5'])
- v9.CheckDefExecAndScriptFailure(['sign_place(0, "", "MySign", bufnr(), {lnum: ""})'], 'E1209: Invalid value for a line number: ""')
+ v9.CheckSourceDefAndScriptFailure(['sign_place("a", "b", "c", "d")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_place(1, 2, "c", "d")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['sign_place(1, "b", 3, "d")'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['sign_place(1, "b", "c", 1.1)'], ['E1013: Argument 4: type mismatch, expected string but got float', 'E1220: String or Number required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['sign_place(1, "b", "c", "d", [1])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 5'])
+ v9.CheckSourceDefExecAndScriptFailure(['sign_place(0, "", "MySign", bufnr(), {lnum: ""})'], 'E1209: Invalid value for a line number: ""')
assert_fails("sign_place(0, '', '', '')", 'E155:')
enddef
def Test_sign_placelist()
- v9.CheckDefAndScriptFailure(['sign_placelist("x")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_placelist({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['sign_placelist([{"name": "MySign", "buffer": bufnr(), "lnum": ""}])'], 'E1209: Invalid value for a line number: ""')
+ v9.CheckSourceDefAndScriptFailure(['sign_placelist("x")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_placelist({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['sign_placelist([{"name": "MySign", "buffer": bufnr(), "lnum": ""}])'], 'E1209: Invalid value for a line number: ""')
assert_fails('sign_placelist([{name: "MySign", buffer: "", lnum: 1}])', 'E155:')
enddef
def Test_sign_undefine()
- v9.CheckDefAndScriptFailure(['sign_undefine({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_undefine([1])'], ['E1013: Argument 1: type mismatch, expected list<string> but got list<number>', 'E155: Unknown sign:'])
+ v9.CheckSourceDefAndScriptFailure(['sign_undefine({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_undefine([1])'], ['E1013: Argument 1: type mismatch, expected list<string> but got list<number>', 'E155: Unknown sign:'])
enddef
def Test_sign_unplace()
- v9.CheckDefAndScriptFailure(['sign_unplace({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_unplace({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_unplace("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['sign_unplace({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_unplace({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_unplace("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2'])
enddef
def Test_sign_unplacelist()
- v9.CheckDefAndScriptFailure(['sign_unplacelist("x")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['sign_unplacelist({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_unplacelist("x")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sign_unplacelist({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1'])
enddef
def Test_simplify()
- v9.CheckDefAndScriptFailure(['simplify(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['simplify(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
call assert_equal('NonExistingFile', simplify('NonExistingFile'))
simplify('')->assert_equal('')
enddef
@@ -4105,9 +4105,9 @@ def Test_slice()
assert_equal(['val'], lds->slice(0, 1)->map((_, v) => 'val'))
assert_equal(['val'], lds[ : ]->map((_, v) => 'val'))
- v9.CheckDefAndScriptFailure(['slice({"a": 10}, 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['slice([1, 2, 3], "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['slice("abc", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['slice({"a": 10}, 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['slice([1, 2, 3], "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['slice("abc", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
enddef
def Test_spellsuggest()
@@ -4116,29 +4116,29 @@ def Test_spellsuggest()
else
spellsuggest('marrch', 1, true)->assert_equal(['March'])
endif
- v9.CheckDefAndScriptFailure(['spellsuggest(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['spellsuggest("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['spellsuggest("a", 1, 0z01)'], ['E1013: Argument 3: type mismatch, expected bool but got blob', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['spellsuggest(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['spellsuggest("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['spellsuggest("a", 1, 0z01)'], ['E1013: Argument 3: type mismatch, expected bool but got blob', 'E1212: Bool required for argument 3'])
spellsuggest('')->assert_equal([])
enddef
def Test_sound_playevent()
CheckFeature sound
- v9.CheckDefAndScriptFailure(['sound_playevent(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sound_playevent(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
enddef
def Test_sound_playfile()
CheckFeature sound
- v9.CheckDefAndScriptFailure(['sound_playfile(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sound_playfile(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
enddef
def Test_sound_stop()
CheckFeature sound
- v9.CheckDefAndScriptFailure(['sound_stop("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sound_stop("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_soundfold()
- v9.CheckDefAndScriptFailure(['soundfold(20)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['soundfold(20)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_equal('abc', soundfold('abc'))
assert_equal('', soundfold(''))
enddef
@@ -4160,12 +4160,12 @@ def Test_sort_argument()
sort(l, Compare)
assert_equal([1, 2, 3, 4, 5, 6, 7, 8], l)
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
lines =<< trim END
sort([1, 2, 3], (a: any, b: any) => 1)
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
lines =<< trim END
vim9script
@@ -4176,7 +4176,7 @@ def Test_sort_argument()
enddef
SortedList()->assert_equal([1, 2, 3])
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceScriptSuccess(lines)
enddef
def Test_sort_const()
@@ -4184,12 +4184,12 @@ def Test_sort_const()
const l = [1, 2, 3, 4]
sort(l)
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
enddef
def Test_sort_compare_func_fails()
- v9.CheckDefAndScriptFailure(['sort("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['sort([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['sort("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['sort([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
var lines =<< trim END
vim9script
@@ -4202,31 +4202,31 @@ def Test_sort_compare_func_fails()
var l = [1, 2, 3]
sort(l, (a: string, b: number) => 1)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(string, number): number', 'E1013: Argument 1: type mismatch, expected string but got number'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(string, number): number', 'E1013: Argument 1: type mismatch, expected string but got number'])
lines =<< trim END
var l = ['a', 'b', 'c']
sort(l, (a: string, b: number) => 1)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?string): number but got func(string, number): number', 'E1013: Argument 2: type mismatch, expected number but got string'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?string): number but got func(string, number): number', 'E1013: Argument 2: type mismatch, expected number but got string'])
lines =<< trim END
sort([1, 2, 3], (a: number, b: number) => true)
END
- v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, number): bool', 'E1138: Using a Bool as a Number'])
+ v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, number): bool', 'E1138: Using a Bool as a Number'])
enddef
def Test_spellbadword()
- v9.CheckDefAndScriptFailure(['spellbadword(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['spellbadword(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
spellbadword('good')->assert_equal(['', ''])
spellbadword('')->assert_equal(['', ''])
enddef
def Test_split()
split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', ''])
- v9.CheckDefAndScriptFailure(['split(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['split("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['split("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['split(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['split("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['split("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
split('')->assert_equal([])
split('', '')->assert_equal([])
enddef
@@ -4235,12 +4235,12 @@ def Test_srand()
var expected = srand()->len()->range()->map((_, _) => 'x')
assert_equal(expected, srand()->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['srand("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['srand("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
type(srand(100))->assert_equal(v:t_list)
enddef
def Test_state()
- v9.CheckDefAndScriptFailure(['state({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['state({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1'])
assert_equal('', state('a'))
enddef
@@ -4249,14 +4249,14 @@ def Test_str2float()
str2float("2e-2")->assert_equal(0.02)
str2float('')->assert_equal(0.0)
- v9.CheckDefAndScriptFailure(['str2float(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['str2float(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
enddef
def Test_str2list()
assert_equal(['x', 'x', 'x'], str2list('abc')->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['str2list(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['str2list("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['str2list(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['str2list("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
assert_equal([97], str2list('a'))
assert_equal([97], str2list('a', 1))
assert_equal([97], str2list('a', true))
@@ -4267,29 +4267,29 @@ def Test_str2nr()
str2nr("1'000'000", 10, true)->assert_equal(1000000)
str2nr('')->assert_equal(0)
- v9.CheckDefAndScriptFailure(['str2nr(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['str2nr("123", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['str2nr("123", 10, "x")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['str2nr(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['str2nr("123", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['str2nr("123", 10, "x")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
enddef
def Test_strcharlen()
- v9.CheckDefAndScriptFailure(['strcharlen([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strcharlen([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
"abc"->strcharlen()->assert_equal(3)
strcharlen(99)->assert_equal(2)
enddef
def Test_strcharpart()
- v9.CheckDefAndScriptFailure(['strcharpart(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['strcharpart("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['strcharpart("a", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['strcharpart("a", 1, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['strcharpart(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strcharpart("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['strcharpart("a", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['strcharpart("a", 1, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4'])
strcharpart('', 0)->assert_equal('')
enddef
def Test_strchars()
strchars("A\u20dd", true)->assert_equal(1)
- v9.CheckDefAndScriptFailure(['strchars(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['strchars("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['strchars(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strchars("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
assert_equal(3, strchars('abc'))
assert_equal(3, strchars('abc', 1))
assert_equal(3, strchars('abc', true))
@@ -4297,46 +4297,46 @@ def Test_strchars()
enddef
def Test_strdisplaywidth()
- v9.CheckDefAndScriptFailure(['strdisplaywidth(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['strdisplaywidth("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['strdisplaywidth(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strdisplaywidth("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
strdisplaywidth('')->assert_equal(0)
enddef
def Test_strftime()
if exists('*strftime')
- v9.CheckDefAndScriptFailure(['strftime(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['strftime("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['strftime(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strftime("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
strftime('')->assert_equal('')
endif
enddef
def Test_strgetchar()
- v9.CheckDefAndScriptFailure(['strgetchar(1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['strgetchar("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['strgetchar(1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strgetchar("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
strgetchar('', 0)->assert_equal(-1)
strgetchar('', 1)->assert_equal(-1)
enddef
def Test_stridx()
- v9.CheckDefAndScriptFailure(['stridx([1], "b")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['stridx("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['stridx("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['stridx([1], "b")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['stridx("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['stridx("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
stridx('', '')->assert_equal(0)
stridx('', 'a')->assert_equal(-1)
stridx('a', '')->assert_equal(0)
enddef
def Test_strlen()
- v9.CheckDefAndScriptFailure(['strlen([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strlen([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
"abc"->strlen()->assert_equal(3)
strlen(99)->assert_equal(2)
enddef
def Test_strpart()
- v9.CheckDefAndScriptFailure(['strpart(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['strpart("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['strpart("a", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
- v9.CheckDefAndScriptFailure(['strpart("a", 1, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['strpart(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strpart("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['strpart("a", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['strpart("a", 1, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4'])
strpart('', 0)->assert_equal('')
enddef
@@ -4344,8 +4344,8 @@ def Test_strptime()
CheckFunction strptime
CheckNotBSD
if exists_compiled('*strptime')
- v9.CheckDefAndScriptFailure(['strptime(10, "2021")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['strptime("%Y", 2021)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['strptime(10, "2021")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strptime("%Y", 2021)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
assert_notequal(0, strptime('%Y', '2021'))
# This fails on BSD 14 and returns
# -2209078800 instead of 0
@@ -4354,30 +4354,30 @@ def Test_strptime()
enddef
def Test_strridx()
- v9.CheckDefAndScriptFailure(['strridx([1], "b")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['strridx("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['strridx("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['strridx([1], "b")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strridx("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['strridx("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
strridx('', '')->assert_equal(0)
strridx('', 'a')->assert_equal(-1)
strridx('a', '')->assert_equal(1)
enddef
def Test_strtrans()
- v9.CheckDefAndScriptFailure(['strtrans(20)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strtrans(20)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_equal('abc', strtrans('abc'))
strtrans('')->assert_equal('')
enddef
def Test_strutf16len()
- v9.CheckDefAndScriptFailure(['strutf16len([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['strutf16len("a", "")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['strutf16len([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strutf16len("a", "")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2'])
""->strutf16len()->assert_equal(0)
'-ąÌ-ąÌ'->strutf16len(true)->assert_equal(8)
'-ąÌ-ąÌ'->strutf16len(false)->assert_equal(4)
enddef
def Test_strwidth()
- v9.CheckDefAndScriptFailure(['strwidth(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['strwidth(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_equal(4, strwidth('abcd'))
strwidth('')->assert_equal(0)
enddef
@@ -4388,8 +4388,8 @@ def Test_submatch()
var actual = substitute('A123456789', pat, Rep, '')
var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]"
actual->assert_equal(expected)
- v9.CheckDefAndScriptFailure(['submatch("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['submatch(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['submatch("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['submatch(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2'])
enddef
def Test_substitute()
@@ -4400,30 +4400,30 @@ def Test_substitute()
assert_fails('"text"->substitute(".*", () => test_null_job(), "")', 'E908: Using an invalid value as a String: job')
assert_fails('"text"->substitute(".*", () => test_null_channel(), "")', 'E908: Using an invalid value as a String: channel')
endif
- v9.CheckDefAndScriptFailure(['substitute(1, "b", "1", "d")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['substitute("a", 2, "1", "d")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['substitute("a", "b", "1", 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['substitute(1, "b", "1", "d")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['substitute("a", 2, "1", "d")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['substitute("a", "b", "1", 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4'])
substitute('', '', '', '')->assert_equal('')
var lines =<< trim END
assert_equal("4", substitute("3", '\d', '\=str2nr(submatch(0)) + 1', 'g'))
END
- v9.CheckDefAndScriptSuccess(lines)
+ v9.CheckSourceDefAndScriptSuccess(lines)
lines =<< trim END
assert_equal("4", substitute("3", '\d', '\="text" x', 'g'))
END
- v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: x')
+ v9.CheckSourceDefAndScriptFailure(lines, 'E488: Trailing characters: x')
enddef
def Test_swapinfo()
- v9.CheckDefAndScriptFailure(['swapinfo({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['swapinfo({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1'])
call swapinfo('x')->assert_equal({error: 'Cannot open file'})
call swapinfo('')->assert_equal({error: 'Cannot open file'})
enddef
def Test_swapname()
- v9.CheckDefAndScriptFailure(['swapname([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['swapname([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
assert_fails('swapname("NonExistingBuf")', 'E94:')
enddef
@@ -4432,46 +4432,46 @@ def Test_synID()
setline(1, "text")
synID(1, 1, true)->assert_equal(0)
bwipe!
- v9.CheckDefAndScriptFailure(['synID(0z10, 1, true)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['synID("a", true, false)'], ['E1013: Argument 2: type mismatch, expected number but got bool', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['synID(1, 1, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
- v9.CheckDefExecAndScriptFailure(['synID("", 10, true)'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['synID(0z10, 1, true)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['synID("a", true, false)'], ['E1013: Argument 2: type mismatch, expected number but got bool', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['synID(1, 1, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefExecAndScriptFailure(['synID("", 10, true)'], 'E1209: Invalid value for a line number')
enddef
def Test_synIDattr()
- v9.CheckDefAndScriptFailure(['synIDattr("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['synIDattr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['synIDattr(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['synIDattr("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['synIDattr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['synIDattr(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
synIDattr(1, '', '')->assert_equal('')
enddef
def Test_synIDtrans()
- v9.CheckDefAndScriptFailure(['synIDtrans("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['synIDtrans("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_synconcealed()
- v9.CheckDefAndScriptFailure(['synconcealed(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['synconcealed(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['synconcealed(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['synconcealed(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
if has('conceal')
- v9.CheckDefExecAndScriptFailure(['synconcealed("", 4)'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefExecAndScriptFailure(['synconcealed("", 4)'], 'E1209: Invalid value for a line number')
endif
enddef
def Test_synstack()
- v9.CheckDefAndScriptFailure(['synstack(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['synstack(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['synstack("", 4)'], 'E1209: Invalid value for a line number')
+ v9.CheckSourceDefAndScriptFailure(['synstack(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['synstack(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['synstack("", 4)'], 'E1209: Invalid value for a line number')
enddef
def Test_system()
- v9.CheckDefAndScriptFailure(['system(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['system("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1224: String, Number or List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['system(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['system("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1224: String, Number or List required for argument 2'])
assert_equal("123\n", system('echo 123'))
enddef
def Test_systemlist()
- v9.CheckDefAndScriptFailure(['systemlist(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['systemlist("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1224: String, Number or List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['systemlist(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['systemlist("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1224: String, Number or List required for argument 2'])
if has('win32')
call assert_equal(["123\r"], systemlist('echo 123'))
else
@@ -4480,106 +4480,106 @@ def Test_systemlist()
enddef
def Test_tabpagebuflist()
- v9.CheckDefAndScriptFailure(['tabpagebuflist("t")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['tabpagebuflist("t")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
assert_equal([bufnr('')], tabpagebuflist())
assert_equal([bufnr('')], tabpagebuflist(1))
assert_equal(['x'], tabpagebuflist()->map((_, _) => 'x'))
enddef
def Test_tabpagenr()
- v9.CheckDefAndScriptFailure(['tabpagenr(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['tabpagenr("")'], 'E15: Invalid expression')
+ v9.CheckSourceDefAndScriptFailure(['tabpagenr(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['tabpagenr("")'], 'E15: Invalid expression')
assert_equal(1, tabpagenr('$'))
assert_equal(1, tabpagenr())
enddef
def Test_tabpagewinnr()
- v9.CheckDefAndScriptFailure(['tabpagewinnr("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['tabpagewinnr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['tabpagewinnr(1, "")'], 'E15: Invalid expression')
+ v9.CheckSourceDefAndScriptFailure(['tabpagewinnr("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['tabpagewinnr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['tabpagewinnr(1, "")'], 'E15: Invalid expression')
enddef
def Test_taglist()
- v9.CheckDefAndScriptFailure(['taglist([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['taglist("a", [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['taglist([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['taglist("a", [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2'])
taglist('')->assert_equal(0)
taglist('', '')->assert_equal(0)
enddef
def Test_term_dumpload()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_dumpload({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_dumpload({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_dumpload("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['term_dumpload("")'], 'E485: Can''t read file')
+ v9.CheckSourceDefAndScriptFailure(['term_dumpload({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_dumpload({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_dumpload("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['term_dumpload("")'], 'E485: Can''t read file')
enddef
def Test_term_dumpdiff()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_dumpdiff(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_dumpdiff("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['term_dumpdiff("a", "b", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
- v9.CheckDefExecAndScriptFailure(['term_dumpdiff("", "")'], 'E485: Can''t read file')
+ v9.CheckSourceDefAndScriptFailure(['term_dumpdiff(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_dumpdiff("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_dumpdiff("a", "b", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefExecAndScriptFailure(['term_dumpdiff("", "")'], 'E485: Can''t read file')
enddef
def Test_term_dumpwrite()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_dumpwrite(true, "b")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_dumpwrite(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['term_dumpwrite("a", "b", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['term_dumpwrite(true, "b")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_dumpwrite(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_dumpwrite("a", "b", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
enddef
def Test_term_getaltscreen()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_getaltscreen(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_getaltscreen(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1'])
enddef
def Test_term_getansicolors()
CheckRunVimInTerminal
CheckFeature termguicolors
- v9.CheckDefAndScriptFailure(['term_getansicolors(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_getansicolors(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 1'])
enddef
def Test_term_getattr()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_getattr("x", "a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_getattr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_getattr("x", "a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_getattr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
enddef
def Test_term_getcursor()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_getcursor({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_getcursor({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1220: String or Number required for argument 1'])
enddef
def Test_term_getjob()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_getjob(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_getjob(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
enddef
def Test_term_getline()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_getline(1.1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_getline(1, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_getline(1.1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_getline(1, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2'])
enddef
def Test_term_getscrolled()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_getscrolled(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_getscrolled(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
enddef
def Test_term_getsize()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_getsize(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_getsize(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
enddef
def Test_term_getstatus()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_getstatus(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_getstatus(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
enddef
def Test_term_gettitle()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_gettitle(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_gettitle(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
enddef
def Test_term_gettty()
@@ -4590,28 +4590,28 @@ def Test_term_gettty()
term_gettty(buf, true)->assert_notequal('')
g:StopShellInTerminal(buf)
endif
- v9.CheckDefAndScriptFailure(['term_gettty([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_gettty(1, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_gettty([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_gettty(1, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2'])
enddef
def Test_term_scrape()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_scrape(1.1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_scrape(1, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_scrape(1.1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_scrape(1, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2'])
enddef
def Test_term_sendkeys()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_sendkeys([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_sendkeys(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_sendkeys([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_sendkeys(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
enddef
def Test_term_setansicolors()
CheckRunVimInTerminal
if has('termguicolors') || has('gui')
- v9.CheckDefAndScriptFailure(['term_setansicolors([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_setansicolors(10, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_setansicolors([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_setansicolors(10, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2'])
else
throw 'Skipped: Only works with termguicolors or gui feature'
endif
@@ -4619,27 +4619,27 @@ enddef
def Test_term_setapi()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_setapi([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_setapi(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_setapi([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_setapi(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
enddef
def Test_term_setkill()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_setkill([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_setkill(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_setkill([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_setkill(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
enddef
def Test_term_setrestore()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_setrestore([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_setrestore(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_setrestore([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_setrestore(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2'])
enddef
def Test_term_setsize()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_setsize(1.1, 2, 3)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_setsize(1, "2", 3)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['term_setsize(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['term_setsize(1.1, 2, 3)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_setsize(1, "2", 3)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_setsize(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
enddef
def Test_term_start()
@@ -4652,76 +4652,76 @@ def Test_term_start()
winnr()->assert_equal(winnr)
bwipe!
endif
- v9.CheckDefAndScriptFailure(['term_start({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_start([], [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
- v9.CheckDefAndScriptFailure(['term_start("", "")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
- v9.CheckDefExecAndScriptFailure(['term_start("")'], 'E474: Invalid argument')
+ v9.CheckSourceDefAndScriptFailure(['term_start({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1222: String or List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_start([], [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_start("", "")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefExecAndScriptFailure(['term_start("")'], 'E474: Invalid argument')
enddef
def Test_term_wait()
CheckRunVimInTerminal
- v9.CheckDefAndScriptFailure(['term_wait(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['term_wait(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['term_wait(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['term_wait(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_test_alloc_fail()
- v9.CheckDefAndScriptFailure(['test_alloc_fail("a", 10, 20)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['test_alloc_fail(10, "b", 20)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['test_alloc_fail(10, 20, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['test_alloc_fail("a", 10, 20)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_alloc_fail(10, "b", 20)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['test_alloc_fail(10, 20, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
enddef
def Test_test_feedinput()
- v9.CheckDefAndScriptFailure(['test_feedinput(test_void())'], ['E1013: Argument 1: type mismatch, expected string but got void', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['test_feedinput(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_feedinput(test_void())'], ['E1013: Argument 1: type mismatch, expected string but got void', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_feedinput(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
enddef
def Test_test_getvalue()
- v9.CheckDefAndScriptFailure(['test_getvalue(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_getvalue(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1'])
enddef
def Test_test_gui_event()
CheckGui
- v9.CheckDefAndScriptFailure(['test_gui_event([], {})'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['test_gui_event("abc", 1)'], ['E1013: Argument 2: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['test_gui_event([], {})'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_gui_event("abc", 1)'], ['E1013: Argument 2: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 2'])
enddef
def Test_test_ignore_error()
- v9.CheckDefAndScriptFailure(['test_ignore_error([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_ignore_error([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
test_ignore_error('RESET')
enddef
def Test_test_option_not_set()
- v9.CheckDefAndScriptFailure(['test_option_not_set([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_option_not_set([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
enddef
def Test_test_override()
- v9.CheckDefAndScriptFailure(['test_override(1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['test_override("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['test_override(1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_override("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_test_setmouse()
- v9.CheckDefAndScriptFailure(['test_setmouse("a", 10)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['test_setmouse(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['test_setmouse("a", 10)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_setmouse(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_test_settime()
- v9.CheckDefAndScriptFailure(['test_settime([1])'], ['E1013: Argument 1: type mismatch, expected number but got list<number>', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_settime([1])'], ['E1013: Argument 1: type mismatch, expected number but got list<number>', 'E1210: Number required for argument 1'])
enddef
def Test_test_srand_seed()
- v9.CheckDefAndScriptFailure(['test_srand_seed([1])'], ['E1013: Argument 1: type mismatch, expected number but got list<number>', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['test_srand_seed("10")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_srand_seed([1])'], ['E1013: Argument 1: type mismatch, expected number but got list<number>', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['test_srand_seed("10")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_timer_info()
- v9.CheckDefAndScriptFailure(['timer_info("id")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['timer_info("id")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
assert_equal([], timer_info(100))
assert_equal([], timer_info()->filter((_, t) => t.callback->string() !~ 'TestTimeout'))
enddef
def Test_timer_pause()
- v9.CheckDefAndScriptFailure(['timer_pause("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['timer_pause(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['timer_pause("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['timer_pause(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2'])
enddef
def Test_timer_paused()
@@ -4733,31 +4733,31 @@ def Test_timer_paused()
enddef
def Test_timer_start()
- v9.CheckDefAndScriptFailure(['timer_start("a", "1")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['timer_start(1, "1", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
- v9.CheckDefExecAndScriptFailure(['timer_start(100, 0)'], 'E921:')
- v9.CheckDefExecAndScriptFailure(['timer_start(100, "")'], 'E921:')
+ v9.CheckSourceDefAndScriptFailure(['timer_start("a", "1")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['timer_start(1, "1", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefExecAndScriptFailure(['timer_start(100, 0)'], 'E921:')
+ v9.CheckSourceDefExecAndScriptFailure(['timer_start(100, "")'], 'E921:')
enddef
def Test_timer_stop()
- v9.CheckDefAndScriptFailure(['timer_stop("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['timer_stop("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
assert_equal(0, timer_stop(100))
enddef
def Test_tolower()
- v9.CheckDefAndScriptFailure(['tolower(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['tolower(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
tolower('')->assert_equal('')
enddef
def Test_toupper()
- v9.CheckDefAndScriptFailure(['toupper(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['toupper(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
toupper('')->assert_equal('')
enddef
def Test_tr()
- v9.CheckDefAndScriptFailure(['tr(1, "a", "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['tr("a", 1, "b")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['tr("a", "a", 1)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['tr(1, "a", "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['tr("a", 1, "b")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['tr("a", "a", 1)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
tr('', '', '')->assert_equal('')
tr('ab', '', '')->assert_equal('ab')
assert_fails("tr('ab', 'ab', '')", 'E475:')
@@ -4765,9 +4765,9 @@ def Test_tr()
enddef
def Test_trim()
- v9.CheckDefAndScriptFailure(['trim(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['trim("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1174: String required for argument 2'])
- v9.CheckDefAndScriptFailure(['trim("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['trim(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['trim("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1174: String required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['trim("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
trim('')->assert_equal('')
trim('', '')->assert_equal('')
enddef
@@ -4783,26 +4783,30 @@ def Test_typename()
if has('channel')
assert_equal('channel', test_null_channel()->typename())
endif
+ assert_equal('class<Unknown>', typename(null_class))
+ assert_equal('object<Unknown>', typename(null_object))
+ var l: list<func(list<number>): number> = [function('min')]
+ assert_equal('list<func(list<number>): number>', typename(l))
enddef
def Test_undofile()
- v9.CheckDefAndScriptFailure(['undofile(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['undofile(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
assert_equal('.abc.un~', fnamemodify(undofile('abc'), ':t'))
undofile('')->assert_equal('')
enddef
def Test_uniq()
- v9.CheckDefAndScriptFailure(['uniq("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
- v9.CheckDefAndScriptFailure(['uniq([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['uniq("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['uniq([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
- v9.CheckDefFailure(['var l: list<number> = uniq(["a", "b"])'], 'E1012: Type mismatch; expected list<number> but got list<string>')
+ v9.CheckSourceDefFailure(['var l: list<number> = uniq(["a", "b"])'], 'E1012: Type mismatch; expected list<number> but got list<string>')
enddef
def Test_utf16idx()
- v9.CheckDefAndScriptFailure(['utf16idx(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['utf16idx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['utf16idx("a", 1, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
- v9.CheckDefAndScriptFailure(['utf16idx("a", 1, 0, "")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4'])
+ v9.CheckSourceDefAndScriptFailure(['utf16idx(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['utf16idx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['utf16idx("a", 1, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['utf16idx("a", 1, 0, "")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4'])
utf16idx('', 0)->assert_equal(0)
utf16idx('', 1)->assert_equal(-1)
enddef
@@ -4812,11 +4816,11 @@ def Test_uniq_const()
const l = [1, 2, 3, 4]
uniq(l)
END
- v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
+ v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>')
enddef
def Test_values()
- v9.CheckDefAndScriptFailure(['values([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['values([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
assert_equal([], {}->values())
assert_equal(['sun'], {star: 'sun'}->values())
@@ -4843,20 +4847,20 @@ def Test_values()
Process(D)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceScriptSuccess(lines)
enddef
def Test_virtcol()
- v9.CheckDefAndScriptFailure(['virtcol(1.1)'], [
+ v9.CheckSourceDefAndScriptFailure(['virtcol(1.1)'], [
'E1013: Argument 1: type mismatch, expected string but got float',
'E1222: String or List required for argument 1'])
- v9.CheckDefAndScriptFailure(['virtcol(".", "a")'], [
+ v9.CheckSourceDefAndScriptFailure(['virtcol(".", "a")'], [
'E1013: Argument 2: type mismatch, expected bool but got string',
'E1212: Bool required for argument 2'])
- v9.CheckDefAndScriptFailure(['virtcol(".", v:true, [])'], [
+ v9.CheckSourceDefAndScriptFailure(['virtcol(".", v:true, [])'], [
'E1013: Argument 3: type mismatch, expected number but got list',
'E1210: Number required for argument 3'])
- v9.CheckDefExecAndScriptFailure(['virtcol("")'],
+ v9.CheckSourceDefExecAndScriptFailure(['virtcol("")'],
'E1209: Invalid value for a line number')
new
setline(1, ['abcde和平fgh'])
@@ -4872,8 +4876,8 @@ def Test_virtcol()
enddef
def Test_visualmode()
- v9.CheckDefAndScriptFailure(['visualmode("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
- v9.CheckDefAndScriptFailure(['visualmode(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['visualmode("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['visualmode(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1'])
enddef
def Test_win_execute()
@@ -4881,29 +4885,29 @@ def Test_win_execute()
assert_equal("\n" .. winnr(), 'echo winnr()'->win_execute(win_getid()))
assert_equal("\n" .. winnr(), win_execute(win_getid(), 'echo winnr()', 'silent'))
assert_equal('', win_execute(342343, 'echo winnr()'))
- v9.CheckDefAndScriptFailure(['win_execute("a", "b", "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['win_execute(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1222: String or List required for argument 2'])
- v9.CheckDefAndScriptFailure(['win_execute(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['win_execute("a", "b", "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['win_execute(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1222: String or List required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['win_execute(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'])
enddef
def Test_win_findbuf()
- v9.CheckDefAndScriptFailure(['win_findbuf("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['win_findbuf("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
assert_equal([], win_findbuf(1000))
assert_equal([win_getid()], win_findbuf(bufnr('')))
enddef
def Test_win_getid()
- v9.CheckDefAndScriptFailure(['win_getid(".")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['win_getid(1, ".")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['win_getid(".")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['win_getid(1, ".")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
assert_equal(win_getid(), win_getid(1, 1))
enddef
def Test_win_gettype()
- v9.CheckDefAndScriptFailure(['win_gettype("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['win_gettype("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_win_gotoid()
- v9.CheckDefAndScriptFailure(['win_gotoid("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['win_gotoid("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
func Test_win_gotoid_in_mapping()
@@ -4948,43 +4952,43 @@ func Test_win_gotoid_in_mapping()
endfunc
def Test_win_id2tabwin()
- v9.CheckDefAndScriptFailure(['win_id2tabwin("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['win_id2tabwin("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_win_id2win()
- v9.CheckDefAndScriptFailure(['win_id2win("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['win_id2win("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_win_screenpos()
assert_equal(['x', 'x'], win_screenpos(1)->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['win_screenpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['win_screenpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_win_splitmove()
split
win_splitmove(1, 2, {vertical: true, rightbelow: true})
close
- v9.CheckDefAndScriptFailure(['win_splitmove("a", 2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['win_splitmove(1, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
- v9.CheckDefAndScriptFailure(['win_splitmove(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
+ v9.CheckSourceDefAndScriptFailure(['win_splitmove("a", 2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['win_splitmove(1, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['win_splitmove(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3'])
enddef
def Test_winbufnr()
- v9.CheckDefAndScriptFailure(['winbufnr("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['winbufnr("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_winheight()
- v9.CheckDefAndScriptFailure(['winheight("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['winheight("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_winlayout()
- v9.CheckDefAndScriptFailure(['winlayout("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['winlayout("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_winnr()
- v9.CheckDefAndScriptFailure(['winnr([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
- v9.CheckDefExecAndScriptFailure(['winnr("")'], 'E15: Invalid expression')
+ v9.CheckSourceDefAndScriptFailure(['winnr([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1'])
+ v9.CheckSourceDefExecAndScriptFailure(['winnr("")'], 'E15: Invalid expression')
assert_equal(1, winnr())
assert_equal(1, winnr('$'))
enddef
@@ -4999,7 +5003,7 @@ def Test_winrestcmd()
enddef
def Test_winrestview()
- v9.CheckDefAndScriptFailure(['winrestview([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['winrestview([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1'])
:%d _
setline(1, 'Hello World')
winrestview({lnum: 1, col: 6})
@@ -5012,20 +5016,20 @@ def Test_winsaveview()
var lines =<< trim END
var view: list<number> = winsaveview()
END
- v9.CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list<number> but got dict<number>', 1)
+ v9.CheckSourceDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list<number> but got dict<number>', 1)
enddef
def Test_winwidth()
- v9.CheckDefAndScriptFailure(['winwidth("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['winwidth("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
enddef
def Test_xor()
- v9.CheckDefAndScriptFailure(['xor("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
- v9.CheckDefAndScriptFailure(['xor(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
+ v9.CheckSourceDefAndScriptFailure(['xor("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['xor(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2'])
enddef
def Test_writefile()
- v9.CheckDefExecAndScriptFailure(['writefile(["a"], "")'], 'E482: Can''t create file <empty>')
+ v9.CheckSourceDefExecAndScriptFailure(['writefile(["a"], "")'], 'E482: Can''t create file <empty>')
enddef
def Test_passing_type_to_builtin()
@@ -5045,7 +5049,7 @@ def Test_passing_type_to_builtin()
x = string(T)
x = instanceof(C.new(), U, C)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceScriptSuccess(lines)
# check argument to add at script level
# Note: add() is special cased in compile_call in vim9expr
@@ -5055,7 +5059,7 @@ def Test_passing_type_to_builtin()
endclass
add([], C)
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# check argument to add in :def
lines =<< trim END
@@ -5067,7 +5071,7 @@ def Test_passing_type_to_builtin()
enddef
F()
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# check member call argument to add at script level
lines =<< trim END
@@ -5076,7 +5080,7 @@ def Test_passing_type_to_builtin()
endclass
[]->add(C)
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# check member call argument to add in :def
lines =<< trim END
@@ -5088,7 +5092,7 @@ def Test_passing_type_to_builtin()
enddef
F()
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# Try "empty()" builtin
# check argument to empty at script level
@@ -5098,7 +5102,7 @@ def Test_passing_type_to_builtin()
endclass
empty(C)
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# check argument to empty in :def
lines =<< trim END
@@ -5110,7 +5114,7 @@ def Test_passing_type_to_builtin()
enddef
F()
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# check member call argument to empty at script level
lines =<< trim END
@@ -5119,7 +5123,7 @@ def Test_passing_type_to_builtin()
endclass
C->empty()
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# check member call argument to empty in :def
lines =<< trim END
@@ -5131,7 +5135,7 @@ def Test_passing_type_to_builtin()
enddef
F()
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# Try "abs()" builtin
# check argument to abs at script level
@@ -5141,7 +5145,7 @@ def Test_passing_type_to_builtin()
endclass
abs(C)
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# check argument to abs in :def
lines =<< trim END
@@ -5153,7 +5157,7 @@ def Test_passing_type_to_builtin()
enddef
F()
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# check member call argument to abs at script level
lines =<< trim END
@@ -5162,7 +5166,7 @@ def Test_passing_type_to_builtin()
endclass
C->abs()
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
# check member call argument to abs in :def
lines =<< trim END
@@ -5174,15 +5178,15 @@ def Test_passing_type_to_builtin()
enddef
F()
END
- v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+ v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
enddef
def Test_getregion()
assert_equal(['x'], getregion(getpos('.'), getpos('.'))->map((_, _) => 'x'))
- v9.CheckDefAndScriptFailure(['getregion(10, getpos("."))'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['getregion(10, getpos("."))'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1'])
assert_equal([''], getregion(getpos('.'), getpos('.')))
- v9.CheckDefExecFailure(['getregion(getpos("a"), getpos("."))'], 'E1209:')
+ v9.CheckSourceDefExecFailure(['getregion(getpos("a"), getpos("."))'], 'E1209:')
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index d6c55bf..5957f57 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -400,7 +400,7 @@ def Test_class_def_method()
enddef
endclass
END
- v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
+ v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
# Using the "public" keyword when defining a class method
lines =<< trim END
@@ -410,7 +410,7 @@ def Test_class_def_method()
enddef
endclass
END
- v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
+ v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
# Using the "public" keyword when defining an object protected method
lines =<< trim END
@@ -420,7 +420,7 @@ def Test_class_def_method()
enddef
endclass
END
- v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
+ v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
# Using the "public" keyword when defining a class protected method
lines =<< trim END
@@ -430,7 +430,7 @@ def Test_class_def_method()
enddef
endclass
END
- v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
+ v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
# Using a "def" keyword without an object method name
lines =<< trim END
@@ -1191,7 +1191,7 @@ def Test_instance_variable_access()
public var _val = 10
endclass
END
- v9.CheckSourceFailure(lines, 'E1332: Public variable name cannot start with underscore: public var _val = 10', 3)
+ v9.CheckSourceFailure(lines, 'E1332: public variable name cannot start with underscore: public var _val = 10', 3)
lines =<< trim END
vim9script
@@ -1287,7 +1287,7 @@ def Test_instance_variable_access()
public val = 1
endclass
END
- v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
+ v9.CheckSourceFailure(lines, 'E1331: public must be followed by "var" or "static"', 3)
# Modify a instance variable using the class name in the script context
lines =<< trim END
@@ -2275,6 +2275,18 @@ def Test_interface_basics()
v9.CheckScriptSuccess(lines)
enddef
+" Test for using string() with an interface
+def Test_interface_to_string()
+ var lines =<< trim END
+ vim9script
+ interface Intf
+ def Method(nr: number)
+ endinterface
+ assert_equal("interface Intf", string(Intf))
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
def Test_class_implements_interface()
var lines =<< trim END
vim9script
@@ -3109,6 +3121,28 @@ def Test_class_import()
v9.CheckScriptSuccess(lines)
enddef
+" Test for importing a class into a legacy script and calling the class method
+def Test_class_method_from_legacy_script()
+ var lines =<< trim END
+ vim9script
+ export class A
+ static var name: string = 'a'
+ static def SetName(n: string)
+ name = n
+ enddef
+ endclass
+ END
+ writefile(lines, 'Xvim9export.vim', 'D')
+
+ lines =<< trim END
+ import './Xvim9export.vim' as vim9
+
+ call s:vim9.A.SetName('b')
+ call assert_equal('b', s:vim9.A.name)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
" Test for implementing an imported interface
def Test_implement_imported_interface()
var lines =<< trim END
@@ -3208,6 +3242,23 @@ def Test_abstract_class()
endclass
END
v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
+
+ # extending an abstract class with class methods and variables
+ lines =<< trim END
+ vim9script
+ abstract class A
+ static var s: string = 'vim'
+ static def Fn(): list<number>
+ return [10]
+ enddef
+ endclass
+ class B extends A
+ endclass
+ var b = B.new()
+ assert_equal('vim', A.s)
+ assert_equal([10], A.Fn())
+ END
+ v9.CheckScriptSuccess(lines)
enddef
def Test_closure_in_class()
@@ -3729,7 +3780,7 @@ def Test_stack_expansion_with_methods()
endclass
def F0()
- assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
+ assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
enddef
def F()
@@ -6486,7 +6537,7 @@ def Test_interface_with_unsupported_members()
public static var num: number
endinterface
END
- v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
+ v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
lines =<< trim END
vim9script
@@ -6494,7 +6545,7 @@ def Test_interface_with_unsupported_members()
public static var num: number
endinterface
END
- v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
+ v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
lines =<< trim END
vim9script
@@ -10391,6 +10442,23 @@ def Test_compound_op_in_objmethod_lambda()
v9.CheckScriptSuccess(lines)
enddef
+" Test for using test_refcount() with a class and an object
+def Test_class_object_refcount()
+ var lines =<< trim END
+ vim9script
+ class A
+ endclass
+ var a: A = A.new()
+ assert_equal(2, test_refcount(A))
+ assert_equal(1, test_refcount(a))
+ var b = a
+ assert_equal(2, test_refcount(A))
+ assert_equal(2, test_refcount(a))
+ assert_equal(2, test_refcount(b))
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
" call a lambda function in one object from another object
def Test_lambda_invocation_across_classes()
var lines =<< trim END
@@ -10420,4 +10488,154 @@ def Test_lambda_invocation_across_classes()
v9.CheckScriptSuccess(lines)
enddef
+" Test for using a class member which is an object of the current class
+def Test_current_class_object_class_member()
+ var lines =<< trim END
+ vim9script
+ class A
+ public static var obj1: A = A.new(10)
+ var n: number
+ endclass
+ defcompile
+ assert_equal(10, A.obj1.n)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
+" Test for updating a base class variable from a base class method without the
+" class name. This used to crash Vim (Github issue #14352).
+def Test_use_base_class_variable_from_base_class_method()
+ var lines =<< trim END
+ vim9script
+
+ class DictKeyClass
+ static var _obj_id_count = 1
+ def _GenerateKey()
+ _obj_id_count += 1
+ enddef
+ static def GetIdCount(): number
+ return _obj_id_count
+ enddef
+ endclass
+
+ class C extends DictKeyClass
+ def F()
+ this._GenerateKey()
+ enddef
+ endclass
+
+ C.new().F()
+ assert_equal(2, DictKeyClass.GetIdCount())
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
+" Test for accessing protected funcref object and class variables
+def Test_protected_funcref()
+ # protected funcref object variable
+ var lines =<< trim END
+ vim9script
+ class Test1
+ const _Id: func(any): any = (v) => v
+ endclass
+ var n = Test1.new()._Id(1)
+ END
+ v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
+
+ # protected funcref class variable
+ lines =<< trim END
+ vim9script
+ class Test2
+ static const _Id: func(any): any = (v) => v
+ endclass
+ var n = Test2._Id(2)
+ END
+ v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
+enddef
+
+" Test for using lambda block in classes
+def Test_lambda_block_in_class()
+ # This used to crash Vim
+ var lines =<< trim END
+ vim9script
+ class IdClass1
+ const Id: func(number): number = (num: number): number => {
+ # Return a ID
+ return num * 10
+ }
+ endclass
+ var id = IdClass1.new()
+ assert_equal(20, id.Id(2))
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # This used to crash Vim
+ lines =<< trim END
+ vim9script
+ class IdClass2
+ static const Id: func(number): number = (num: number): number => {
+ # Return a ID
+ return num * 2
+ }
+ endclass
+ assert_equal(16, IdClass2.Id(8))
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
+" Test for defcompiling an abstract method
+def Test_abstract_method_defcompile()
+ # Compile an abstract class with abstract object methods
+ var lines =<< trim END
+ vim9script
+ abstract class A
+ abstract def Foo(): string
+ abstract def Bar(): list<string>
+ endclass
+ defcompile
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # Compile a concrete object method in an abstract class
+ lines =<< trim END
+ vim9script
+ abstract class A
+ abstract def Foo(): string
+ abstract def Bar(): list<string>
+ def Baz(): string
+ pass
+ enddef
+ endclass
+ defcompile
+ END
+ v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
+
+ # Compile a concrete class method in an abstract class
+ lines =<< trim END
+ vim9script
+ abstract class A
+ abstract def Foo(): string
+ abstract def Bar(): list<string>
+ static def Baz(): string
+ pass
+ enddef
+ endclass
+ defcompile
+ END
+ v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
+enddef
+
+" Test for defining a class in a function
+def Test_class_definition_in_a_function()
+ var lines =<< trim END
+ vim9script
+ def Foo()
+ class A
+ endclass
+ enddef
+ defcompile
+ END
+ v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
+enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim
index 1daef22..c74cce4 100644
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -381,6 +381,34 @@ def Test_disassemble_import_autoload()
v9.CheckScriptSuccess(lines)
enddef
+def Test_disassemble_import_autoload_autoload()
+ mkdir('Xauto_auto/autoload', 'pR')
+ var lines =<< trim END
+ vim9script
+ export const val = 11
+ END
+ writefile(lines, 'Xauto_auto/autoload/Xauto_vars_f1.vim')
+
+ lines =<< trim END
+ vim9script
+
+ import autoload './Xauto_auto/autoload/Xauto_vars_f1.vim' as f1
+ def F()
+ f1.val = 13
+ enddef
+ var res = execute('disass F')
+
+ assert_match('<SNR>\d*_F.*' ..
+ 'f1.val = 13\_s*' ..
+ '\d PUSHNR 13\_s*' ..
+ '\d SOURCE .*/Xauto_auto/autoload/Xauto_vars_f1.vim\_s*' ..
+ '\d STOREEXPORT val in .*/Xauto_auto/autoload/Xauto_vars_f1.vim\_s*' ..
+ '\d RETURN void',
+ res)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
def s:ScriptFuncStore()
var localnr = 1
localnr = 2
@@ -1030,7 +1058,7 @@ def Test_disassemble_closure_in_loop()
'endif\_s*' ..
'g:Ref = () => ii\_s*' ..
- '\d\+ FUNCREF <lambda>4 vars $3-$3\_s*' ..
+ '\d\+ FUNCREF <lambda>\d\+ vars $3-$3\_s*' ..
'\d\+ STOREG g:Ref\_s*' ..
'continue\_s*' ..
diff --git a/src/testdir/test_vim9_enum.vim b/src/testdir/test_vim9_enum.vim
new file mode 100644
index 0000000..274b556
--- /dev/null
+++ b/src/testdir/test_vim9_enum.vim
@@ -0,0 +1,1537 @@
+" Test Vim9 enums
+
+source check.vim
+import './vim9.vim' as v9
+
+" Test for parsing an enum definition
+def Test_enum_parse()
+ # enum supported only in a Vim9 script
+ var lines =<< trim END
+ enum Foo
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1414: Enum can only be defined in Vim9 script', 1)
+
+ # First character in an enum name should be capitalized.
+ lines =<< trim END
+ vim9script
+ enum foo
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1415: Enum name must start with an uppercase letter: foo', 2)
+
+ # Only alphanumeric characters are supported in an enum name
+ lines =<< trim END
+ vim9script
+ enum Foo@bar
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1315: White space required after name: Foo@bar', 2)
+
+ # Unsupported keyword (instead of enum)
+ lines =<< trim END
+ vim9script
+ noenum Something
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E492: Not an editor command: noenum Something', 2)
+
+ # Only the complete word "enum" should be recognized
+ lines =<< trim END
+ vim9script
+ enums Something
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E492: Not an editor command: enums Something', 2)
+
+ # The complete "endenum" should be specified.
+ lines =<< trim END
+ vim9script
+ enum Something
+ enden
+ END
+ v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: enden', 3)
+
+ # Only the complete word "endenum" should be recognized
+ lines =<< trim END
+ vim9script
+ enum Something
+ endenums
+ END
+ v9.CheckSourceFailure(lines, 'E1420: Missing :endenum', 4)
+
+ # all lower case should be used for "enum"
+ lines =<< trim END
+ vim9script
+ Enum Something
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E492: Not an editor command: Enum Something', 2)
+
+ # all lower case should be used for "endenum"
+ lines =<< trim END
+ vim9script
+ enum Something
+ Endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1420: Missing :endenum', 4)
+
+ # Additional words after "endenum"
+ lines =<< trim END
+ vim9script
+ enum Something
+ endenum school's out
+ END
+ v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
+
+ # Additional commands after "endenum"
+ lines =<< trim END
+ vim9script
+ enum Something
+ endenum | echo 'done'
+ END
+ v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
+
+ # Try to define enum in a single command
+ lines =<< trim END
+ vim9script
+ enum Something | endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1420: Missing :endenum', 3)
+
+ # Try to define an enum with the same name as an existing variable
+ lines =<< trim END
+ vim9script
+ var Something: list<number> = [1]
+ enum Something
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 3)
+
+ # Unsupported special character following enum name
+ lines =<< trim END
+ vim9script
+ enum Foo
+ first,
+ second : 20
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: : 20', 4)
+
+ # Try initializing an enum item with a number
+ lines =<< trim END
+ vim9script
+ enum Foo
+ first,
+ second = 2
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: = 2', 4)
+
+ # Try initializing an enum item with a String
+ lines =<< trim END
+ vim9script
+ enum Foo
+ first,
+ second = 'second'
+ endenum
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, "E1123: Missing comma before argument: = 'second'", 4)
+
+ # Try initializing an enum item with a List
+ lines =<< trim END
+ vim9script
+ enum Foo
+ first,
+ second = []
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: = []', 4)
+
+ # Use a colon after name
+ lines =<< trim END
+ vim9script
+ enum Foo
+
+ # first
+ first:
+ second
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: :', 5)
+
+ # Use a '=='
+ lines =<< trim END
+ vim9script
+ enum Foo
+ first == 1
+ endenum
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: == 1', 3)
+
+ # Missing comma after an enum item
+ lines =<< trim END
+ vim9script
+ enum Planet
+ mercury
+ venus
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1419: Not a valid command in an Enum: venus', 4)
+
+ # Comma at the beginning of an item
+ lines =<< trim END
+ vim9script
+ enum Planet
+ mercury
+ ,venus
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1419: Not a valid command in an Enum: ,venus', 4)
+ # Space before comma
+ lines =<< trim END
+ vim9script
+ enum Planet
+ mercury ,
+ venus
+ endenum
+ END
+ v9.CheckSourceFailure(lines, "E1068: No white space allowed before ','", 3)
+
+ # No space after comma
+ lines =<< trim END
+ vim9script
+ enum Planet
+ mercury,venus
+ endenum
+ END
+ v9.CheckSourceFailure(lines, "E1069: White space required after ',': mercury,venus", 3)
+
+ # no comma between items in the same line
+ lines =<< trim END
+ vim9script
+ enum Planet
+ mercury venus earth
+ endenum
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: venus earth', 3)
+
+ # No space after an item and comment between items
+ lines =<< trim END
+ vim9script
+ enum Planet
+ mercury
+
+ # Venus
+ venus
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1419: Not a valid command in an Enum: venus', 6)
+
+ # Comma is supported for the last item
+ lines =<< trim END
+ vim9script
+ enum Planet
+ mercury,
+ venus,
+ endenum
+ var p: Planet
+ p = Planet.mercury
+ p = Planet.venus
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # invalid enum value declaration
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple,
+ $%@
+ endenum
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1418: Invalid enum value declaration: $%@', 4)
+
+ # Duplicate enum value
+ lines =<< trim END
+ vim9script
+ enum A
+ Foo,
+ Bar,
+ Foo
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1428: Duplicate enum value: Foo', 5)
+
+ # Duplicate enum value in the same line
+ lines =<< trim END
+ vim9script
+ enum A
+ Foo, Bar, Foo,
+ Bar
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1428: Duplicate enum value: Foo', 3)
+
+ # Try extending a class when defining an enum
+ lines =<< trim END
+ vim9script
+ class Foo
+ endclass
+ enum Bar extends Foo
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1416: Enum cannot extend a class or enum', 4)
+
+ # Try extending an enum
+ lines =<< trim END
+ vim9script
+ enum Foo
+ endenum
+ enum Bar extends Foo
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1416: Enum cannot extend a class or enum', 4)
+
+ # Try extending an enum using a class
+ lines =<< trim END
+ vim9script
+ enum Foo
+ endenum
+ class Bar extends Foo
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1354: Cannot extend Foo', 5)
+
+ # Try implementing an enum using a class
+ lines =<< trim END
+ vim9script
+ enum Foo
+ endenum
+ class Bar implements Foo
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: Foo', 5)
+
+ # abstract method is not supported in an enum
+ lines =<< trim END
+ vim9script
+ enum Foo
+ Apple
+ abstract def Bar()
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1417: Abstract cannot be used in an Enum', 4)
+
+ # Define an enum without any enum values but only with an object variable
+ lines =<< trim END
+ vim9script
+ enum Foo
+ final n: number = 10
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: n: number = 10', 3)
+enddef
+
+def Test_basic_enum()
+ # Declare a simple enum
+ var lines =<< trim END
+ vim9script
+ enum Foo
+ apple,
+ orange
+ endenum
+ var a: Foo = Foo.apple
+ var b: Foo = Foo.orange
+ assert_equal(a, Foo.apple)
+ assert_equal(b, Foo.orange)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Multiple enums in a single line
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple, orange
+ endenum
+ assert_equal('enum<Foo>', typename(Foo.apple))
+ assert_equal('enum<Foo>', typename(Foo.orange))
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Comments and empty lines are supported between enum items
+ lines =<< trim END
+ vim9script
+ enum Foo
+ # Apple
+ apple,
+
+ # Orange
+ orange
+ endenum
+ def Fn()
+ var a: Foo = Foo.apple
+ var b: Foo = Foo.orange
+ assert_equal(a, Foo.apple)
+ assert_equal(b, Foo.orange)
+ enddef
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Try using a non-existing enum value
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple,
+ orange
+ endenum
+ var a: Foo = Foo.pear
+ END
+ v9.CheckSourceFailure(lines, 'E1422: Enum value "pear" not found in enum "Foo"', 6)
+
+ # Enum function argument
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple,
+ orange
+ endenum
+ def Fn(a: Foo): Foo
+ return a
+ enddef
+ assert_equal(Foo.apple, Fn(Foo.apple))
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Enum function argument
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple,
+ orange
+ endenum
+ def Fn(a: Foo): Foo
+ return a
+ enddef
+ Fn({})
+ END
+ v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected enum<Foo> but got dict<any>', 9)
+
+ # Returning an enum in a function returning number
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple,
+ orange
+ endenum
+ def Fn(): number
+ return Foo.orange
+ enddef
+ Fn()
+ END
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got enum<Foo>', 1)
+
+ # Returning a number in a function returning enum
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple,
+ orange
+ endenum
+ def Fn(): Foo
+ return 20
+ enddef
+ Fn()
+ END
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 1)
+
+ # Use a List of enums
+ lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury,
+ Venus,
+ Earth
+ endenum
+ var l1: list<Planet> = [Planet.Mercury, Planet.Venus]
+ assert_equal(Planet.Venus, l1[1])
+ def Fn()
+ var l2: list<Planet> = [Planet.Mercury, Planet.Venus]
+ assert_equal(Planet.Venus, l2[1])
+ enddef
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Try using an enum as a value
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple,
+ Orange
+ endenum
+ var a = Fruit
+ END
+ v9.CheckSourceFailure(lines, 'E1421: Enum "Fruit" cannot be used as a value', 6)
+enddef
+
+" Test for type() and typename() of an enum
+def Test_enum_type()
+ var lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple,
+ Orange
+ endenum
+ assert_equal('enum<Fruit>', typename(Fruit))
+ assert_equal('enum<Fruit>', typename(Fruit.Apple))
+ assert_equal(v:t_enum, type(Fruit))
+ assert_equal(v:t_enumvalue, type(Fruit.Apple))
+ assert_equal(15, type(Fruit))
+ assert_equal(16, type(Fruit.Apple))
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Assign an enum to a variable with any type
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple,
+ Orange
+ endenum
+ var a = Fruit.Apple
+ var b: any = Fruit.Orange
+ assert_equal('enum<Fruit>', typename(a))
+ assert_equal('enum<Fruit>', typename(b))
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Try modifying an enum or an enum item
+def Test_enum_modify()
+ # Try assigning an unsupported value to an enum
+ var lines =<< trim END
+ vim9script
+ enum Foo
+ apple
+ endenum
+ var a: Foo = 30
+ END
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 5)
+
+ # Try assigning an unsupported value to an enum in a function
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple
+ endenum
+ def Fn()
+ var a: Foo = 30
+ enddef
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 1)
+
+ # Try assigning a number to an enum
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple,
+ orange
+ endenum
+ Foo = 10
+ END
+ v9.CheckSourceFailure(lines, 'E1421: Enum "Foo" cannot be used as a value', 6)
+
+ # Try assigning a number to an enum in a function
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple
+ endenum
+ def Fn()
+ Foo = 10
+ enddef
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 1)
+
+ # Try assigning a number to an enum value
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple
+ endenum
+ Foo.apple = 20
+ END
+ v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.apple" cannot be modified', 5)
+
+ # Try assigning a number to an enum value in a function
+ lines =<< trim END
+ vim9script
+ enum Foo
+ apple
+ endenum
+ def Fn()
+ Foo.apple = 20
+ enddef
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.apple" cannot be modified', 1)
+
+ # Try assigning one enum to another
+ lines =<< trim END
+ vim9script
+ enum Foo
+ endenum
+ enum Bar
+ endenum
+ Foo = Bar
+ END
+ v9.CheckSourceFailure(lines, 'E1421: Enum "Bar" cannot be used as a value', 6)
+
+ # Try assigning one enum to another in a function
+ lines =<< trim END
+ vim9script
+ enum Foo
+ endenum
+ enum Bar
+ endenum
+ def Fn()
+ Foo = Bar
+ enddef
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1421: Enum "Bar" cannot be used as a value', 1)
+
+ # Try assigning one enum item to another enum item
+ lines =<< trim END
+ vim9script
+ enum Foo
+ Apple
+ endenum
+ enum Bar
+ Orange
+ endenum
+ Foo.Apple = Bar.Orange
+ END
+ v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.Apple" cannot be modified', 8)
+
+ # Try assigning one enum item to another enum item in a function
+ lines =<< trim END
+ vim9script
+ enum Foo
+ Apple
+ endenum
+ enum Bar
+ Orange
+ endenum
+ def Fn()
+ Foo.Apple = Bar.Orange
+ enddef
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.Apple" cannot be modified', 1)
+enddef
+
+" Test for using enum in an expression
+def Test_enum_expr()
+ var lines =<< trim END
+ vim9script
+ enum Color
+ Red, Blue, Green
+ endenum
+ var a: number = 1 + Color
+ END
+ v9.CheckSourceFailure(lines, 'E1421: Enum "Color" cannot be used as a value', 5)
+
+ lines =<< trim END
+ vim9script
+ enum Color
+ Red, Blue, Green
+ endenum
+ var a: number = 1 + Color.Red
+ END
+ v9.CheckSourceFailure(lines, 'E1424: Using an Enum "Color" as a Number', 5)
+
+ lines =<< trim END
+ vim9script
+ enum Color
+ Red, Blue, Green
+ endenum
+ var s: string = "abc" .. Color
+ END
+ v9.CheckSourceFailure(lines, 'E1421: Enum "Color" cannot be used as a value', 5)
+
+ lines =<< trim END
+ vim9script
+ enum Color
+ Red, Blue, Green
+ endenum
+ var s: string = "abc" .. Color.Red
+ END
+ v9.CheckSourceFailure(lines, 'E1425: Using an Enum "Color" as a String', 5)
+enddef
+
+" Using an enum in a lambda function
+def Test_enum_lambda()
+ var lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury,
+ Venus,
+ Earth,
+ endenum
+ var Fn = (p: Planet): Planet => p
+ for [idx, v] in items([Planet.Mercury, Planet.Venus, Planet.Earth])
+ assert_equal(idx, Fn(v).ordinal)
+ endfor
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Comparison using enums
+def Test_enum_compare()
+ var lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury,
+ Venus,
+ Earth,
+ endenum
+ enum Fruit
+ Apple,
+ Orange
+ endenum
+
+ var p: Planet = Planet.Venus
+ var f: Fruit = Fruit.Orange
+ assert_equal(true, p == Planet.Venus)
+ assert_equal(false, p == Planet.Earth)
+ assert_equal(false, p == f)
+ assert_equal(true, Planet.Mercury == Planet.Mercury)
+ assert_equal(true, Planet.Venus != Planet.Earth)
+ assert_equal(true, Planet.Mercury != Fruit.Apple)
+
+ def Fn1()
+ var p2: Planet = Planet.Venus
+ var f2: Fruit = Fruit.Orange
+ assert_equal(true, p2 == Planet.Venus)
+ assert_equal(false, p2 == Planet.Earth)
+ assert_equal(false, p2 == f2)
+ enddef
+ Fn1()
+
+ # comparison using "is" and "isnot"
+ assert_equal(true, p is Planet.Venus)
+ assert_equal(true, p isnot Planet.Earth)
+ assert_equal(false, p is Fruit.Orange)
+ assert_equal(true, p isnot Fruit.Orange)
+ def Fn2(arg: Planet)
+ assert_equal(true, arg is Planet.Venus)
+ assert_equal(true, arg isnot Planet.Earth)
+ assert_equal(false, arg is Fruit.Orange)
+ assert_equal(true, arg isnot Fruit.Orange)
+ enddef
+ Fn2(p)
+
+ class A
+ endclass
+ var o: A = A.new()
+ assert_equal(false, p == o)
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using an enum as a default argument to a function
+def Test_enum_default_arg()
+ var lines =<< trim END
+ vim9script
+ enum Day
+ Monday, Tuesday, Wednesday
+ endenum
+ def Fn(d: Day = Day.Tuesday): Day
+ return d
+ enddef
+ assert_equal(Day.Tuesday, Fn())
+ assert_equal(Day.Wednesday, Fn(Day.Wednesday))
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for enum garbage collection
+func Test_enum_garbagecollect()
+ let lines =<< trim END
+ vim9script
+ enum Car
+ Honda, Ford, Tesla
+ endenum
+ assert_equal(1, Car.Ford.ordinal)
+ call test_garbagecollect_now()
+ assert_equal(1, Car.Ford.ordinal)
+ var c: Car = Car.Tesla
+ assert_equal(2, c.ordinal)
+ call test_garbagecollect_now()
+ assert_equal(2, c.ordinal)
+ END
+ call v9.CheckSourceSuccess(lines)
+
+ " garbage collection with a variable of type any
+ let lines =<< trim END
+ vim9script
+ enum Car
+ Honda, Ford, Tesla
+ endenum
+ call test_garbagecollect_now()
+ var c: any = Car.Tesla
+ call test_garbagecollect_now()
+ assert_equal(Car.Tesla, c)
+ END
+ call v9.CheckSourceSuccess(lines)
+
+ " garbage collection with function arguments and return types
+ let lines =<< trim END
+ vim9script
+ enum Car
+ Honda, Ford, Tesla
+ endenum
+ def Fn(a: Car): Car
+ assert_equal(Car.Ford, a)
+ return Car.Tesla
+ enddef
+ call test_garbagecollect_now()
+ var b: Car = Car.Ford
+ call test_garbagecollect_now()
+ assert_equal(Car.Tesla, Fn(b))
+ call test_garbagecollect_now()
+ END
+ call v9.CheckSourceSuccess(lines)
+endfunc
+
+" Test for the enum values class variable
+def Test_enum_values()
+ var lines =<< trim END
+ vim9script
+ enum Car
+ Honda, Ford, Tesla
+ endenum
+ var l: list<Car> = Car.values
+ assert_equal(Car.Ford, l[1])
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # empty enum
+ lines =<< trim END
+ vim9script
+ enum Car
+ endenum
+ assert_equal([], Car.values)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # single value
+ lines =<< trim END
+ vim9script
+ enum Car
+ Honda
+ endenum
+ assert_equal([Car.Honda], Car.values)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ lines =<< trim END
+ vim9script
+ enum A
+ Red,
+ Blue
+ static def GetValues(): list<A>
+ return values
+ enddef
+ endenum
+ assert_equal([A.Red, A.Blue], A.GetValues())
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Other class variables in an enum should not be added to 'values'
+ lines =<< trim END
+ vim9script
+ enum LogLevel
+ Error, Warn
+ static const x: number = 22
+ endenum
+ assert_equal([LogLevel.Error, LogLevel.Warn], LogLevel.values)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Other class variable of enum type should not be added to 'values'
+ lines =<< trim END
+ vim9script
+ enum LogLevel
+ Error, Warn
+ static const x: LogLevel = LogLevel.Warn
+ endenum
+ assert_equal([LogLevel.Error, LogLevel.Warn], LogLevel.values)
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test comments in enums
+def Test_enum_comments()
+ var lines =<< trim END
+ vim9script
+ enum Car # cars
+ # before enum
+ Honda, # honda
+ # before enum
+ Ford # ford
+ endenum
+ assert_equal(1, Car.Ford.ordinal)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Test for using an unsupported comment
+ lines =<< trim END
+ vim9script
+ enum Car
+ Honda,
+ Ford,
+ #{
+ endenum
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 4)
+enddef
+
+" Test string() with enums
+def Test_enum_string()
+ var lines =<< trim END
+ vim9script
+ enum Car
+ Honda,
+ Ford
+ endenum
+ assert_equal("enum Car", string(Car))
+ assert_equal("enum Car.Honda {name: 'Honda', ordinal: 0}", string(Car.Honda))
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # customized string function
+ lines =<< trim END
+ vim9script
+ enum Dir
+ North,
+ South
+
+ def string(): string
+ return $'Dir.{this.name}'
+ enddef
+ endenum
+ assert_equal('Dir.North', string(Dir.North))
+ assert_equal('Dir.South', string(Dir.South))
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for importing an enum
+def Test_enum_import()
+ var lines =<< trim END
+ vim9script
+ export enum Star
+ Gemini,
+ Orion,
+ Pisces
+ endenum
+ END
+ writefile(lines, 'Xenumexport.vim', 'D')
+
+ lines =<< trim END
+ vim9script
+ import './Xenumexport.vim' as mod
+
+ var s1: mod.Star = mod.Star.Orion
+ assert_equal(true, s1 == mod.Star.Orion)
+ assert_equal(2, mod.Star.Pisces.ordinal)
+ var l1: list<mod.Star> = mod.Star.values
+ assert_equal("enum Star.Orion {name: 'Orion', ordinal: 1}", string(l1[1]))
+ assert_equal(s1, l1[1])
+
+ def Fn()
+ var s2: mod.Star = mod.Star.Orion
+ assert_equal(true, s2 == mod.Star.Orion)
+ assert_equal(2, mod.Star.Pisces.ordinal)
+ var l2: list<mod.Star> = mod.Star.values
+ assert_equal("enum Star.Orion {name: 'Orion', ordinal: 1}", string(l2[1]))
+ assert_equal(s2, l2[1])
+ enddef
+ Fn()
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
+" Test for using test_refcount() with enum
+def Test_enum_refcount()
+ var lines =<< trim END
+ vim9script
+ enum Foo
+ endenum
+ assert_equal(1, test_refcount(Foo))
+
+ enum Star
+ Gemini,
+ Orion
+ endenum
+ assert_equal(3, test_refcount(Star))
+ assert_equal(2, test_refcount(Star.Gemini))
+ assert_equal(2, test_refcount(Star.Orion))
+
+ var s: Star
+ assert_equal(3, test_refcount(Star))
+ assert_equal(-1, test_refcount(s))
+ s = Star.Orion
+ assert_equal(3, test_refcount(Star))
+ assert_equal(3, test_refcount(s))
+ assert_equal(2, test_refcount(Star.Gemini))
+ var t = s
+ assert_equal(3, test_refcount(Star))
+ assert_equal(4, test_refcount(s))
+ assert_equal(4, test_refcount(Star.Orion))
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for defining an enum with additional object variables and methods
+def Test_enum_enhanced()
+ var lines =<< trim END
+ vim9script
+ enum Vehicle
+ car(4, 5, 400),
+ bus(6, 50, 800),
+ bicycle(2, 1, 0)
+
+ final tires: number
+ final passengers: number
+ final carbonPerKilometer: number
+
+ def new(t: number, p: number, cpk: number)
+ this.tires = t
+ this.passengers = p
+ this.carbonPerKilometer = cpk
+ enddef
+
+ def CarbonFootprint(): float
+ return round(this.carbonPerKilometer / this.passengers)
+ enddef
+
+ def IsTwoWheeled(): bool
+ return this == Vehicle.bicycle
+ enddef
+
+ def CompareTo(other: Vehicle): float
+ return this.CarbonFootprint() - other.CarbonFootprint()
+ enddef
+ endenum
+
+ var v: Vehicle = Vehicle.bus
+ assert_equal([6, 50, 800], [v.tires, v.passengers, v.carbonPerKilometer])
+ assert_equal(true, Vehicle.bicycle.IsTwoWheeled())
+ assert_equal(false, Vehicle.car.IsTwoWheeled())
+ assert_equal(16.0, Vehicle.bus.CarbonFootprint())
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for the enum value 'name' variable
+def Test_enum_name()
+ # Check the names of enum values
+ var lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury,
+ Venus,
+ Earth
+ endenum
+ assert_equal('Mercury', Planet.Mercury.name)
+ assert_equal('Venus', Planet.Venus.name)
+ assert_equal('Earth', Planet.Earth.name)
+ assert_equal('string', typename(Planet.Earth.name))
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Check the name of enum items in the constructor
+ lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury("Mercury"),
+ Venus("Venus"),
+ Earth("Earth")
+
+ def new(s: string)
+ assert_equal(s, this.name)
+ enddef
+ endenum
+ defcompile
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Try assigning to the name of an enum
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple
+ endenum
+ Fruit.Apple.name = 'foo'
+ END
+ v9.CheckSourceFailure(lines, 'E1335: Variable "name" in class "Fruit" is not writable', 5)
+
+ # Try assigning to the name of an enum in a function
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple
+ endenum
+ def Fn()
+ Fruit.Apple.name = 'bar'
+ enddef
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1423: Enum value "Fruit.name" cannot be modified', 1)
+
+ # Try to overwrite an enum value name in the enum constructor
+ lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury,
+ Venus
+
+ def new()
+ this.name = 'foo'
+ enddef
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1427: Enum "Planet" name cannot be modified', 1)
+
+ # Try to declare an object variable named 'name'
+ lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury
+ var name: string
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: name', 4)
+enddef
+
+" Test for the enum value 'ordinal' variable
+def Test_enum_ordinal()
+ # Check the ordinal values of enum items
+ var lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury,
+ Venus,
+ Earth
+ endenum
+ assert_equal(0, Planet.Mercury.ordinal)
+ assert_equal(1, Planet.Venus.ordinal)
+ assert_equal(2, Planet.Earth.ordinal)
+ assert_equal('number', typename(Planet.Earth.ordinal))
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Check the ordinal value of enum items in the constructor
+ lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury(0),
+ Venus(1),
+ Earth(2)
+
+ def new(v: number)
+ assert_equal(v, this.ordinal)
+ enddef
+ endenum
+ defcompile
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Try assigning to the ordinal value of an enum
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple
+ endenum
+ Fruit.Apple.ordinal = 20
+ END
+ v9.CheckSourceFailure(lines, 'E1335: Variable "ordinal" in class "Fruit" is not writable', 5)
+
+ # Try assigning to the ordinal value of an enum in a function
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple
+ endenum
+ def Fn()
+ Fruit.Apple.ordinal = 20
+ enddef
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1423: Enum value "Fruit.ordinal" cannot be modified', 1)
+
+ # Try to overwrite an enum value ordinal in the enum constructor
+ lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury,
+ Venus
+
+ def new()
+ this.ordinal = 20
+ enddef
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1426: Enum "Planet" ordinal value cannot be modified', 1)
+
+ # Try to declare an object variable named 'ordinal'
+ lines =<< trim END
+ vim9script
+ enum Planet
+ Mercury
+ var ordinal: number
+ endenum
+ END
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: ordinal', 4)
+enddef
+
+" Test for trying to create a new enum object using the constructor
+def Test_enum_invoke_constructor()
+ var lines =<< trim END
+ vim9script
+ enum Foo
+ endenum
+ var f: Foo = Foo.new()
+ END
+ v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Foo"', 4)
+
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple,
+ Orange
+ endenum
+ var f: Fruit = Fruit.new()
+ END
+ v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Fruit"', 6)
+
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple,
+ Orange
+ def newFruit()
+ enddef
+ endenum
+ var f: Fruit = Fruit.newFruit()
+ END
+ v9.CheckSourceFailure(lines, 'E1325: Method "newFruit" not found in class "Fruit"', 8)
+
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple,
+ Orange
+ endenum
+ def Fn()
+ var f: Fruit = Fruit.new()
+ enddef
+ Fn()
+ END
+ v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Fruit"', 1)
+
+ # error in the enum constructor
+ lines =<< trim END
+ vim9script
+ enum Planet
+ earth
+ def new()
+ x = 123
+ enddef
+ endenum
+ END
+ v9.CheckSourceFailureList(lines, ['E1100:', 'E1100:'], 1)
+enddef
+
+" Test for checking "this" in an enum constructor
+def Test_enum_this_in_constructor()
+ var lines =<< trim END
+ vim9script
+ enum A
+ Red("enum A.Red {name: 'Red', ordinal: 0}"),
+ Blue("enum A.Blue {name: 'Blue', ordinal: 1}"),
+ Green("enum A.Green {name: 'Green', ordinal: 2}")
+
+ def new(s: string)
+ assert_equal(s, string(this))
+ enddef
+ endenum
+ defcompile
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using member variables in an enum object
+def Test_enum_object_variable()
+ var lines =<< trim END
+ vim9script
+ enum Planet
+ Jupiter(95),
+ Saturn(146)
+
+ var moons: number
+ endenum
+ assert_equal(95, Planet.Jupiter.moons)
+ assert_equal(146, Planet.Saturn.moons)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Use a final object variable
+ lines =<< trim END
+ vim9script
+ enum Planet
+ Jupiter(95),
+ Saturn(146)
+
+ final moons: number
+ def new(n: number)
+ this.moons = n
+ enddef
+ endenum
+ assert_equal(95, Planet.Jupiter.moons)
+ assert_equal(146, Planet.Saturn.moons)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Use a const object variable
+ lines =<< trim END
+ vim9script
+ enum Planet
+ Mars(false),
+ Jupiter(true)
+
+ const has_ring: bool
+ def new(r: bool)
+ this.has_ring = r
+ enddef
+ endenum
+ assert_equal(false, Planet.Mars.has_ring)
+ assert_equal(true, Planet.Jupiter.has_ring)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Use a regular object variable
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple,
+ Orange
+
+ final farm: string = 'SunValley'
+ endenum
+ assert_equal('SunValley', Fruit.Apple.farm)
+ assert_equal('SunValley', Fruit.Apple.farm)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Invoke the default constructor with an object variable
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple('foo'),
+ Orange('bar')
+
+ final t: string
+ endenum
+ assert_equal('foo', Fruit.Apple.t)
+ assert_equal('bar', Fruit.Orange.t)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Invoke the default constructor with an argument but without the object
+ # variable
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple,
+ Orange('bar')
+ endenum
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E118: Too many arguments for function: new', 5)
+
+ # Define a default constructor with an argument, but don't pass it in when
+ # defining the enum value
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple(5),
+ Orange
+
+ def new(t: number)
+ enddef
+ endenum
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 8)
+enddef
+
+" Test for using a custom constructor with an enum
+def Test_enum_custom_constructor()
+ # space before "("
+ var lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple(10),
+ Orange (20)
+
+ def new(t: number)
+ enddef
+ endenum
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, "E1068: No white space allowed before '(': Orange (20)", 4)
+
+ # no closing ")"
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple(10),
+ Orange (20
+
+ def new(t: number)
+ enddef
+ endenum
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, "E1068: No white space allowed before '(': Orange (20", 4)
+
+ # Specify constructor arguments split across multiple lines
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple(10,
+ 'foo'), Orange(20,
+ 'bar'),
+ Pear(30,
+ 'baz'), Mango(40,
+ 'qux')
+
+ final n: number
+ final s: string
+ def new(t: number, str: string)
+ this.n = t
+ this.s = str
+ enddef
+ endenum
+ defcompile
+ assert_equal([10, 'foo'], [Fruit.Apple.n, Fruit.Apple.s])
+ assert_equal([20, 'bar'], [Fruit.Orange.n, Fruit.Orange.s])
+ assert_equal([30, 'baz'], [Fruit.Pear.n, Fruit.Pear.s])
+ assert_equal([40, 'qux'], [Fruit.Mango.n, Fruit.Mango.s])
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # specify multiple enums with constructor arguments in a single line
+ lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple(10, 'foo'), Orange(20, 'bar'), Pear(30, 'baz'), Mango(40, 'qux')
+ const n: number
+ const s: string
+ endenum
+ defcompile
+ assert_equal([10, 'foo'], [Fruit.Apple.n, Fruit.Apple.s])
+ assert_equal([20, 'bar'], [Fruit.Orange.n, Fruit.Orange.s])
+ assert_equal([30, 'baz'], [Fruit.Pear.n, Fruit.Pear.s])
+ assert_equal([40, 'qux'], [Fruit.Mango.n, Fruit.Mango.s])
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using class variables in an enum class
+def Test_enum_class_variable()
+ var lines =<< trim END
+ vim9script
+ enum Fruit
+ Apple,
+ Orange
+
+ static var farm: string = 'SunValley'
+ endenum
+ assert_equal('SunValley', Fruit.farm)
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for converting a string to an enum value
+def Test_enum_eval()
+ var lines =<< trim END
+ vim9script
+ enum Color
+ Red,
+ Blue
+ endenum
+ var e = eval('Color.Blue')
+ assert_equal(Color.Blue, e)
+ assert_equal(1, e.ordinal)
+ assert_fails("eval('Color.Green')", 'E1422: Enum value "Green" not found in enum "Color"')
+ assert_fails("var x = eval('Color')", 'E1421: Enum "Color" cannot be used as a value')
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using "values" in an enum class variable
+def Test_use_enum_values_in_class_variable()
+ var lines =<< trim END
+ vim9script
+ enum Dir
+ North, South
+ static const dirs: list<Dir> = Dir.values
+ endenum
+ assert_equal([Dir.North, Dir.South], Dir.dirs)
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using lambda block in enums
+def Test_lambda_block_in_enum()
+ # This used to crash Vim
+ var lines =<< trim END
+ vim9script
+ enum IdEnum1
+ ID1
+ const Id: func(number): number = (num: number): number => {
+ # Return a ID
+ return num / 2
+ }
+ endenum
+ assert_equal(5, IdEnum1.ID1.Id(10))
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # This used to crash Vim
+ lines =<< trim END
+ vim9script
+ enum IdEnum2
+ ID1
+ static const Id: func(number): number = (num: number): number => {
+ # Return a ID
+ return num + 2
+ }
+ endenum
+ assert_equal(12, IdEnum2.Id(10))
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
+" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index 27585a9..b008929 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -166,6 +166,37 @@ def Test_wrong_function_name()
delfunc g:Define
enddef
+" Check that in a legacy script a :def accesses the correct script variables.
+" Github issue: #14615.
+def Test_access_var_from_legacy_def()
+ # Access a script variable by name WITH "s:" prefix.
+ var lines =<< trim END
+ let s:foo = 'init'
+ let s:xxfoo = 'init'
+ def! AccessVarFromLegacyDef()
+ s:xxfoo = 'CHANGED'
+ enddef
+ call AccessVarFromLegacyDef()
+ call assert_equal('init', s:foo)
+ call assert_equal('CHANGED', s:xxfoo)
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # Access a script variable by name WITHOUT "s:" prefix;
+ # previously this accessed "foo" and not "xxfoo"
+ lines =<< trim END
+ let s:foo = 'init'
+ let s:xxfoo = 'init'
+ def! AccessVarFromLegacyDef()
+ xxfoo = 'CHANGED'
+ enddef
+ call AccessVarFromLegacyDef()
+ call assert_equal('init', s:foo)
+ call assert_equal('CHANGED', s:xxfoo)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
def Test_listing_function_error()
var lines =<< trim END
var filler = 123
diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim
index fa1aeb1..581925d 100644
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -1140,6 +1140,182 @@ def Test_autoload_import_relative()
v9.CheckScriptFailure(lines, 'E484:')
enddef
+" autoload relative, access from compiled function.
+" Github issues: #14565, #14579
+def Test_autoload_import_relative_compiled_buffer()
+ var lines =<< trim END
+ vim9script
+
+ export def F1(): string
+ return 'InFile.vim'
+ enddef
+ END
+ writefile(lines, 'Ximportrelativebuffer.vim', 'D')
+ lines =<< trim END
+ vim9script
+
+ import autoload './Ximportrelativebuffer.vim' as xfile
+
+ def F(): string
+ return xfile.F1()
+ enddef
+ assert_equal('InFile.vim', F())
+ END
+ new
+ setline(1, lines)
+ :source
+ # source one more time to detect issues with clearing the script state and
+ # variables
+ :source
+ :bw!
+enddef
+
+" Test for relative import when sourcing a buffer in another directory
+def Test_autoload_import_relative_from_buffer_in_dir()
+ mkdir('Ximportrelative/dir1/dir2', 'pR')
+ var lines =<< trim END
+ vim9script
+
+ export def F1(): string
+ return 'InFile.vim'
+ enddef
+ END
+ writefile(lines, 'Ximportrelative/dir1/dir2/Ximport.vim')
+ lines =<< trim END
+ vim9script
+
+ import autoload './Ximport.vim' as xfile
+
+ def F(): string
+ return xfile.F1()
+ enddef
+ assert_equal('InFile.vim', F())
+ END
+ writefile(lines, 'Ximportrelative/dir1/dir2/Xrelative.vim')
+
+ split Ximportrelative/dir1/dir2/Xrelative.vim
+ :source
+ # source one more time to detect issues with clearing the script state and
+ # variables
+ :source
+ :bw!
+enddef
+
+" Test modifying exported autoload variable. Github issue: #14591
+def Test_autoload_export_variables()
+ mkdir('Xautoload_vars/autoload', 'pR')
+ var lines =<< trim END
+ vim9script
+ g:Xautoload_vars_autoload = true
+ export var val = 11
+ val = 42
+ END
+
+ # Test that the imported script, above, can modify the exported variable;
+ # and test that the importing script, below, can modify the variable.
+ writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f2.vim', 'D')
+ lines =<< trim END
+ vim9script
+ g:Xautoload_vars_autoload = false
+
+ import autoload './Xautoload_vars/autoload/Xauto_vars_f2.vim' as f2
+ # Verify that the import statement does not load the file.
+ assert_equal(false, g:Xautoload_vars_autoload)
+
+ def F(): number
+ return f2.val
+ enddef
+ # Verify compile does not load the file.
+ defcompile F
+ assert_equal(false, g:Xautoload_vars_autoload)
+
+ # load the file by accessing the exported variable
+ assert_equal(42, F())
+ assert_equal(true, g:Xautoload_vars_autoload)
+ unlet g:Xautoload_vars_autoload
+
+ assert_equal(42, f2.val)
+ f2.val = 17
+ assert_equal(17, f2.val)
+
+ def G()
+ f2.val = 19
+ enddef
+ G()
+ assert_equal(19, f2.val)
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # Test const var is not modifiable.
+ lines =<< trim END
+ vim9script
+ export const val = 11
+ val = 42
+ END
+ writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f3.vim', 'D')
+ lines =<< trim END
+ vim9script
+
+ import autoload './Xautoload_vars/autoload/Xauto_vars_f3.vim' as f3
+
+ var x = f3.val
+ END
+ v9.CheckScriptFailure(lines, 'E46:')
+
+ # Test const var is not modifiable from importing script.
+ lines =<< trim END
+ vim9script
+ export const val = 11
+ END
+ writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f4.vim', 'D')
+ lines =<< trim END
+ vim9script
+
+ import autoload './Xautoload_vars/autoload/Xauto_vars_f4.vim' as f4
+
+ f4.val = 13
+ END
+ v9.CheckScriptFailure(lines, 'E46:')
+
+ # Test const var is not modifiable from importing script from :def.
+ # Github issue: #14606
+ lines =<< trim END
+ vim9script
+ export const val = 11
+ END
+ writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f5.vim', 'D')
+ lines =<< trim END
+ vim9script
+
+ import autoload './Xautoload_vars/autoload/Xauto_vars_f5.vim' as f5
+
+ def F()
+ f5.val = 13
+ enddef
+ F()
+ END
+ v9.CheckScriptFailure(lines, 'E741:')
+
+ # Still part of Github issue: #14606
+ lines =<< trim END
+ vim9script
+ export var val = 11
+ END
+ writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f6.vim', 'D')
+ lines =<< trim END
+ vim9script
+
+ import autoload './Xautoload_vars/autoload/Xauto_vars_f6.vim' as f6
+
+ def F()
+ f6.val = 13
+ enddef
+ F()
+ assert_equal(13, f6.val)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
def Test_autoload_import_relative_autoload_dir()
mkdir('autoload', 'pR')
var lines =<< trim END
@@ -2054,6 +2230,13 @@ def Test_import_vim9_from_legacy()
export def GetText(): string
return 'text'
enddef
+ export var exported_nr: number = 22
+ def AddNum(n: number)
+ exported_nr += n
+ enddef
+ export var exportedDict: dict<func> = {Fn: AddNum}
+ export const CONST = 10
+ export final finalVar = 'abc'
END
writefile(vim9_lines, 'Xvim9_export.vim', 'D')
@@ -2072,6 +2255,13 @@ def Test_import_vim9_from_legacy()
" imported symbol is script-local
call assert_equal('exported', s:vim9.exported)
call assert_equal('text', s:vim9.GetText())
+ call s:vim9.exportedDict.Fn(5)
+ call assert_equal(27, s:vim9.exported_nr)
+ call call(s:vim9.exportedDict.Fn, [3])
+ call assert_equal(30, s:vim9.exported_nr)
+ call assert_fails('let s:vim9.CONST = 20', 'E46: Cannot change read-only variable "CONST"')
+ call assert_fails('let s:vim9.finalVar = ""', 'E46: Cannot change read-only variable "finalVar"')
+ call assert_fails('let s:vim9.non_existing_var = 20', 'E1048: Item not found in script: non_existing_var')
END
writefile(legacy_lines, 'Xlegacy_script.vim', 'D')
@@ -2916,6 +3106,33 @@ def Test_vim9_import_symlink()
unlet g:resultValue
&rtp = save_rtp
delete('Xfrom', 'rf')
+
+ # Access item from :def imported through symbolic linked directory. #14536
+ mkdir('Xto/real_dir', 'pR')
+ lines =<< trim END
+ vim9script
+ export const val = 17
+ export def F(): number
+ return 23
+ enddef
+ END
+ writefile(lines, 'Xto/real_dir/real_file.vim')
+ system('ln -s real_dir Xto/syml_dir')
+ defer delete('Xto/syml_dir')
+ lines =<< trim END
+ vim9script
+ import autoload './Xto/syml_dir/real_file.vim'
+
+ def Fmain()
+ assert_equal(17, real_file.val)
+ enddef
+ def F2()
+ assert_equal(23, real_file.F())
+ enddef
+ Fmain()
+ F2()
+ END
+ v9.CheckScriptSuccess(lines)
endif
enddef
@@ -2979,4 +3196,30 @@ def Test_import_autloaded_script()
&rtp = save_rtp
enddef
+" Test for autoloading an imported dict func
+def Test_autoload_import_dict_func()
+ mkdir('Xdir/autoload', 'pR')
+ var lines =<< trim END
+ vim9script
+ export var al_exported_nr: number = 33
+ def Al_AddNum(n: number)
+ al_exported_nr += n
+ enddef
+ export var al_exportedDict: dict<func> = {Fn: Al_AddNum}
+ END
+ writefile(lines, 'Xdir/autoload/Xdictfunc.vim')
+
+ var save_rtp = &rtp
+ exe 'set rtp^=' .. getcwd() .. '/Xdir'
+ lines =<< trim END
+ import './Xdir/autoload/Xdictfunc.vim'
+ call Xdictfunc#al_exportedDict.Fn(5)
+ call assert_equal(38, Xdictfunc#al_exported_nr)
+ call call(Xdictfunc#al_exportedDict.Fn, [3])
+ call assert_equal(41, Xdictfunc#al_exported_nr)
+ END
+ v9.CheckScriptSuccess(lines)
+ &rtp = save_rtp
+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 77b8831..a3f21be 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -458,7 +458,7 @@ func s:InvokeSomeCommand()
SomeCommand
endfunc
-def Test_autocommand_block()
+def Test_command_block()
com SomeCommand {
g:someVar = 'some'
}
@@ -469,7 +469,121 @@ def Test_autocommand_block()
unlet g:someVar
enddef
-def Test_command_block()
+" Test for using heredoc in a :command command block
+def Test_command_block_heredoc()
+ var lines =<< trim CODE
+ vim9script
+ com SomeCommand {
+ g:someVar =<< trim END
+ aaa
+ bbb
+ END
+ }
+ SomeCommand
+ assert_equal(['aaa', 'bbb'], g:someVar)
+ def Foo()
+ g:someVar = []
+ SomeCommand
+ assert_equal(['aaa', 'bbb'], g:someVar)
+ enddef
+ Foo()
+ delcommand SomeCommand
+ unlet g:someVar
+ CODE
+ v9.CheckSourceSuccess( lines)
+
+ # Execute a command with heredoc in a block
+ lines =<< trim CODE
+ vim9script
+ com SomeCommand {
+ g:someVar =<< trim END
+ aaa
+ bbb
+ END
+ }
+ execute('SomeCommand')
+ assert_equal(['aaa', 'bbb'], g:someVar)
+ delcommand SomeCommand
+ unlet g:someVar
+ CODE
+ v9.CheckSourceSuccess(lines)
+
+ # Heredoc with comment
+ lines =<< trim CODE
+ vim9script
+ com SomeCommand {
+ g:someVar =<< trim END # comment
+ aaa
+ bbb
+ END
+ }
+ execute('SomeCommand')
+ assert_equal(['aaa', 'bbb'], g:someVar)
+ delcommand SomeCommand
+ unlet g:someVar
+ CODE
+ v9.CheckSourceSuccess(lines)
+
+ # heredoc evaluation
+ lines =<< trim CODE
+ vim9script
+ com SomeCommand {
+ var suffix = '---'
+ g:someVar =<< trim eval END
+ ccc{suffix}
+ ddd
+ END
+ }
+ SomeCommand
+ assert_equal(['ccc---', 'ddd'], g:someVar)
+ def Foo()
+ g:someVar = []
+ SomeCommand
+ assert_equal(['ccc---', 'ddd'], g:someVar)
+ enddef
+ Foo()
+ delcommand SomeCommand
+ unlet g:someVar
+ CODE
+ v9.CheckSourceSuccess(lines)
+
+ # command following heredoc
+ lines =<< trim CODE
+ vim9script
+ com SomeCommand {
+ var l =<< trim END
+ eee
+ fff
+ END
+ g:someVar = l
+ }
+ SomeCommand
+ assert_equal(['eee', 'fff'], g:someVar)
+ delcommand SomeCommand
+ unlet g:someVar
+ CODE
+ v9.CheckSourceSuccess(lines)
+
+ # Error in heredoc
+ lines =<< trim CODE
+ vim9script
+ com SomeCommand {
+ g:someVar =<< trim END
+ eee
+ fff
+ }
+ try
+ SomeCommand
+ catch
+ assert_match("E990: Missing end marker 'END'", v:exception)
+ endtry
+ delcommand SomeCommand
+ unlet g:someVar
+ CODE
+ v9.CheckSourceSuccess(lines)
+enddef
+
+def Test_autocommand_block()
au BufNew *.xml {
g:otherVar = 'other'
}
@@ -4906,7 +5020,7 @@ def Test_for_stmt_space_before_type()
v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: :number in range(10)', 2)
enddef
-" This test used to cause an use-after-free memory access
+" This test used to cause a use-after-free memory access
def Test_for_empty_line_after_lambda()
var lines =<< trim END
vim9script
@@ -4931,6 +5045,16 @@ def Test_for_empty_line_after_lambda()
v9.CheckSourceSuccess(lines)
enddef
+" Test for evaluating a lambda block from a string
+def Test_eval_lambda_block()
+ var lines =<< trim END
+ vim9script
+ var Fn = eval("(x: number): number => {\nreturn x * 2\n}")
+ assert_equal(6, Fn(3))
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
" Keep this last, it messes up highlighting.
def Test_substitute_cmd()
new
diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index fd174a9..adcc3e9 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -1149,7 +1149,7 @@ func Test_visual_inner_block()
" try to select non-existing inner block
call cursor(5, 1)
call assert_beeps('normal ViBiBiB')
- " try to select a unclosed inner block
+ " try to select an unclosed inner block
8,9d
call cursor(5, 1)
call assert_beeps('normal ViBiB')
diff --git a/src/testdir/test_winfixbuf.vim b/src/testdir/test_winfixbuf.vim
index 04043f8..f800338 100644
--- a/src/testdir/test_winfixbuf.vim
+++ b/src/testdir/test_winfixbuf.vim
@@ -1,6 +1,7 @@
" Test 'winfixbuf'
source check.vim
+source shared.vim
" Find the number of open windows in the current tab
func s:get_windows_count()
@@ -199,10 +200,7 @@ func s:reset_all_buffers()
set nowinfixbuf
call setqflist([])
-
- for l:window_info in getwininfo()
- call setloclist(l:window_info["winid"], [])
- endfor
+ call setloclist(0, [], 'f')
delmarks A-Z0-9
endfunc
@@ -641,7 +639,7 @@ func Test_caddexpr()
call s:reset_all_buffers()
let l:file_path = tempname()
- call writefile(["Error - bad-thing-found"], l:file_path)
+ call writefile(["Error - bad-thing-found"], l:file_path, 'D')
execute "edit " . l:file_path
let l:file_buffer = bufnr()
let l:current = bufnr()
@@ -657,8 +655,6 @@ func Test_caddexpr()
execute 'caddexpr expand("%") .. ":" .. line(".") .. ":" .. getline(".")'
call assert_equal(l:current, bufnr())
-
- call delete(l:file_path)
endfunc
" Fail :cbuffer but :cbuffer! is allowed
@@ -667,7 +663,7 @@ func Test_cbuffer()
call s:reset_all_buffers()
let l:file_path = tempname()
- call writefile(["first.unittest:1:Error - bad-thing-found"], l:file_path)
+ call writefile(["first.unittest:1:Error - bad-thing-found"], l:file_path, 'D')
execute "edit " . l:file_path
let l:file_buffer = bufnr()
let l:current = bufnr()
@@ -686,8 +682,6 @@ func Test_cbuffer()
execute "cbuffer! " . l:file_buffer
call assert_equal("first.unittest", expand("%:t"))
-
- call delete(l:file_path)
endfunc
" Allow :cc but the 'nowinfixbuf' window is selected, instead
@@ -1125,6 +1119,150 @@ func Test_edit()
call assert_equal(l:other, bufnr())
endfunc
+" Fail :e when selecting a buffer from a relative path if in a different folder
+"
+" In this tests there's 2 buffers
+"
+" foo - lives on disk, in some folder. e.g. /tmp/foo
+" foo - an in-memory buffer that has not been saved to disk. If saved, it
+" would live in a different folder, /other/foo.
+"
+" The 'winfixbuf' is looking at the in-memory buffer and trying to switch to
+" the buffer on-disk (and fails, because it's a different buffer)
+func Test_edit_different_buffer_on_disk_and_relative_path_to_disk()
+ call s:reset_all_buffers()
+
+ let l:file_on_disk = tempname()
+ let l:directory_on_disk1 = fnamemodify(l:file_on_disk, ":p:h")
+ let l:name = fnamemodify(l:file_on_disk, ":t")
+ execute "edit " . l:file_on_disk
+ write!
+
+ let l:directory_on_disk2 = l:directory_on_disk1 . "_something_else"
+
+ if !isdirectory(l:directory_on_disk2)
+ call mkdir(l:directory_on_disk2)
+ endif
+
+ execute "cd " . l:directory_on_disk2
+ execute "edit " l:name
+
+ let l:current = bufnr()
+
+ call assert_equal(l:current, bufnr())
+ set winfixbuf
+ call assert_fails("edit " . l:file_on_disk, "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ call delete(l:directory_on_disk1)
+ call delete(l:directory_on_disk2)
+endfunc
+
+" Fail :e when selecting a buffer from a relative path if in a different folder
+"
+" In this tests there's 2 buffers
+"
+" foo - lives on disk, in some folder. e.g. /tmp/foo
+" foo - an in-memory buffer that has not been saved to disk. If saved, it
+" would live in a different folder, /other/foo.
+"
+" The 'winfixbuf' is looking at the on-disk buffer and trying to switch to
+" the in-memory buffer (and fails, because it's a different buffer)
+func Test_edit_different_buffer_on_disk_and_relative_path_to_memory()
+ call s:reset_all_buffers()
+
+ let l:file_on_disk = tempname()
+ let l:directory_on_disk1 = fnamemodify(l:file_on_disk, ":p:h")
+ let l:name = fnamemodify(l:file_on_disk, ":t")
+ execute "edit " . l:file_on_disk
+ write!
+
+ let l:directory_on_disk2 = l:directory_on_disk1 . "_something_else"
+
+ if !isdirectory(l:directory_on_disk2)
+ call mkdir(l:directory_on_disk2)
+ endif
+
+ execute "cd " . l:directory_on_disk2
+ execute "edit " l:name
+ execute "cd " . l:directory_on_disk1
+ execute "edit " l:file_on_disk
+ execute "cd " . l:directory_on_disk2
+
+ let l:current = bufnr()
+
+ call assert_equal(l:current, bufnr())
+ set winfixbuf
+ call assert_fails("edit " . l:name, "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ call delete(l:directory_on_disk1)
+ call delete(l:directory_on_disk2)
+endfunc
+
+" Fail to call `:e first` if called from a starting, in-memory buffer
+func Test_edit_first_buffer()
+ call s:reset_all_buffers()
+
+ set winfixbuf
+ let l:current = bufnr()
+
+ call assert_fails("edit first", "E1513:")
+ call assert_equal(l:current, bufnr())
+
+ edit! first
+ call assert_equal(l:current, bufnr())
+ edit! somewhere_else
+ call assert_notequal(l:current, bufnr())
+endfunc
+
+" Allow reloading a buffer using :e
+func Test_edit_no_arguments()
+ call s:reset_all_buffers()
+
+ let l:current = bufnr()
+ file some_buffer
+
+ call assert_equal(l:current, bufnr())
+ set winfixbuf
+ edit
+ call assert_equal(l:current, bufnr())
+endfunc
+
+" Allow :e selecting the current buffer
+func Test_edit_same_buffer_in_memory()
+ call s:reset_all_buffers()
+
+ let current = bufnr()
+ file same_buffer
+
+ call assert_equal(current, bufnr())
+ set winfixbuf
+ edit same_buffer
+ call assert_equal(current, bufnr())
+ set nowinfixbuf
+endfunc
+
+" Allow :e selecting the current buffer as a full path
+func Test_edit_same_buffer_on_disk_absolute_path()
+ call s:reset_all_buffers()
+
+ let file = tempname()
+ " file must exist for expansion of 8.3 paths to succeed
+ call writefile([], file, 'D')
+ let file = fnamemodify(file, ':p')
+ let current = bufnr()
+ execute "edit " . file
+ write!
+
+ call assert_equal(current, bufnr())
+ set winfixbuf
+ execute "edit " file
+ call assert_equal(current, bufnr())
+
+ set nowinfixbuf
+endfunc
+
" Fail :enew but :enew! is allowed
func Test_enew()
call s:reset_all_buffers()
@@ -1160,7 +1298,7 @@ func Test_find()
let l:current = bufnr()
let l:file = tempname()
- call writefile([], l:file)
+ call writefile([], l:file, 'D')
let l:file = fnamemodify(l:file, ':p') " In case it's Windows 8.3-style.
let l:directory = fnamemodify(l:file, ":p:h")
let l:name = fnamemodify(l:file, ":p:t")
@@ -1177,7 +1315,6 @@ func Test_find()
call assert_equal(l:file, expand("%:p"))
execute "set path=" . l:original_path
- call delete(l:file)
endfunc
" Fail :first but :first! is allowed
@@ -1238,8 +1375,8 @@ func Test_ijump()
call writefile([
\ '#include "' . l:include_file . '"'
\ ],
- \ "main.c")
- call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file)
+ \ "main.c", 'D')
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D')
edit main.c
set winfixbuf
@@ -1261,8 +1398,6 @@ func Test_ijump()
set define&
set include&
set path&
- call delete("main.c")
- call delete(l:include_file)
endfunc
" Fail :lNext but :lNext! is allowed
@@ -1327,7 +1462,7 @@ func Test_laddexpr()
call s:reset_all_buffers()
let l:file_path = tempname()
- call writefile(["Error - bad-thing-found"], l:file_path)
+ call writefile(["Error - bad-thing-found"], l:file_path, 'D')
execute "edit " . l:file_path
let l:file_buffer = bufnr()
let l:current = bufnr()
@@ -1343,8 +1478,6 @@ func Test_laddexpr()
execute 'laddexpr expand("%") .. ":" .. line(".") .. ":" .. getline(".")'
call assert_equal(l:current, bufnr())
-
- call delete(l:file_path)
endfunc
" Fail :last but :last! is allowed
@@ -1367,7 +1500,7 @@ func Test_lbuffer()
call s:reset_all_buffers()
let l:file_path = tempname()
- call writefile(["first.unittest:1:Error - bad-thing-found"], l:file_path)
+ call writefile(["first.unittest:1:Error - bad-thing-found"], l:file_path, 'D')
execute "edit " . l:file_path
let l:file_buffer = bufnr()
let l:current = bufnr()
@@ -1386,8 +1519,6 @@ func Test_lbuffer()
execute "lbuffer! " . l:file_buffer
call assert_equal("first.unittest", expand("%:t"))
-
- call delete(l:file_path)
endfunc
" Fail :ldo but :ldo! is allowed
@@ -1451,7 +1582,7 @@ func Test_lfile()
write
let l:file = tempname()
- call writefile(["first.unittest:1:Error - bad-thing-found was detected"], l:file)
+ call writefile(["first.unittest:1:Error - bad-thing-found was detected"], l:file, 'D')
let l:current = bufnr()
@@ -1463,7 +1594,6 @@ func Test_lfile()
execute ":lfile! " . l:file
call assert_equal(l:first, bufnr())
- call delete(l:file)
call delete("first.unittest")
call delete("second.unittest")
endfunc
@@ -1603,9 +1733,9 @@ func Test_ltag()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
execute "normal \<C-]>"
@@ -1618,9 +1748,6 @@ func Test_ltag()
ltag! one
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail vim.command if we try to change buffers while 'winfixbuf' is set
@@ -1826,9 +1953,9 @@ func Test_normal_g_ctrl_square_bracket_right()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -1839,9 +1966,6 @@ func Test_normal_g_ctrl_square_bracket_right()
call assert_equal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail to jump to a tag with g<RightMouse> if 'winfixbuf' is enabled
@@ -1854,9 +1978,9 @@ func Test_normal_g_rightmouse()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
execute "normal \<C-]>"
@@ -1869,9 +1993,6 @@ func Test_normal_g_rightmouse()
set tags&
set mouse&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail to jump to a tag with g] if 'winfixbuf' is enabled
@@ -1883,9 +2004,9 @@ func Test_normal_g_square_bracket_right()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -1896,9 +2017,6 @@ func Test_normal_g_square_bracket_right()
call assert_equal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail to jump to a tag with <C-RightMouse> if 'winfixbuf' is enabled
@@ -1911,9 +2029,9 @@ func Test_normal_ctrl_rightmouse()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
execute "normal \<C-]>"
@@ -1926,9 +2044,6 @@ func Test_normal_ctrl_rightmouse()
set tags&
set mouse&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail to jump to a tag with <C-t> if 'winfixbuf' is enabled
@@ -1940,9 +2055,9 @@ func Test_normal_ctrl_t()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
execute "normal \<C-]>"
@@ -1954,9 +2069,6 @@ func Test_normal_ctrl_t()
call assert_equal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Disallow <C-^> in 'winfixbuf' windows
@@ -2058,9 +2170,9 @@ func Test_normal_ctrl_square_bracket_right()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -2071,9 +2183,6 @@ func Test_normal_ctrl_square_bracket_right()
call assert_equal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Allow <C-w><C-]> with 'winfixbuf' enabled because it runs in a new, split window
@@ -2085,9 +2194,9 @@ func Test_normal_ctrl_w_ctrl_square_bracket_right()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -2097,9 +2206,6 @@ func Test_normal_ctrl_w_ctrl_square_bracket_right()
call assert_equal(l:current_windows + 1, s:get_windows_count())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Allow <C-w>g<C-]> with 'winfixbuf' enabled because it runs in a new, split window
@@ -2111,9 +2217,9 @@ func Test_normal_ctrl_w_g_ctrl_square_bracket_right()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -2123,9 +2229,6 @@ func Test_normal_ctrl_w_g_ctrl_square_bracket_right()
call assert_equal(l:current_windows + 1, s:get_windows_count())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail to jump to a tag with <C-]> if 'winfixbuf' is enabled
@@ -2137,9 +2240,9 @@ func Test_normal_gt()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one", "two", "three"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one", "two", "three"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -2150,9 +2253,6 @@ func Test_normal_gt()
call assert_equal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Prevent gF from switching a 'winfixbuf' window's buffer
@@ -2161,7 +2261,7 @@ func Test_normal_gF()
let l:file = tempname()
call append(0, [l:file])
- call writefile([], l:file)
+ call writefile([], l:file, 'D')
" Place the cursor onto the line that has `l:file`
normal gg
" Prevent Vim from erroring with "No write since last change @ command
@@ -2180,7 +2280,7 @@ func Test_normal_gF()
normal gF
call assert_notequal(l:buffer, bufnr())
- call delete(l:file)
+ set nohidden
endfunc
" Prevent gf from switching a 'winfixbuf' window's buffer
@@ -2189,7 +2289,7 @@ func Test_normal_gf()
let l:file = tempname()
call append(0, [l:file])
- call writefile([], l:file)
+ call writefile([], l:file, 'D')
" Place the cursor onto the line that has `l:file`
normal gg
" Prevent Vim from erroring with "No write since last change @ command
@@ -2208,7 +2308,7 @@ func Test_normal_gf()
normal gf
call assert_notequal(l:buffer, bufnr())
- call delete(l:file)
+ set nohidden
endfunc
" Fail "goto file under the cursor" (using [f, which is the same as `:normal gf`)
@@ -2217,7 +2317,7 @@ func Test_normal_square_bracket_left_f()
let l:file = tempname()
call append(0, [l:file])
- call writefile([], l:file)
+ call writefile([], l:file, 'D')
" Place the cursor onto the line that has `l:file`
normal gg
" Prevent Vim from erroring with "No write since last change @ command
@@ -2236,7 +2336,7 @@ func Test_normal_square_bracket_left_f()
normal [f
call assert_notequal(l:buffer, bufnr())
- call delete(l:file)
+ set nohidden
endfunc
" Fail to go to a C macro with [<C-d> if 'winfixbuf' is enabled
@@ -2247,8 +2347,8 @@ func Test_normal_square_bracket_left_ctrl_d()
call writefile(["min(1, 12);",
\ '#include "' . l:include_file . '"'
\ ],
- \ "main.c")
- call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file)
+ \ "main.c", 'D')
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D')
edit main.c
normal ]\<C-d>
@@ -2263,9 +2363,6 @@ func Test_normal_square_bracket_left_ctrl_d()
execute "normal [\<C-d>"
call assert_notequal(l:current, bufnr())
-
- call delete("main.c")
- call delete(l:include_file)
endfunc
" Fail to go to a C macro with ]<C-d> if 'winfixbuf' is enabled
@@ -2276,8 +2373,8 @@ func Test_normal_square_bracket_right_ctrl_d()
call writefile(["min(1, 12);",
\ '#include "' . l:include_file . '"'
\ ],
- \ "main.c")
- call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file)
+ \ "main.c", 'D')
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D')
edit main.c
set winfixbuf
@@ -2291,9 +2388,6 @@ func Test_normal_square_bracket_right_ctrl_d()
execute "normal ]\<C-d>"
call assert_notequal(l:current, bufnr())
-
- call delete("main.c")
- call delete(l:include_file)
endfunc
" Fail to go to a C macro with [<C-i> if 'winfixbuf' is enabled
@@ -2304,8 +2398,8 @@ func Test_normal_square_bracket_left_ctrl_i()
call writefile(['#include "' . l:include_file . '"',
\ "min(1, 12);",
\ ],
- \ "main.c")
- call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file)
+ \ "main.c", 'D')
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D')
edit main.c
" Move to the line with `min(1, 12);` on it"
normal j
@@ -2328,8 +2422,6 @@ func Test_normal_square_bracket_left_ctrl_i()
set define&
set include&
set path&
- call delete("main.c")
- call delete(l:include_file)
endfunc
" Fail to go to a C macro with ]<C-i> if 'winfixbuf' is enabled
@@ -2340,8 +2432,8 @@ func Test_normal_square_bracket_right_ctrl_i()
call writefile(["min(1, 12);",
\ '#include "' . l:include_file . '"'
\ ],
- \ "main.c")
- call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file)
+ \ "main.c", 'D')
+ call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D')
edit main.c
set winfixbuf
@@ -2363,8 +2455,6 @@ func Test_normal_square_bracket_right_ctrl_i()
set define&
set include&
set path&
- call delete("main.c")
- call delete(l:include_file)
endfunc
" Fail "goto file under the cursor" (using ]f, which is the same as `:normal gf`)
@@ -2373,7 +2463,7 @@ func Test_normal_square_bracket_right_f()
let l:file = tempname()
call append(0, [l:file])
- call writefile([], l:file)
+ call writefile([], l:file, 'D')
" Place the cursor onto the line that has `l:file`
normal gg
" Prevent Vim from erroring with "No write since last change @ command
@@ -2392,7 +2482,7 @@ func Test_normal_square_bracket_right_f()
normal ]f
call assert_notequal(l:buffer, bufnr())
- call delete(l:file)
+ set nohidden
endfunc
" Fail to jump to a tag with v<C-]> if 'winfixbuf' is enabled
@@ -2404,9 +2494,9 @@ func Test_normal_v_ctrl_square_bracket_right()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -2417,9 +2507,6 @@ func Test_normal_v_ctrl_square_bracket_right()
call assert_equal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail to jump to a tag with vg<C-]> if 'winfixbuf' is enabled
@@ -2431,9 +2518,9 @@ func Test_normal_v_g_ctrl_square_bracket_right()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -2444,9 +2531,6 @@ func Test_normal_v_g_ctrl_square_bracket_right()
call assert_equal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Allow :pedit because, unlike :edit, it uses a separate window
@@ -2471,9 +2555,9 @@ func Test_pop()
\ "thesame\tXfile\t2;\"\td\tfile:",
\ "thesame\tXfile\t3;\"\td\tfile:",
\ ],
- \ "Xtags")
- call writefile(["thesame one", "thesame two", "thesame three"], "Xfile")
- call writefile(["thesame one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D')
+ call writefile(["thesame one"], "Xother", 'D')
edit Xother
tag thesame
@@ -2489,9 +2573,6 @@ func Test_pop()
call assert_notequal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail :previous but :previous! is allowed
@@ -2559,7 +2640,7 @@ func Test_pythonx_pyxfile()
\ "buffer = vim.vars['_previous_buffer']",
\ "vim.current.buffer = vim.buffers[buffer]",
\ ],
- \ "file.py")
+ \ "file.py", 'D')
try
pyxfile file.py
@@ -2569,7 +2650,6 @@ func Test_pythonx_pyxfile()
call assert_equal(1, l:caught)
- call delete("file.py")
unlet g:_previous_buffer
endfunc
@@ -2696,11 +2776,11 @@ func Test_short_option()
call s:make_buffer_pairs()
set winfixbuf
- call assert_fails("edit something_else", "E1513")
+ call assert_fails("edit something_else", "E1513:")
set nowinfixbuf
set wfb
- call assert_fails("edit another_place", "E1513")
+ call assert_fails("edit another_place", "E1513:")
set nowfb
edit last_place
@@ -2747,9 +2827,9 @@ func Test_tNext()
\ "thesame\tXfile\t2;\"\td\tfile:",
\ "thesame\tXfile\t3;\"\td\tfile:",
\ ],
- \ "Xtags")
- call writefile(["thesame one", "thesame two", "thesame three"], "Xfile")
- call writefile(["thesame one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D')
+ call writefile(["thesame one"], "Xother", 'D')
edit Xother
tag thesame
@@ -2766,9 +2846,6 @@ func Test_tNext()
tNext!
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Call :tabdo and choose the next available 'nowinfixbuf' window.
@@ -2826,9 +2903,9 @@ func Test_tag()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -2842,9 +2919,6 @@ func Test_tag()
call assert_notequal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
@@ -2857,9 +2931,9 @@ func Test_tfirst()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -2873,9 +2947,6 @@ func Test_tfirst()
call assert_notequal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail :tjump but :tjump! is allowed
@@ -2887,9 +2958,9 @@ func Test_tjump()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
- call writefile(["one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
+ call writefile(["one"], "Xother", 'D')
edit Xother
set winfixbuf
@@ -2903,9 +2974,6 @@ func Test_tjump()
call assert_notequal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail :tlast but :tlast! is allowed
@@ -2917,8 +2985,8 @@ func Test_tlast()
\ "one\tXfile\t1",
\ "three\tXfile\t3",
\ "two\tXfile\t2"],
- \ "Xtags")
- call writefile(["one", "two", "three"], "Xfile")
+ \ "Xtags", 'D')
+ call writefile(["one", "two", "three"], "Xfile", 'D')
edit Xfile
tjump one
edit Xfile
@@ -2934,8 +3002,6 @@ func Test_tlast()
call assert_equal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
endfunc
" Fail :tnext but :tnext! is allowed
@@ -2948,9 +3014,9 @@ func Test_tnext()
\ "thesame\tXfile\t2;\"\td\tfile:",
\ "thesame\tXfile\t3;\"\td\tfile:",
\ ],
- \ "Xtags")
- call writefile(["thesame one", "thesame two", "thesame three"], "Xfile")
- call writefile(["thesame one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D')
+ call writefile(["thesame one"], "Xother", 'D')
edit Xother
tag thesame
@@ -2967,9 +3033,6 @@ func Test_tnext()
call assert_notequal(l:current, bufnr())
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail :tprevious but :tprevious! is allowed
@@ -2982,9 +3045,9 @@ func Test_tprevious()
\ "thesame\tXfile\t2;\"\td\tfile:",
\ "thesame\tXfile\t3;\"\td\tfile:",
\ ],
- \ "Xtags")
- call writefile(["thesame one", "thesame two", "thesame three"], "Xfile")
- call writefile(["thesame one"], "Xother")
+ \ "Xtags", 'D')
+ call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D')
+ call writefile(["thesame one"], "Xother", 'D')
edit Xother
tag thesame
@@ -3001,9 +3064,6 @@ func Test_tprevious()
tprevious!
set tags&
- call delete("Xtags")
- call delete("Xfile")
- call delete("Xother")
endfunc
" Fail :view but :view! is allowed
@@ -3283,4 +3343,15 @@ func Test_bufdo_cnext_splitwin_fails()
set winminheight&vim winheight&vim
endfunc
+" Test that exiting with 'winfixbuf' and EXITFREE doesn't cause an error.
+func Test_exitfree_no_error()
+ let lines =<< trim END
+ set winfixbuf
+ qall!
+ END
+ call writefile(lines, 'Xwfb_exitfree', 'D')
+ call assert_notmatch('E1513:',
+ \ system(GetVimCommandClean() .. ' --not-a-term -X -S Xwfb_exitfree'))
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_xdg.vim b/src/testdir/test_xdg.vim
new file mode 100644
index 0000000..6f35b72
--- /dev/null
+++ b/src/testdir/test_xdg.vim
@@ -0,0 +1,295 @@
+" Tests for the XDG feature
+
+source check.vim
+source shared.vim
+
+func s:get_rcs()
+ let rcs = {
+ \ 'file1': { 'path': '~/.vimrc' },
+ \ 'file2': { 'path': '~/.vim/vimrc' },
+ \ 'xdg': { 'path': exists('$XDG_CONFIG_HOME') ? '$XDG_CONFIG_HOME' : "~/.config" },
+ \}
+ for v in values(rcs)
+ let v.exists = filereadable(expand(v.path))
+ endfor
+ return rcs
+endfunc
+
+func Test_xdg_rc_detection()
+ CheckUnix
+ let rc = s:get_rcs()
+ let before =<< trim CODE
+ call writefile([expand('$MYVIMRC')], "XMY_VIMRC")
+ quit!
+ CODE
+ call RunVim(before, [], "")
+ let my_rc = readfile("XMY_VIMRC")
+ if rc.file1.exists
+ call assert_equal(rc.file1.path, my_rc)
+ elseif !rc.file1.exists && rc.file2.exists
+ call assert_equal(rc.file2.path, my_rc)
+ elseif !rc.file1.exists && !rc.file2.exists && rc.xdg.exists
+ call assert_equal(rc.xdg.path, my_rc)
+ endif
+ call delete("XMY_VIMRC")
+endfunc
+
+func Test_xdg_runtime_files()
+ " This tests, that the initialization file from
+ " ~/.vimrc, ~/.vim/vimrc and ~/.config/vim/vimrc (or
+ " $XDG_CONFIG_HOME/vim/vimrc) are sourced in that order
+ CheckUnix
+ call mkdir(expand('~/.vim/'), 'pD')
+ call mkdir(expand('~/.config/vim/'), 'pD')
+ call mkdir(expand('~/xdg/vim/'), 'pD')
+
+ let rc1=expand('~/.vimrc')
+ let rc2=expand('~/.vim/vimrc')
+ let rc3=expand('~/.config/vim/vimrc')
+ let rc4=expand('~/xdg/vim/vimrc')
+
+ " g:rc_one|two|three|four is to verify, that the other
+ " init files are not sourced
+ " g:rc is to verify which rc file has been loaded.
+ let file1 =<< trim CODE
+ let g:rc_one = 'one'
+ let g:rc = '.vimrc'
+ CODE
+ let file2 =<< trim CODE
+ let g:rc_two = 'two'
+ let g:rc = '.vim/vimrc'
+ CODE
+ let file3 =<< trim CODE
+ let g:rc_three = 'three'
+ let g:rc = '.config/vim/vimrc'
+ CODE
+ let file4 =<< trim CODE
+ let g:rc_four = 'four'
+ let g:rc = 'xdg/vim/vimrc'
+ CODE
+ call writefile(file1, rc1)
+ call writefile(file2, rc2)
+ call writefile(file3, rc3)
+ call writefile(file4, rc4)
+
+ " Get the Vim command to run without the '-u NONE' argument
+ let vimcmd = substitute(GetVimCommand(), '-u NONE', '', '')
+
+ " Test for ~/.vimrc
+ let lines =<< trim END
+ call assert_match('XfakeHOME/\.vimrc', $MYVIMRC)
+ call filter(g:, {idx, _ -> idx =~ '^rc'})
+ call assert_equal(#{rc_one: 'one', rc: '.vimrc'}, g:)
+ call writefile(v:errors, 'Xresult')
+ quit
+ END
+ call writefile(lines, 'Xscript', 'D')
+ call system($'{vimcmd} -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+
+ call delete(rc1)
+
+ " Test for ~/.vim/vimrc
+ let lines =<< trim END
+ call assert_match('XfakeHOME/\.vim/vimrc', $MYVIMRC)
+ call filter(g:, {idx, _ -> idx =~ '^rc'})
+ call assert_equal(#{rc_two: 'two', rc: '.vim/vimrc'}, g:)
+ call writefile(v:errors, 'Xresult')
+ quit
+ END
+ call writefile(lines, 'Xscript', 'D')
+ call system($'{vimcmd} -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+
+ call delete(rc2)
+
+ " XDG_CONFIG_HOME is set in Github CI runners
+ unlet $XDG_CONFIG_HOME
+
+ " Test for ~/.config/vim/vimrc
+ let lines =<< trim END
+ let msg = $'HOME="{$HOME}", ~="{expand("~")}"'
+ call assert_match('XfakeHOME/\.config/vim/vimrc', $MYVIMRC, msg)
+ call filter(g:, {idx, _ -> idx =~ '^rc'})
+ call assert_equal(#{rc_three: 'three', rc: '.config/vim/vimrc'}, g:)
+ call writefile(v:errors, 'Xresult')
+ quit
+ END
+ call writefile(lines, 'Xscript', 'D')
+ call system($'{vimcmd} -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+
+ call delete(rc3)
+
+ " Test for ~/xdg/vim/vimrc
+ let $XDG_CONFIG_HOME=expand('~/xdg/')
+ let lines =<< trim END
+ let msg = $'HOME="{$HOME}", XDG_CONFIG_HOME="{$XDG_CONFIG_HOME}"'
+ call assert_match('XfakeHOME/xdg/vim/vimrc', $MYVIMRC, msg)
+ call filter(g:, {idx, _ -> idx =~ '^rc'})
+ call assert_equal(#{rc_four: 'four', rc: 'xdg/vim/vimrc'}, g:)
+ call writefile(v:errors, 'Xresult')
+ quit
+ END
+ call writefile(lines, 'Xscript', 'D')
+ call system($'{vimcmd} -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+
+ call delete(rc4)
+ unlet $XDG_CONFIG_HOME
+endfunc
+
+func Test_xdg_version()
+ CheckUnix
+ let $HOME = getcwd() .. '/XfakeHOME'
+ unlet $XDG_CONFIG_HOME
+ let a = execute(':version')->split('\n')
+ let a = filter(a, { _, val -> val =~ '\.config\|XDG_CONFIG_HOME' })
+ " There should be 1 entry for gvimrc and 1 entry for vimrc,
+ " but only if Vim was compiled with gui support
+ call assert_equal(1 + has("gui"), len(a))
+ call assert_match('\~/\.config/vim/vimrc', a[0])
+ if has("gui")
+ call assert_match('\~/\.config/vim/gvimrc', a[1])
+ endif
+
+ let $XDG_CONFIG_HOME = expand('~/.xdg')
+ let a = execute(':version')->split('\n')
+ let a = filter(a, { _, val -> val =~ '\.config\|XDG_CONFIG_HOME' })
+ call assert_equal(1 + has("gui"), len(a))
+ call assert_match('XDG_CONFIG_HOME/vim/vimrc', a[0])
+ if has("gui")
+ call assert_match('XDG_CONFIG_HOME/vim/gvimrc', a[1])
+ endif
+ unlet $XDG_CONFIG_HOME
+endfunc
+
+" Test for gvimrc, must be last, since it starts the GUI
+" and sources a few extra test files
+func Test_zzz_xdg_runtime_files()
+ CheckCanRunGui
+ CheckUnix
+
+ " Is setup in Github Runner
+ unlet $XDG_CONFIG_HOME
+ source setup_gui.vim
+ call GUISetUpCommon()
+
+ " This tests, that the GUI initialization file from
+ " ~/.gvimrc, ~/.vim/gvimrc, ~/.config/vim/gvimrc
+ " and ~/XDG_CONFIG_HOME/vim/gvimrc is sourced
+ " when starting GUI mode
+ call mkdir(expand('~/.vim/'), 'pD')
+ call mkdir(expand('~/.config/vim/'), 'pD')
+ call mkdir(expand('~/xdg/vim/'), 'pD')
+
+ let rc1=expand('~/.gvimrc')
+ let rc2=expand('~/.vim/gvimrc')
+ let rc3=expand('~/.config/vim/gvimrc')
+ let rc4=expand('~/xdg/vim/gvimrc')
+
+ " g:rc_one|two|three|four is to verify, that the other
+ " init files are not sourced
+ " g:rc is to verify which rc file has been loaded.
+ let file1 =<< trim CODE
+ let g:rc_one = 'one'
+ let g:rc = '.gvimrc'
+ CODE
+ let file2 =<< trim CODE
+ let g:rc_two = 'two'
+ let g:rc = '.vim/gvimrc'
+ CODE
+ let file3 =<< trim CODE
+ let g:rc_three = 'three'
+ let g:rc = '.config/vim/gvimrc'
+ CODE
+ let file4 =<< trim CODE
+ let g:rc_four = 'four'
+ let g:rc = 'xdg/vim/gvimrc'
+ CODE
+ call writefile(file1, rc1)
+ call writefile(file2, rc2)
+ call writefile(file3, rc3)
+ call writefile(file4, rc4)
+
+ " Get the Vim command to run without the '-u NONE' argument
+ let vimcmd = substitute(GetVimCommand(), '-u NONE', '', '')
+
+ " Test for ~/.gvimrc
+ let lines =<< trim END
+ " Ignore the "failed to create input context" error.
+ call test_ignore_error('E285')
+ gui -f
+ call assert_match('Xhome/\.gvimrc', $MYGVIMRC)
+ call filter(g:, {idx, _ -> idx =~ '^rc'})
+ call assert_equal(#{rc_one: 'one', rc: '.gvimrc'}, g:)
+ call writefile(v:errors, 'Xresult')
+ quit
+ END
+ call writefile(lines, 'Xscript', 'D')
+ call system($'{vimcmd} -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+
+ call delete(rc1)
+
+ " Test for ~/.vim/gvimrc
+ let lines =<< trim END
+ " Ignore the "failed to create input context" error.
+ call test_ignore_error('E285')
+ gui -f
+ call assert_match('Xhome/\.vim/gvimrc', $MYGVIMRC)
+ call filter(g:, {idx, _ -> idx =~ '^rc'})
+ call assert_equal(#{rc_two: 'two', rc: '.vim/gvimrc'}, g:)
+ call writefile(v:errors, 'Xresult')
+ quit
+ END
+ call writefile(lines, 'Xscript', 'D')
+ call system($'{vimcmd} -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+
+ call delete(rc2)
+
+ " Test for ~/.config/vim/gvimrc
+ let lines =<< trim END
+ " Ignore the "failed to create input context" error.
+ call test_ignore_error('E285')
+ gui -f
+ let msg = $'HOME="{$HOME}", ~="{expand("~")}"'
+ call assert_match('Xhome/\.config/vim/gvimrc', $MYGVIMRC, msg)
+ call filter(g:, {idx, _ -> idx =~ '^rc'})
+ call assert_equal(#{rc_three: 'three', rc: '.config/vim/gvimrc'}, g:)
+ call writefile(v:errors, 'Xresult')
+ quit
+ END
+ call writefile(lines, 'Xscript', 'D')
+ call system($'{vimcmd} -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+
+ call delete(rc3)
+
+ " Test for ~/xdg/vim/gvimrc
+ let $XDG_CONFIG_HOME=expand('~/xdg/')
+ let lines =<< trim END
+ " Ignore the "failed to create input context" error.
+ call test_ignore_error('E285')
+ gui -f
+ let msg = $'HOME="{$HOME}", XDG_CONFIG_HOME="{$XDG_CONFIG_HOME}"'
+ call assert_match('Xhome/xdg/vim/gvimrc', $MYGVIMRC, msg)
+ call filter(g:, {idx, _ -> idx =~ '^rc'})
+ call assert_equal(#{rc_four: 'four', rc: 'xdg/vim/gvimrc'}, g:)
+ call writefile(v:errors, 'Xresult')
+ quit
+ END
+ call writefile(lines, 'Xscript', 'D')
+ call system($'{vimcmd} -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+
+ call delete(rc4)
+
+ " Clean up
+ unlet $XDG_CONFIG_HOME
+ call GUITearDownCommon()
+ call delete('Xhome', 'rf')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/vim9.vim b/src/testdir/vim9.vim
index 782809b..ff4db7b 100644
--- a/src/testdir/vim9.vim
+++ b/src/testdir/vim9.vim
@@ -110,40 +110,6 @@ export def CheckScriptSuccess(lines: list<string>)
endtry
enddef
-# :source a list of "lines" and check whether it fails with "error"
-export def CheckSourceFailure(lines: list<string>, error: string, lnum = -3)
- new
- setline(1, lines)
- try
- assert_fails('source', error, lines, lnum)
- finally
- bw!
- endtry
-enddef
-
-# :source a list of "lines" and check whether it fails with the list of
-# "errors"
-export def CheckSourceFailureList(lines: list<string>, errors: list<string>, lnum = -3)
- new
- setline(1, lines)
- try
- assert_fails('source', errors, lines, lnum)
- finally
- bw!
- endtry
-enddef
-
-# :source a list of "lines" and check whether it succeeds
-export def CheckSourceSuccess(lines: list<string>)
- new
- setline(1, lines)
- try
- :source
- finally
- bw!
- endtry
-enddef
-
export def CheckDefAndScriptSuccess(lines: list<string>)
CheckDefSuccess(lines)
CheckScriptSuccess(['vim9script'] + lines)
@@ -307,3 +273,177 @@ export def CheckLegacyAndVim9Failure(lines: list<string>, error: any)
CheckDefExecFailure(vim9lines, defError)
CheckScriptFailure(['vim9script'] + vim9lines, scriptError)
enddef
+
+# :source a list of "lines" and check whether it fails with "error"
+export def CheckSourceScriptFailure(lines: list<string>, error: string, lnum = -3)
+ var cwd = getcwd()
+ new
+ setline(1, lines)
+ var bnr = bufnr()
+ try
+ assert_fails('source', error, lines, lnum)
+ finally
+ chdir(cwd)
+ exe $':bw! {bnr}'
+ endtry
+enddef
+
+# :source a list of "lines" and check whether it fails with the list of
+# "errors"
+export def CheckSourceScriptFailureList(lines: list<string>, errors: list<string>, lnum = -3)
+ var cwd = getcwd()
+ new
+ var bnr = bufnr()
+ setline(1, lines)
+ try
+ assert_fails('source', errors, lines, lnum)
+ finally
+ chdir(cwd)
+ exe $':bw! {bnr}'
+ endtry
+enddef
+
+# :source a list of "lines" and check whether it succeeds
+export def CheckSourceScriptSuccess(lines: list<string>)
+ var cwd = getcwd()
+ new
+ var bnr = bufnr()
+ setline(1, lines)
+ try
+ :source
+ finally
+ chdir(cwd)
+ exe $':bw! {bnr}'
+ endtry
+enddef
+
+export def CheckSourceSuccess(lines: list<string>)
+ CheckSourceScriptSuccess(lines)
+enddef
+
+export def CheckSourceFailure(lines: list<string>, error: string, lnum = -3)
+ CheckSourceScriptFailure(lines, error, lnum)
+enddef
+
+export def CheckSourceFailureList(lines: list<string>, errors: list<string>, lnum = -3)
+ CheckSourceScriptFailureList(lines, errors, lnum)
+enddef
+
+# :source a List of "lines" inside a ":def" function and check that no error
+# occurs when called.
+export func CheckSourceDefSuccess(lines)
+ let cwd = getcwd()
+ new
+ let bnr = bufnr()
+ call setline(1, ['def Func()'] + a:lines + ['enddef', 'defcompile'])
+ try
+ source
+ call Func()
+ finally
+ call chdir(cwd)
+ delfunc! Func
+ exe $'bw! {bnr}'
+ endtry
+endfunc
+
+export def CheckSourceDefAndScriptSuccess(lines: list<string>)
+ CheckSourceDefSuccess(lines)
+ CheckSourceScriptSuccess(['vim9script'] + lines)
+enddef
+
+# Check that "lines" inside a ":def" function has no error when compiled.
+export func CheckSourceDefCompileSuccess(lines)
+ let cwd = getcwd()
+ new
+ let bnr = bufnr()
+ call setline(1, ['def Func()', '# comment'] + a:lines + ['#comment', 'enddef', 'defcompile'])
+ try
+ source
+ finally
+ call chdir(cwd)
+ delfunc! Func
+ exe $':bw! {bnr}'
+ endtry
+endfunc
+
+# Check that "lines" inside ":def" results in an "error" message.
+# If "lnum" is given check that the error is reported for this line.
+# Add a line before and after to make it less likely that the line number is
+# accidentally correct.
+export func CheckSourceDefFailure(lines, error, lnum = -3)
+ let cwd = getcwd()
+ new
+ let bnr = bufnr()
+ call setline(1, ['def Func()', '# comment'] + a:lines + ['#comment', 'enddef', 'defcompile'])
+ try
+ call assert_fails('source', a:error, a:lines, a:lnum + 1)
+ finally
+ call chdir(cwd)
+ delfunc! Func
+ exe $':bw! {bnr}'
+ endtry
+endfunc
+
+# Check that "lines" inside ":def" results in an "error" message when executed.
+# If "lnum" is given check that the error is reported for this line.
+# Add a line before and after to make it less likely that the line number is
+# accidentally correct.
+export func CheckSourceDefExecFailure(lines, error, lnum = -3)
+ let cwd = getcwd()
+ new
+ let bnr = bufnr()
+ call setline(1, ['def Func()', '# comment'] + a:lines + ['#comment', 'enddef'])
+ try
+ source
+ call assert_fails('call Func()', a:error, a:lines, a:lnum + 1)
+ finally
+ call chdir(cwd)
+ delfunc! Func
+ exe $':bw! {bnr}'
+ endtry
+endfunc
+
+# Check that a command fails when used in a :def function and when used in
+# Vim9 script.
+# When "error" is a string, both with the same error.
+# When "error" is a list, the :def function fails with "error[0]" , the script
+# fails with "error[1]".
+export def CheckSourceDefAndScriptFailure(lines: list<string>, error: any, lnum = -3)
+ var errorDef: string
+ var errorScript: string
+ if type(error) == v:t_string
+ errorDef = error
+ errorScript = error
+ elseif type(error) == v:t_list && len(error) == 2
+ errorDef = error[0]
+ errorScript = error[1]
+ else
+ echoerr 'error argument must be a string or a list with two items'
+ return
+ endif
+ CheckSourceDefFailure(lines, errorDef, lnum)
+ CheckSourceScriptFailure(['vim9script'] + lines, errorScript, lnum + 1)
+enddef
+
+# Check that a command fails when executed in a :def function and when used in
+# Vim9 script.
+# When "error" is a string, both with the same error.
+# When "error" is a list, the :def function fails with "error[0]" , the script
+# fails with "error[1]".
+export def CheckSourceDefExecAndScriptFailure(lines: list<string>, error: any, lnum = -3)
+ var errorDef: string
+ var errorScript: string
+ if type(error) == v:t_string
+ errorDef = error
+ errorScript = error
+ elseif type(error) == v:t_list && len(error) == 2
+ errorDef = error[0]
+ errorScript = error[1]
+ else
+ echoerr 'error argument must be a string or a list with two items'
+ return
+ endif
+ CheckSourceDefExecFailure(lines, errorDef, lnum)
+ CheckSourceScriptFailure(['vim9script'] + lines, errorScript, lnum + 1)
+enddef
+
diff --git a/src/testing.c b/src/testing.c
index 0d731da..33de3a5 100644
--- a/src/testing.c
+++ b/src/testing.c
@@ -1091,9 +1091,8 @@ f_test_refcount(typval_T *argvars, typval_T *rettv)
case VAR_SPECIAL:
case VAR_STRING:
case VAR_INSTR:
- case VAR_CLASS:
- case VAR_OBJECT:
break;
+
case VAR_JOB:
#ifdef FEAT_JOB_CHANNEL
if (argvars[0].vval.v_job != NULL)
@@ -1132,6 +1131,14 @@ f_test_refcount(typval_T *argvars, typval_T *rettv)
if (argvars[0].vval.v_dict != NULL)
retval = argvars[0].vval.v_dict->dv_refcount - 1;
break;
+ case VAR_CLASS:
+ if (argvars[0].vval.v_class != NULL)
+ retval = argvars[0].vval.v_class->class_refcount - 1;
+ break;
+ case VAR_OBJECT:
+ if (argvars[0].vval.v_object != NULL)
+ retval = argvars[0].vval.v_object->obj_refcount - 1;
+ break;
case VAR_TYPEALIAS:
if (argvars[0].vval.v_typealias != NULL)
retval = argvars[0].vval.v_typealias->ta_refcount - 1;
diff --git a/src/textformat.c b/src/textformat.c
index 14acc53..41ec2cf 100644
--- a/src/textformat.c
+++ b/src/textformat.c
@@ -56,6 +56,7 @@ internal_format(
colnr_T leader_len;
int no_leader = FALSE;
int do_comments = (flags & INSCHAR_DO_COM);
+ int safe_tw = trim_to_int(8 * (vimlong_T)textwidth);
#ifdef FEAT_LINEBREAK
int has_lbr = curwin->w_p_lbr;
@@ -95,7 +96,7 @@ internal_format(
// Cursor is currently at the end of line. No need to format
// if line length is less than textwidth (8 * textwidth for
// utf safety)
- if (curwin->w_cursor.col < 8 * textwidth)
+ if (curwin->w_cursor.col < safe_tw)
{
virtcol = get_nolist_virtcol()
+ char2cells(c != NUL ? c : gchar_cursor());
@@ -156,8 +157,7 @@ internal_format(
// line to textwidth border every time for each line break.
//
// Ceil to 8 * textwidth to optimize.
- curwin->w_cursor.col = startcol < 8 * textwidth ? startcol :
- 8 * textwidth;
+ curwin->w_cursor.col = startcol < safe_tw ? startcol : safe_tw;
foundcol = 0;
skip_pos = 0;
diff --git a/src/textprop.c b/src/textprop.c
index a976570..83c42a3 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -672,16 +672,10 @@ prop_count_above_below(buf_T *buf, linenr_T lnum)
mch_memmove(&prop, props + i * sizeof(prop), sizeof(prop));
if (prop.tp_col == MAXCOL && text_prop_type_valid(buf, &prop))
{
- if ((prop.tp_flags & TP_FLAG_ALIGN_BELOW)
+ if ((prop.tp_flags & (TP_FLAG_ALIGN_ABOVE | TP_FLAG_ALIGN_BELOW))
|| (next_right_goes_below
&& (prop.tp_flags & TP_FLAG_ALIGN_RIGHT)))
{
- next_right_goes_below = TRUE;
- ++result;
- }
- else if (prop.tp_flags & TP_FLAG_ALIGN_ABOVE)
- {
- next_right_goes_below = FALSE;
++result;
}
else if (prop.tp_flags & TP_FLAG_ALIGN_RIGHT)
diff --git a/src/typval.c b/src/typval.c
index 62958f6..6a73719 100644
--- a/src/typval.c
+++ b/src/typval.c
@@ -266,7 +266,13 @@ tv_get_bool_or_number_chk(
check_typval_is_value(varp);
break;
case VAR_OBJECT:
- emsg(_(e_using_object_as_number));
+ {
+ class_T *cl = varp->vval.v_object->obj_class;
+ if (cl != NULL && IS_ENUM(cl))
+ semsg(_(e_using_enum_str_as_number), cl->class_name);
+ else
+ emsg(_(e_using_object_as_number));
+ }
break;
case VAR_VOID:
emsg(_(e_cannot_use_void_value));
@@ -1139,7 +1145,13 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
check_typval_is_value(varp);
break;
case VAR_OBJECT:
- emsg(_(e_using_object_as_string));
+ {
+ class_T *cl = varp->vval.v_object->obj_class;
+ if (cl != NULL && IS_ENUM(cl))
+ semsg(_(e_using_enum_str_as_string), cl->class_name);
+ else
+ emsg(_(e_using_object_as_string));
+ }
break;
case VAR_JOB:
#ifdef FEAT_JOB_CHANNEL
diff --git a/src/userfunc.c b/src/userfunc.c
index ce144a3..71b3983 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -555,7 +555,9 @@ parse_argument_types(
type = &t_any;
for (int om = 0; om < obj_member_count; ++om)
{
- if (STRCMP(aname, obj_members[om].ocm_name) == 0)
+ if (obj_members != NULL
+ && STRCMP(aname,
+ obj_members[om].ocm_name) == 0)
{
type = obj_members[om].ocm_type;
break;
@@ -570,10 +572,16 @@ parse_argument_types(
fp->uf_arg_types[i] = type;
if (i < fp->uf_args.ga_len
&& (type->tt_type == VAR_FUNC
- || type->tt_type == VAR_PARTIAL)
- && var_wrong_func_name(
- ((char_u **)fp->uf_args.ga_data)[i], TRUE))
- return FAIL;
+ || type->tt_type == VAR_PARTIAL))
+ {
+ char_u *name = ((char_u **)fp->uf_args.ga_data)[i];
+ if (obj_members != NULL && *name == '_')
+ // protected object method
+ name++;
+
+ if (var_wrong_func_name(name, TRUE))
+ return FAIL;
+ }
}
}
}
@@ -1219,13 +1227,18 @@ get_function_body(
|| checkforcmd(&arg, "const", 5)
|| vim9_function)
{
- while (vim_strchr((char_u *)"$@&", *arg) != NULL)
- ++arg;
- arg = skipwhite(find_name_end(arg, NULL, NULL,
- FNE_INCL_BR | FNE_ALLOW_CURLY));
- if (vim9_function && *arg == ':')
- arg = skipwhite(skip_type(skipwhite(arg + 1), FALSE));
- if (arg[0] == '=' && arg[1] == '<' && arg[2] =='<')
+ int save_sc_version = current_sctx.sc_version;
+ int var_count = 0;
+ int semicolon = 0;
+
+ current_sctx.sc_version
+ = vim9_function ? SCRIPT_VERSION_VIM9 : 1;
+ arg = skip_var_list(arg, TRUE, &var_count, &semicolon,
+ TRUE);
+ if (arg != NULL)
+ arg = skipwhite(arg);
+ current_sctx.sc_version = save_sc_version;
+ if (arg != NULL && STRNCMP(arg, "=<<", 3) == 0)
{
p = skipwhite(arg + 3);
while (TRUE)
@@ -1329,6 +1342,7 @@ lambda_function_body(
char_u *name;
int lnum_save = -1;
linenr_T sourcing_lnum_top = SOURCING_LNUM;
+ char_u *line_arg = NULL;
*arg = skipwhite(*arg + 1);
if (**arg == '|' || !ends_excmd2(start, *arg))
@@ -1337,6 +1351,12 @@ lambda_function_body(
return FAIL;
}
+ // When there is a line break use what follows for the lambda body.
+ // Makes lambda body initializers work for object and enum member
+ // variables.
+ if (**arg == '\n')
+ line_arg = *arg + 1;
+
CLEAR_FIELD(eap);
eap.cmdidx = CMD_block;
eap.forceit = FALSE;
@@ -1351,7 +1371,7 @@ lambda_function_body(
}
ga_init2(&newlines, sizeof(char_u *), 10);
- if (get_function_body(&eap, &newlines, NULL,
+ if (get_function_body(&eap, &newlines, line_arg,
&evalarg->eval_tofree_ga) == FAIL)
goto erret;
@@ -1366,7 +1386,12 @@ lambda_function_body(
for (idx = 0; idx < newlines.ga_len; ++idx)
{
- char_u *p = skipwhite(((char_u **)newlines.ga_data)[idx]);
+ char_u *p = ((char_u **)newlines.ga_data)[idx];
+ if (p == NULL)
+ // comment line in the lambda body
+ continue;
+
+ p = skipwhite(p);
if (ga_grow(gap, 1) == FAIL || ga_grow(freegap, 1) == FAIL)
goto erret;
diff --git a/src/version.c b/src/version.c
index 32037e3..2bd0667 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,356 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 374,
+/**/
+ 373,
+/**/
+ 372,
+/**/
+ 371,
+/**/
+ 370,
+/**/
+ 369,
+/**/
+ 368,
+/**/
+ 367,
+/**/
+ 366,
+/**/
+ 365,
+/**/
+ 364,
+/**/
+ 363,
+/**/
+ 362,
+/**/
+ 361,
+/**/
+ 360,
+/**/
+ 359,
+/**/
+ 358,
+/**/
+ 357,
+/**/
+ 356,
+/**/
+ 355,
+/**/
+ 354,
+/**/
+ 353,
+/**/
+ 352,
+/**/
+ 351,
+/**/
+ 350,
+/**/
+ 349,
+/**/
+ 348,
+/**/
+ 347,
+/**/
+ 346,
+/**/
+ 345,
+/**/
+ 344,
+/**/
+ 343,
+/**/
+ 342,
+/**/
+ 341,
+/**/
+ 340,
+/**/
+ 339,
+/**/
+ 338,
+/**/
+ 337,
+/**/
+ 336,
+/**/
+ 335,
+/**/
+ 334,
+/**/
+ 333,
+/**/
+ 332,
+/**/
+ 331,
+/**/
+ 330,
+/**/
+ 329,
+/**/
+ 328,
+/**/
+ 327,
+/**/
+ 326,
+/**/
+ 325,
+/**/
+ 324,
+/**/
+ 323,
+/**/
+ 322,
+/**/
+ 321,
+/**/
+ 320,
+/**/
+ 319,
+/**/
+ 318,
+/**/
+ 317,
+/**/
+ 316,
+/**/
+ 315,
+/**/
+ 314,
+/**/
+ 313,
+/**/
+ 312,
+/**/
+ 311,
+/**/
+ 310,
+/**/
+ 309,
+/**/
+ 308,
+/**/
+ 307,
+/**/
+ 306,
+/**/
+ 305,
+/**/
+ 304,
+/**/
+ 303,
+/**/
+ 302,
+/**/
+ 301,
+/**/
+ 300,
+/**/
+ 299,
+/**/
+ 298,
+/**/
+ 297,
+/**/
+ 296,
+/**/
+ 295,
+/**/
+ 294,
+/**/
+ 293,
+/**/
+ 292,
+/**/
+ 291,
+/**/
+ 290,
+/**/
+ 289,
+/**/
+ 288,
+/**/
+ 287,
+/**/
+ 286,
+/**/
+ 285,
+/**/
+ 284,
+/**/
+ 283,
+/**/
+ 282,
+/**/
+ 281,
+/**/
+ 280,
+/**/
+ 279,
+/**/
+ 278,
+/**/
+ 277,
+/**/
+ 276,
+/**/
+ 275,
+/**/
+ 274,
+/**/
+ 273,
+/**/
+ 272,
+/**/
+ 271,
+/**/
+ 270,
+/**/
+ 269,
+/**/
+ 268,
+/**/
+ 267,
+/**/
+ 266,
+/**/
+ 265,
+/**/
+ 264,
+/**/
+ 263,
+/**/
+ 262,
+/**/
+ 261,
+/**/
+ 260,
+/**/
+ 259,
+/**/
+ 258,
+/**/
+ 257,
+/**/
+ 256,
+/**/
+ 255,
+/**/
+ 254,
+/**/
+ 253,
+/**/
+ 252,
+/**/
+ 251,
+/**/
+ 250,
+/**/
+ 249,
+/**/
+ 248,
+/**/
+ 247,
+/**/
+ 246,
+/**/
+ 245,
+/**/
+ 244,
+/**/
+ 243,
+/**/
+ 242,
+/**/
+ 241,
+/**/
+ 240,
+/**/
+ 239,
+/**/
+ 238,
+/**/
+ 237,
+/**/
+ 236,
+/**/
+ 235,
+/**/
+ 234,
+/**/
+ 233,
+/**/
+ 232,
+/**/
+ 231,
+/**/
+ 230,
+/**/
+ 229,
+/**/
+ 228,
+/**/
+ 227,
+/**/
+ 226,
+/**/
+ 225,
+/**/
+ 224,
+/**/
+ 223,
+/**/
+ 222,
+/**/
+ 221,
+/**/
+ 220,
+/**/
+ 219,
+/**/
+ 218,
+/**/
+ 217,
+/**/
+ 216,
+/**/
+ 215,
+/**/
+ 214,
+/**/
+ 213,
+/**/
+ 212,
+/**/
+ 211,
+/**/
+ 210,
+/**/
+ 209,
+/**/
+ 208,
+/**/
+ 207,
+/**/
+ 206,
+/**/
+ 205,
+/**/
+ 204,
+/**/
+ 203,
+/**/
+ 202,
+/**/
+ 201,
+/**/
+ 200,
+/**/
199,
/**/
198,
@@ -1469,10 +1819,21 @@ list_version(void)
version_msg(USR_VIMRC_FILE2);
version_msg("\"\n");
#endif
-#ifdef USR_VIMRC_FILE3
+#if defined(USR_VIMRC_FILE3) && defined(XDG_VIMRC_FILE)
version_msg(_(" 3rd user vimrc file: \""));
version_msg(USR_VIMRC_FILE3);
version_msg("\"\n");
+ version_msg(_(" 4th user vimrc file: \""));
+ version_msg((char *)(XDG_VIMRC_FILE));
+ version_msg("\"\n");
+#elif defined(USR_VIMRC_FILE3)
+ version_msg(_(" 3rd user vimrc file: \""));
+ version_msg(USR_VIMRC_FILE3);
+ version_msg("\"\n");
+#elif defined(XDG_VIMRC_FILE)
+ version_msg(_(" 3rd user vimrc file: \""));
+ version_msg((char *)(XDG_VIMRC_FILE));
+ version_msg("\"\n");
#endif
#ifdef USR_EXRC_FILE
version_msg(_(" user exrc file: \""));
diff --git a/src/version.h b/src/version.h
index b9c6d83..13f3bac 100644
--- a/src/version.h
+++ b/src/version.h
@@ -31,7 +31,22 @@
#ifndef VIM_VERSION_PATCHLEVEL
# define VIM_VERSION_PATCHLEVEL 0
#endif
-#define VIM_VERSION_PATCHLEVEL_STR VIM_TOSTR(VIM_VERSION_PATCHLEVEL)
+
+// Patchlevel with leading zeros
+// For compatibility with the installer from "vim-win32-installer" and WinGet.
+// For details see https://github.com/vim/vim-win32-installer/pull/277
+// and https://github.com/vim/vim-win32-installer/pull/285
+#if VIM_VERSION_PATCHLEVEL < 10
+#define LEADZERO(x) 000 ## x
+#elif VIM_VERSION_PATCHLEVEL < 100
+#define LEADZERO(x) 00 ## x
+#elif VIM_VERSION_PATCHLEVEL < 1000
+#define LEADZERO(x) 0 ## x
+#else
+#define LEADZERO(x) x
+#endif
+
+#define VIM_VERSION_PATCHLEVEL_STR VIM_TOSTR(LEADZERO(VIM_VERSION_PATCHLEVEL))
// Used by MacOS port; should be one of: development, alpha, beta, final
#define VIM_VERSION_RELEASE final
diff --git a/src/vim.h b/src/vim.h
index 85d92d5..f359245 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -36,7 +36,7 @@
# error configure did not run properly. Check auto/config.log.
# endif
-# if (defined(__linux__) && !defined(__ANDROID__)) || defined(__CYGWIN__)
+# if (defined(__linux__) && !defined(__ANDROID__)) || defined(__CYGWIN__) || defined(__GNU__)
// Needed for strptime(). Needs to be done early, since header files can
// include other header files and end up including time.h, where these symbols
// matter for Vim.
@@ -656,8 +656,8 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define VALID_VIRTCOL 0x04 // w_virtcol (file col) is valid
#define VALID_CHEIGHT 0x08 // w_cline_height and w_cline_folded valid
#define VALID_CROW 0x10 // w_cline_row is valid
-#define VALID_BOTLINE 0x20 // w_botine and w_empty_rows are valid
-#define VALID_BOTLINE_AP 0x40 // w_botine is approximated
+#define VALID_BOTLINE 0x20 // w_botline and w_empty_rows are valid
+#define VALID_BOTLINE_AP 0x40 // w_botline is approximated
#define VALID_TOPLINE 0x80 // w_topline is valid (for cursor position)
// Values for w_popup_flags.
@@ -1404,6 +1404,7 @@ enum auto_event
EVENT_SAFESTATE, // going to wait for a character
EVENT_SAFESTATEAGAIN, // still waiting for a character
EVENT_SESSIONLOADPOST, // after loading a session file
+ EVENT_SESSIONWRITEPOST, // after writing a session file
EVENT_SHELLCMDPOST, // after ":!cmd"
EVENT_SHELLFILTERPOST, // after ":1,2!cmd", ":w !cmd", ":r !cmd".
EVENT_SIGUSR1, // after the SIGUSR1 signal
@@ -1514,6 +1515,7 @@ typedef enum
, HLF_QFL // quickfix window line currently selected
, HLF_ST // status lines of terminal windows
, HLF_STNC // status lines of not-current terminal windows
+ , HLF_MSG // message area
, HLF_COUNT // MUST be the last one
} hlf_T;
@@ -1525,7 +1527,7 @@ typedef enum
'B', 'P', 'R', 'L', \
'+', '=', '[', ']', '{', '}', 'x', 'X', \
'*', '#', '_', '!', '.', 'o', 'q', \
- 'z', 'Z'}
+ 'z', 'Z', 'g'}
/*
* Boolean constants
@@ -2163,7 +2165,9 @@ typedef int sock_T;
#define VV_MAXCOL 105
#define VV_PYTHON3_VERSION 106
#define VV_TYPE_TYPEALIAS 107
-#define VV_LEN 108 // number of v: vars
+#define VV_TYPE_ENUM 108
+#define VV_TYPE_ENUMVALUE 109
+#define VV_LEN 110 // number of v: vars
// used for v_number in VAR_BOOL and VAR_SPECIAL
#define VVAL_FALSE 0L // VAR_BOOL
@@ -2187,6 +2191,8 @@ typedef int sock_T;
#define VAR_TYPE_CLASS 12
#define VAR_TYPE_OBJECT 13
#define VAR_TYPE_TYPEALIAS 14
+#define VAR_TYPE_ENUM 15
+#define VAR_TYPE_ENUMVALUE 16
#define DICT_MAXNEST 100 // maximum nesting of lists and dicts
@@ -2812,7 +2818,6 @@ typedef int (*opt_expand_cb_T)(optexpand_T *args, int *numMatches, char_u ***mat
// flags for find_name_end()
#define FNE_INCL_BR 1 // include [] in name
#define FNE_CHECK_START 2 // check name starts with valid character
-#define FNE_ALLOW_CURLY 4 // always allow curly braces name
// BSD is supposed to cover FreeBSD and similar systems.
#if (defined(SUN_SYSTEM) || defined(BSD) || defined(__FreeBSD_kernel__)) \
diff --git a/src/vim9.h b/src/vim9.h
index dd5ad73..54938fe 100644
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -460,7 +460,7 @@ typedef struct {
// arguments to ISN_2STRING and ISN_2STRING_ANY
typedef struct {
int offset;
- int tolerant;
+ int flags;
} tostring_T;
// arguments to ISN_2BOOL
@@ -780,6 +780,7 @@ typedef enum {
dest_vimvar,
dest_class_member,
dest_script,
+ dest_script_v9,
dest_reg,
dest_expr,
} assign_dest_T;
@@ -880,3 +881,10 @@ typedef enum {
// flags for call_def_function()
#define DEF_USE_PT_ARGV 1 // use the partial arguments
+
+// Flag used for conversion to string by may_generate_2STRING()
+#define TOSTRING_NONE 0x0
+// Convert a List to series of values separated by newline
+#define TOSTRING_INTERPOLATE 0x1
+// Convert a List to a textual representation of the list "[...]"
+#define TOSTRING_TOLERANT 0x2
diff --git a/src/vim9class.c b/src/vim9class.c
index 7227c3d..52c2f76 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -168,7 +168,8 @@ struct oc_newmember_S
/*
* Add a member to an object or a class.
* Returns OK when successful, "init_expr" will be consumed then.
- * Returns FAIL otherwise, caller might need to free "init_expr".
+ * Returns OK on success and FAIL on memory allocation failure (caller might
+ * need to free "init_expr").
*/
static int
add_member(
@@ -323,13 +324,15 @@ validate_extends_class(
}
if (tv.v_type != VAR_CLASS || tv.vval.v_class == NULL
- || (is_class
- && (tv.vval.v_class->class_flags & CLASS_INTERFACE) != 0)
- || (!is_class
- && (tv.vval.v_class->class_flags & CLASS_INTERFACE) == 0))
- // a interface cannot extend a class and a class cannot extend an
- // interface.
+ || (is_class && IS_INTERFACE(tv.vval.v_class))
+ || (!is_class && !IS_INTERFACE(tv.vval.v_class))
+ || (is_class && IS_ENUM(tv.vval.v_class)))
+ {
+ // a class cannot extend an interface
+ // an interface cannot extend a class
+ // a class cannot extend an enum.
semsg(_(e_cannot_extend_str), extends_name);
+ }
else
{
class_T *extends_cl = tv.vval.v_class;
@@ -793,7 +796,7 @@ validate_implements_classes(
if (tv.v_type != VAR_CLASS
|| tv.vval.v_class == NULL
- || (tv.vval.v_class->class_flags & CLASS_INTERFACE) == 0)
+ || !IS_INTERFACE(tv.vval.v_class))
{
semsg(_(e_not_valid_interface_str), impl);
success = FALSE;
@@ -1234,14 +1237,14 @@ add_lookup_tables(class_T *cl, class_T *extends_cl, garray_T *objmethods_gap)
* Add class members to a new class. Allocate a typval for each class member
* and initialize it.
*/
- static void
+ static int
add_class_members(class_T *cl, exarg_T *eap, garray_T *type_list_gap)
{
// Allocate a typval for each class member and initialize it.
cl->class_members_tv = ALLOC_CLEAR_MULT(typval_T,
cl->class_class_member_count);
if (cl->class_members_tv == NULL)
- return;
+ return FAIL;
for (int i = 0; i < cl->class_class_member_count; ++i)
{
@@ -1250,19 +1253,19 @@ add_class_members(class_T *cl, exarg_T *eap, garray_T *type_list_gap)
if (m->ocm_init != NULL)
{
typval_T *etv = eval_expr(m->ocm_init, eap);
- if (etv != NULL)
- {
- if (m->ocm_type->tt_type == VAR_ANY
- && !(m->ocm_flags & OCMFLAG_HAS_TYPE)
- && etv->v_type != VAR_SPECIAL)
- // If the member variable type is not yet set, then use
- // the initialization expression type.
- m->ocm_type = typval2type(etv, get_copyID(),
- type_list_gap,
- TVTT_DO_MEMBER|TVTT_MORE_SPECIFIC);
- *tv = *etv;
- vim_free(etv);
- }
+ if (etv == NULL)
+ return FAIL;
+
+ if (m->ocm_type->tt_type == VAR_ANY
+ && !(m->ocm_flags & OCMFLAG_HAS_TYPE)
+ && etv->v_type != VAR_SPECIAL)
+ // If the member variable type is not yet set, then use
+ // the initialization expression type.
+ m->ocm_type = typval2type(etv, get_copyID(),
+ type_list_gap,
+ TVTT_DO_MEMBER|TVTT_MORE_SPECIFIC);
+ *tv = *etv;
+ vim_free(etv);
}
else
{
@@ -1273,6 +1276,8 @@ add_class_members(class_T *cl, exarg_T *eap, garray_T *type_list_gap)
if (m->ocm_flags & OCMFLAG_CONST)
item_lock(tv, DICT_MAXNEST, TRUE, TRUE);
}
+
+ return OK;
}
/*
@@ -1284,13 +1289,21 @@ add_default_constructor(
garray_T *classfunctions_gap,
garray_T *type_list_gap)
{
- garray_T fga;
+ garray_T fga;
+ int is_enum = IS_ENUM(cl);
ga_init2(&fga, 1, 1000);
ga_concat(&fga, (char_u *)"new(");
for (int i = 0; i < cl->class_obj_member_count; ++i)
{
- if (i > 0)
+ if (i < 2 && is_enum)
+ // The first two object variables in an enum are the enum value
+ // name and ordinal. Don't initialize these object variables in
+ // the default constructor as they are already initialized right
+ // after creating the object.
+ continue;
+
+ if (i > (is_enum ? 2 : 0))
ga_concat(&fga, (char_u *)", ");
ga_concat(&fga, (char_u *)"this.");
ocmember_T *m = cl->class_obj_members + i;
@@ -1336,6 +1349,7 @@ add_default_constructor(
* Add the class methods and object methods to the new class "cl".
* When extending a class "extends_cl", add the instance methods from the
* parent class also.
+ * Returns OK on success and FAIL on memory allocation failure.
*/
static int
add_classfuncs_objmethods(
@@ -1373,7 +1387,7 @@ add_classfuncs_objmethods(
if (gap->ga_len != 0)
mch_memmove(*fup, gap->ga_data, sizeof(ufunc_T *) * gap->ga_len);
- vim_free(gap->ga_data);
+ VIM_CLEAR(gap->ga_data);
if (loop == 1)
cl->class_class_function_count_child = gap->ga_len;
else
@@ -1422,6 +1436,8 @@ add_classfuncs_objmethods(
if (loop == 2)
fp->uf_flags |= FC_OBJECT;
}
+
+ ga_clear(gap);
}
return OK;
@@ -1471,6 +1487,246 @@ find_class_name_end(char_u *arg)
return end;
}
+/*
+ * Returns TRUE if the enum value "varname" is already defined.
+ */
+ static int
+is_duplicate_enum(
+ garray_T *enum_gap,
+ char_u *varname,
+ char_u *varname_end)
+{
+ char_u *name = vim_strnsave(varname, varname_end - varname);
+ int dup = FALSE;
+
+ for (int i = 0; i < enum_gap->ga_len; ++i)
+ {
+ ocmember_T *m = ((ocmember_T *)enum_gap->ga_data) + i;
+ if (STRCMP(name, m->ocm_name) == 0)
+ {
+ semsg(_(e_duplicate_enum_str), name);
+ dup = TRUE;
+ break;
+ }
+ }
+
+ vim_free(name);
+ return dup;
+}
+
+/*
+ * Parse the enum values in "line" separated by comma and add them to "gap".
+ * If the last enum value is found, then "enum_end" is set to TRUE.
+ */
+ static int
+enum_parse_values(
+ exarg_T *eap,
+ class_T *en,
+ char_u *line,
+ garray_T *gap,
+ int *num_enum_values,
+ int *enum_end)
+{
+ evalarg_T evalarg;
+ char_u *p = line;
+ char initexpr_buf[1024];
+ char_u last_char = NUL;
+ int rc = OK;
+
+ fill_evalarg_from_eap(&evalarg, eap, FALSE);
+
+ int did_emsg_before = did_emsg;
+ while (*p != NUL)
+ {
+ // ignore comment
+ if (*p == '#')
+ break;
+
+ if (!eval_isnamec1(*p))
+ {
+ semsg(_(e_invalid_enum_value_declaration_str), p);
+ break;
+ }
+
+ char_u *eni_name_start = p;
+ char_u *eni_name_end = to_name_end(p, FALSE);
+
+ if (is_duplicate_enum(gap, eni_name_start, eni_name_end))
+ break;
+
+ p = skipwhite(eni_name_end);
+
+ char_u *init_expr = NULL;
+ if (*p == '(')
+ {
+ if (VIM_ISWHITE(p[-1]))
+ {
+ semsg(_(e_no_white_space_allowed_before_str_str), "(", line);
+ break;
+ }
+
+ char_u *expr_start, *expr_end;
+
+ p = eni_name_start;
+ (void)skip_expr_concatenate(&p, &expr_start, &expr_end, &evalarg);
+
+ while (*expr_start && *expr_start != '(')
+ expr_start++;
+
+ if (expr_end > expr_start)
+ init_expr = vim_strnsave(expr_start, expr_end - expr_start);
+ }
+
+ if (init_expr == NULL)
+ vim_snprintf(initexpr_buf, sizeof(initexpr_buf), "%s.new()",
+ en->class_name);
+ else
+ {
+ vim_snprintf(initexpr_buf, sizeof(initexpr_buf), "%s.new%s",
+ en->class_name, init_expr);
+ vim_free(init_expr);
+ }
+ if (add_member(gap, eni_name_start, eni_name_end, FALSE,
+ TRUE, TRUE, TRUE, &en->class_object_type,
+ vim_strsave((char_u *)initexpr_buf)) == FAIL)
+ break;
+
+ ++*num_enum_values;
+
+ if (*p != '#')
+ last_char = *p;
+
+ if (*p != NUL && *p != ',')
+ break;
+
+ if (*p == ',')
+ {
+ if (!IS_WHITE_OR_NUL(p[1]))
+ {
+ semsg(_(e_white_space_required_after_str_str), ",", line);
+ break;
+ }
+ if (VIM_ISWHITE(p[-1]))
+ {
+ semsg(_(e_no_white_space_allowed_before_str_str), ",", line);
+ break;
+ }
+ p = skipwhite(p + 1);
+ }
+ }
+
+ if (*p != NUL && *p != '#')
+ {
+ if (did_emsg == did_emsg_before)
+ semsg(_(e_missing_comma_before_argument_str), p);
+ rc = FAIL;
+ }
+
+ if (last_char != ',')
+ // last enum value should not be terminated by ","
+ *enum_end = TRUE;
+
+ // Free the memory pointed by expr_start.
+ clear_evalarg(&evalarg, NULL);
+
+ return rc;
+}
+
+/*
+ * Add the "values" class variable (List of enum value objects) to the enum
+ * class "en"
+ */
+ static int
+enum_add_values_member(
+ class_T *en,
+ garray_T *gap,
+ int num_enum_values,
+ garray_T *type_list_gap)
+{
+ garray_T fga;
+ int rc = FAIL;
+
+ ga_init2(&fga, 1, 1000);
+ ga_concat(&fga, (char_u *)"[");
+ for (int i = 0; i < num_enum_values; ++i)
+ {
+ ocmember_T *m = ((ocmember_T *)gap->ga_data) + i;
+
+ if (i > 0)
+ ga_concat(&fga, (char_u *)", ");
+ ga_concat(&fga, en->class_name);
+ ga_concat(&fga, (char_u *)".");
+ ga_concat(&fga, (char_u *)m->ocm_name);
+ }
+ ga_concat(&fga, (char_u *)"]");
+ ga_append(&fga, NUL);
+
+ char_u *varname = (char_u *)"values";
+
+ type_T *type = get_type_ptr(type_list_gap);
+ if (type == NULL)
+ goto done;
+
+ type->tt_type = VAR_LIST;
+ type->tt_member = get_type_ptr(type_list_gap);
+ if (type->tt_member != NULL)
+ {
+ type->tt_member->tt_type = VAR_OBJECT;
+ type->tt_member->tt_class = en;
+ }
+
+ rc = add_member(gap, varname, varname + 6, FALSE, FALSE, TRUE, TRUE, type,
+ vim_strsave((char_u *)fga.ga_data));
+
+done:
+ vim_free(fga.ga_data);
+
+ return rc;
+}
+
+/*
+ * Clear the constructor method names in a enum class, so that an enum class
+ * cannot be instantiated.
+ */
+ static void
+enum_clear_constructors(class_T *en)
+{
+ for (int i = 0; i < en->class_class_function_count; ++i)
+ {
+ ufunc_T *fp = en->class_class_functions[i];
+
+ if (fp->uf_flags & FC_NEW)
+ *fp->uf_name = NUL;
+ }
+}
+
+/*
+ * Initialize the name and ordinal object variable in the enum value "enval" in
+ * the enum "en". These values are set during the enum value object creation.
+ */
+ void
+enum_set_internal_obj_vars(class_T *en, object_T *enval)
+{
+ int i;
+
+ for (i = 0; i < en->class_class_member_count; ++i)
+ {
+ typval_T *en_tv = en->class_members_tv + i;
+ if (en_tv != NULL && en_tv->v_type == VAR_UNKNOWN)
+ break;
+ }
+
+ // First object variable is the name
+ ocmember_T *value_ocm = en->class_class_members + i;
+ typval_T *name_tv = (typval_T *)(enval + 1);
+ name_tv->v_type = VAR_STRING;
+ name_tv->vval.v_string = vim_strsave(value_ocm->ocm_name);
+
+ // Second object variable is the ordinal
+ typval_T *ord_tv = (typval_T *)(name_tv + 1);
+ ord_tv->v_type = VAR_NUMBER;
+ ord_tv->vval.v_number = i;
+}
/*
* Handle ":class" and ":abstract class" up to ":endclass".
@@ -1479,10 +1735,12 @@ find_class_name_end(char_u *arg)
void
ex_class(exarg_T *eap)
{
- int is_class = eap->cmdidx == CMD_class; // FALSE for :interface
+ int is_class = eap->cmdidx == CMD_class;
+ int is_abstract = eap->cmdidx == CMD_abstract;
+ int is_enum = eap->cmdidx == CMD_enum;
+ int is_interface;
long start_lnum = SOURCING_LNUM;
char_u *arg = eap->arg;
- int is_abstract = eap->cmdidx == CMD_abstract;
if (is_abstract)
{
@@ -1495,12 +1753,16 @@ ex_class(exarg_T *eap)
is_class = TRUE;
}
+ is_interface = !is_class && !is_enum;
+
if (!current_script_is_vim9()
|| (cmdmod.cmod_flags & CMOD_LEGACY)
|| !getline_equal(eap->ea_getline, eap->cookie, getsourceline))
{
if (is_class)
emsg(_(e_class_can_only_be_defined_in_vim9_script));
+ else if (is_enum)
+ emsg(_(e_enum_can_only_be_defined_in_vim9_script));
else
emsg(_(e_interface_can_only_be_defined_in_vim9_script));
return;
@@ -1510,6 +1772,8 @@ ex_class(exarg_T *eap)
{
if (is_class)
semsg(_(e_class_name_must_start_with_uppercase_letter_str), arg);
+ else if (is_enum)
+ semsg(_(e_enum_name_must_start_with_uppercase_letter_str), arg);
else
semsg(_(e_interface_name_must_start_with_uppercase_letter_str),
arg);
@@ -1523,11 +1787,6 @@ ex_class(exarg_T *eap)
}
char_u *name_start = arg;
- // "export class" gets used when creating the class, don't use "is_export"
- // for the items inside the class.
- int class_export = is_export;
- is_export = FALSE;
-
// TODO:
// generics: <Tkey, Tentry>
@@ -1545,6 +1804,11 @@ ex_class(exarg_T *eap)
// specifies SomeInterface
if (STRNCMP(arg, "extends", 7) == 0 && IS_WHITE_OR_NUL(arg[7]))
{
+ if (is_enum)
+ {
+ emsg(_(e_enum_cannot_extend_class));
+ goto early_ret;
+ }
if (extends != NULL)
{
emsg(_(e_duplicate_extends));
@@ -1567,7 +1831,7 @@ ex_class(exarg_T *eap)
else if (STRNCMP(arg, "implements", 10) == 0
&& IS_WHITE_OR_NUL(arg[10]))
{
- if (!is_class)
+ if (is_interface)
{
emsg(_(e_interface_cannot_use_implements));
goto early_ret;
@@ -1652,11 +1916,15 @@ early_ret:
class_T *cl = NULL;
class_T *extends_cl = NULL; // class from "extends" argument
class_T **intf_classes = NULL;
+ int num_enum_values = 0;
cl = ALLOC_CLEAR_ONE(class_T);
if (cl == NULL)
goto cleanup;
- if (!is_class)
+
+ if (is_enum)
+ cl->class_flags = CLASS_ENUM;
+ else if (is_interface)
cl->class_flags = CLASS_INTERFACE;
else if (is_abstract)
cl->class_flags = CLASS_ABSTRACT;
@@ -1666,22 +1934,48 @@ early_ret:
if (cl->class_name == NULL)
goto cleanup;
+ cl->class_type.tt_type = VAR_CLASS;
+ cl->class_type.tt_class = cl;
+ cl->class_object_type.tt_type = VAR_OBJECT;
+ cl->class_object_type.tt_class = cl;
+
// Add the class to the script-local variables.
// TODO: handle other context, e.g. in a function
// TODO: does uf_hash need to be cleared?
typval_T tv;
tv.v_type = VAR_CLASS;
tv.vval.v_class = cl;
- is_export = class_export;
SOURCING_LNUM = start_lnum;
int rc = set_var_const(cl->class_name, current_sctx.sc_sid,
NULL, &tv, FALSE, 0, 0);
if (rc == FAIL)
goto cleanup;
+ if (is_enum)
+ {
+ // All the enum classes have the name and ordinal object variables.
+ char_u *varname = (char_u *)"name";
+ if (add_member(&objmembers, varname, varname + 4, FALSE, FALSE, TRUE,
+ TRUE, &t_string, NULL) == FAIL)
+ goto cleanup;
+
+ varname = (char_u *)"ordinal";
+ if (add_member(&objmembers, varname, varname + 7, FALSE, FALSE, TRUE,
+ TRUE, &t_number, NULL) == FAIL)
+ goto cleanup;
+ }
+
+ // "export class" gets used when creating the class, don't use "is_export"
+ // for the items inside the class.
+ is_export = FALSE;
+
+ // When parsing an enum definition, this denotes whether all the enumerated
+ // values are parsed or not.
+ int enum_end = FALSE;
+
/*
* Go over the body of the class/interface until "endclass" or
- * "endinterface" is found.
+ * "endinterface" or "endenum" is found.
*/
char_u *theline = NULL;
int success = FALSE;
@@ -1704,10 +1998,32 @@ early_ret:
}
char_u *p = line;
- char *end_name = is_class ? "endclass" : "endinterface";
- if (checkforcmd(&p, end_name, is_class ? 4 : 5))
+
+ char *end_name;
+ int shortlen;
+ int fullen;
+ if (is_class)
+ {
+ end_name = "endclass";
+ shortlen = 4;
+ fullen = 8;
+ }
+ else if (is_enum)
+ {
+ end_name = "endenum";
+ shortlen = 4;
+ fullen = 7;
+ }
+ else
+ {
+ end_name = "endinterface";
+ shortlen = 5;
+ fullen = 12;
+ }
+
+ if (checkforcmd(&p, end_name, shortlen))
{
- if (STRNCMP(line, end_name, is_class ? 8 : 12) != 0)
+ if (STRNCMP(line, end_name, fullen) != 0)
semsg(_(e_command_cannot_be_shortened_str), line);
else if (*p == '|' || !ends_excmd2(line, p))
semsg(_(e_trailing_characters_str), p);
@@ -1715,13 +2031,39 @@ early_ret:
success = TRUE;
break;
}
- char *wrong_name = is_class ? "endinterface" : "endclass";
- if (checkforcmd(&p, wrong_name, is_class ? 5 : 4))
+
+ int wrong_endname = FALSE;
+ if (is_class)
+ wrong_endname = checkforcmd(&p, "endinterface", 5)
+ || checkforcmd(&p, "endenum", 4);
+ else if (is_enum)
+ wrong_endname = checkforcmd(&p, "endclass", 4)
+ || checkforcmd(&p, "endinterface", 5);
+ else
+ wrong_endname = checkforcmd(&p, "endclass", 4)
+ || checkforcmd(&p, "endenum", 4);
+ if (wrong_endname)
{
semsg(_(e_invalid_command_str_expected_str), line, end_name);
break;
}
+ if (is_enum && !enum_end)
+ {
+ // In an enum, all the enumerated values are at the beginning
+ // separated by comma. The class and object variables/methods
+ // follow the values.
+ if (enum_parse_values(eap, cl, line, &classmembers,
+ &num_enum_values, &enum_end) == FAIL)
+ break;
+
+ if (enum_end)
+ // Add the enum "values" class variable.
+ enum_add_values_member(cl, &classmembers, num_enum_values,
+ &type_list);
+ continue;
+ }
+
int has_public = FALSE;
if (checkforcmd(&p, "public", 3))
{
@@ -1730,7 +2072,7 @@ early_ret:
semsg(_(e_command_cannot_be_shortened_str), line);
break;
}
- if (!is_class)
+ if (is_interface)
{
emsg(_(e_public_variable_not_supported_in_interface));
break;
@@ -1738,6 +2080,12 @@ early_ret:
has_public = TRUE;
p = skipwhite(line + 6);
+ if (STRNCMP(p, "def", 3) == 0)
+ {
+ emsg(_(e_public_keyword_not_supported_for_method));
+ break;
+ }
+
if (STRNCMP(p, "var", 3) != 0 && STRNCMP(p, "static", 6) != 0
&& STRNCMP(p, "final", 5) != 0 && STRNCMP(p, "const", 5) != 0)
{
@@ -1756,7 +2104,14 @@ early_ret:
break;
}
- if (!is_class)
+ if (is_enum)
+ {
+ // "abstract" not supported in an enum
+ emsg(_(e_abstract_cannot_be_used_in_enum));
+ break;
+ }
+
+ if (is_interface)
{
// "abstract" not supported in an interface
emsg(_(e_abstract_cannot_be_used_in_interface));
@@ -1789,7 +2144,7 @@ early_ret:
break;
}
- if (!is_class)
+ if (is_interface)
{
emsg(_(e_static_member_not_supported_in_interface));
break;
@@ -1812,7 +2167,7 @@ early_ret:
has_var = TRUE;
else if (checkforcmd(&p, "final", 5))
{
- if (!is_class)
+ if (is_interface)
{
emsg(_(e_final_variable_not_supported_in_interface));
break;
@@ -1821,7 +2176,7 @@ early_ret:
}
else if (checkforcmd(&p, "const", 5))
{
- if (!is_class)
+ if (is_interface)
{
emsg(_(e_const_variable_not_supported_in_interface));
break;
@@ -1867,7 +2222,7 @@ early_ret:
break;
}
- if (!is_class && *varname == '_')
+ if (is_interface && *varname == '_')
{
// private variables are not supported in an interface
semsg(_(e_protected_variable_not_supported_in_interface),
@@ -1877,7 +2232,7 @@ early_ret:
if (parse_member(eap, line, varname, has_public,
&varname_end, &has_type, &type_list, &type,
- is_class ? &init_expr: NULL) == FAIL)
+ !is_interface ? &init_expr: NULL) == FAIL)
break;
if (is_reserved_varname(varname, varname_end)
@@ -1930,7 +2285,7 @@ early_ret:
break;
}
- if (!is_class && *p == '_')
+ if (is_interface && *p == '_')
{
// private methods are not supported in an interface
semsg(_(e_protected_method_not_supported_in_interface), p);
@@ -1953,10 +2308,10 @@ early_ret:
ga_init2(&lines_to_free, sizeof(char_u *), 50);
int class_flags;
- if (is_class)
- class_flags = abstract_method ? CF_ABSTRACT_METHOD : CF_CLASS;
- else
+ if (is_interface)
class_flags = CF_INTERFACE;
+ else
+ class_flags = abstract_method ? CF_ABSTRACT_METHOD : CF_CLASS;
ufunc_T *uf = define_function(&ea, NULL, &lines_to_free,
class_flags, objmembers.ga_data, objmembers.ga_len);
ga_clear_strings(&lines_to_free);
@@ -2011,15 +2366,25 @@ early_ret:
{
if (is_class)
semsg(_(e_not_valid_command_in_class_str), line);
+ else if (is_enum)
+ semsg(_(e_not_valid_command_in_enum_str), line);
else
semsg(_(e_not_valid_command_in_interface_str), line);
break;
}
}
+
+ if (theline == NULL && !success && is_enum)
+ emsg(_(e_missing_endenum));
+
vim_free(theline);
+ if (success && is_enum && num_enum_values == 0)
+ // Empty enum statement. Add an empty "values" class variable
+ enum_add_values_member(cl, &classmembers, 0, &type_list);
+
/*
- * Check a few things before defining the class.
+ * Check a few things
*/
// Check the "extends" class is valid.
@@ -2067,7 +2432,8 @@ early_ret:
if (success)
{
- // "endclass" encountered without failures: Create the class.
+ // "endclass" or "endinterface" or "endenum" encountered without any
+ // failures
if (extends_cl != NULL)
{
@@ -2114,10 +2480,6 @@ early_ret:
goto cleanup;
}
- // Allocate a typval for each class member and initialize it.
- if (is_class && cl->class_class_member_count > 0)
- add_class_members(cl, eap, &type_list);
-
int have_new = FALSE;
ufunc_T *class_func = NULL;
for (int i = 0; i < classfunctions.ga_len; ++i)
@@ -2133,7 +2495,7 @@ early_ret:
if (have_new)
// The return type of new() is an object of class "cl"
class_func->uf_ret_type->tt_class = cl;
- else if (is_class && !is_abstract && !have_new)
+ else if ((is_class || is_enum) && !is_abstract && !have_new)
// No new() method was defined, add the default constructor.
add_default_constructor(cl, &classfunctions, &type_list);
@@ -2144,13 +2506,21 @@ early_ret:
update_builtin_method_index(cl);
- cl->class_type.tt_type = VAR_CLASS;
- cl->class_type.tt_class = cl;
- cl->class_object_type.tt_type = VAR_OBJECT;
- cl->class_object_type.tt_class = cl;
+ class_created(cl);
+
+ // Allocate a typval for each class member and initialize it.
+ if ((is_class || is_enum) && cl->class_class_member_count > 0)
+ if (add_class_members(cl, eap, &type_list) == FAIL)
+ goto cleanup;
+
cl->class_type_list = type_list;
- class_created(cl);
+ if (is_enum)
+ {
+ // clear the constructor method names, so that an enum class cannot
+ // be instantiated
+ enum_clear_constructors(cl);
+ }
// TODO:
// - Fill hashtab with object members and methods ?
@@ -2265,15 +2635,6 @@ oc_member_type_by_idx(
}
/*
- * Handle ":enum" up to ":endenum".
- */
- void
-ex_enum(exarg_T *eap UNUSED)
-{
- // TODO
-}
-
-/*
* Type aliases (:type)
*/
@@ -2480,6 +2841,14 @@ call_oc_method(
return FAIL;
}
+ if (*name == '_')
+ {
+ // Protected object or class funcref variable
+ semsg(_(e_cannot_access_protected_variable_str), ocm->ocm_name,
+ cl->class_name);
+ return FAIL;
+ }
+
if (rettv->v_type == VAR_OBJECT)
{
// funcref object variable
@@ -3334,8 +3703,14 @@ member_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len)
semsg(_(e_object_variable_str_accessible_only_using_object_str),
varname, cl->class_name);
else
- semsg(_(e_class_variable_str_not_found_in_class_str),
- varname, cl->class_name);
+ {
+ if (IS_ENUM(cl))
+ semsg(_(e_enum_value_str_not_found_in_enum_str),
+ varname, cl->class_name);
+ else
+ semsg(_(e_class_variable_str_not_found_in_class_str),
+ varname, cl->class_name);
+ }
}
vim_free(varname);
}
@@ -3354,7 +3729,9 @@ defcompile_class(class_T *cl)
{
ufunc_T *ufunc = loop == 1 ? cl->class_class_functions[i]
: cl->class_obj_methods[i];
- defcompile_function(ufunc, cl);
+ // Don't compile abstract methods
+ if (!IS_ABSTRACT_METHOD(ufunc))
+ defcompile_function(ufunc, cl);
}
}
}
@@ -3426,7 +3803,7 @@ object_call_builtin_method(
}
/*
- * Calls the object "empty()" method and returns the method retun value. In
+ * Calls the object "empty()" method and returns the method return value. In
* case of an error, returns TRUE.
*/
int
@@ -3480,10 +3857,21 @@ object_string(
garray_T ga;
ga_init2(&ga, 1, 50);
- ga_concat(&ga, (char_u *)"object of ");
class_T *cl = obj == NULL ? NULL : obj->obj_class;
- ga_concat(&ga, cl == NULL ? (char_u *)"[unknown]"
- : cl->class_name);
+ if (cl != NULL && IS_ENUM(cl))
+ {
+ ga_concat(&ga, (char_u *)"enum ");
+ ga_concat(&ga, cl->class_name);
+ char_u *enum_name = ((typval_T *)(obj + 1))->vval.v_string;
+ ga_concat(&ga, (char_u *)".");
+ ga_concat(&ga, enum_name);
+ }
+ else
+ {
+ ga_concat(&ga, (char_u *)"object of ");
+ ga_concat(&ga, cl == NULL ? (char_u *)"[unknown]"
+ : cl->class_name);
+ }
if (cl != NULL)
{
ga_concat(&ga, (char_u *)" {");
diff --git a/src/vim9cmds.c b/src/vim9cmds.c
index ad245b9..694bb33 100644
--- a/src/vim9cmds.c
+++ b/src/vim9cmds.c
@@ -1931,7 +1931,7 @@ compile_throw(char_u *arg, cctx_T *cctx UNUSED)
return NULL;
if (cctx->ctx_skip == SKIP_YES)
return p;
- if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
+ if (may_generate_2STRING(-1, TOSTRING_NONE, cctx) == FAIL)
return NULL;
if (generate_instr_drop(cctx, ISN_THROW, 1) == NULL)
return NULL;
@@ -2359,7 +2359,7 @@ compile_exec(char_u *line_arg, exarg_T *eap, cctx_T *cctx)
p += 2;
if (compile_expr0(&p, cctx) == FAIL)
return NULL;
- may_generate_2STRING(-1, TRUE, cctx);
+ may_generate_2STRING(-1, TOSTRING_TOLERANT, cctx);
++count;
p = skipwhite(p);
if (*p != '`')
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 8f67d8a..8e6f6e2 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1222,7 +1222,7 @@ compile_one_expr_in_str(char_u *p, cctx_T *cctx)
}
if (compile_expr0(&block_start, cctx) == FAIL)
return NULL;
- may_generate_2STRING(-1, TRUE, cctx);
+ may_generate_2STRING(-1, TOSTRING_INTERPOLATE, cctx);
return block_end + 1;
}
@@ -1367,6 +1367,7 @@ generate_loadvar(cctx_T *cctx, lhs_T *lhs)
generate_LOAD(cctx, ISN_LOADT, 0, name + 2, type);
break;
case dest_script:
+ case dest_script_v9:
res = compile_load_scriptvar(cctx,
name + (name[1] == ':' ? 2 : 0), NULL, NULL);
break;
@@ -1614,6 +1615,13 @@ lhs_class_member_modifiable(lhs_T *lhs, char_u *var_start, cctx_T *cctx)
return FALSE;
}
+ if (IS_ENUM(cl))
+ {
+ semsg(_(e_enumvalue_str_cannot_be_modified), cl->class_name,
+ m->ocm_name);
+ return FALSE;
+ }
+
// If it is private member variable, then accessing it outside the
// class is not allowed.
// If it is a read only class variable, then it can be modified
@@ -1783,10 +1791,11 @@ compile_lhs(
return FAIL;
lhs->lhs_dest = dest_class_member;
- lhs->lhs_class = cctx->ctx_ufunc->uf_class;
- lhs->lhs_type =
- oc_member_type_by_idx(cctx->ctx_ufunc->uf_class,
- FALSE, lhs->lhs_classmember_idx);
+ // The class variable is defined either in the current class or
+ // in one of the parent class in the hierarchy.
+ lhs->lhs_class = defcl;
+ lhs->lhs_type = oc_member_type_by_idx(defcl, FALSE,
+ lhs->lhs_classmember_idx);
}
else
{
@@ -1830,7 +1839,8 @@ compile_lhs(
return FAIL;
}
- lhs->lhs_dest = dest_script;
+ lhs->lhs_dest = current_script_is_vim9()
+ ? dest_script_v9 : dest_script;
// existing script-local variables should have a type
lhs->lhs_scriptvar_sid = current_sctx.sc_sid;
@@ -2037,6 +2047,25 @@ compile_lhs(
return FAIL;
}
+ if (IS_ENUM(cl))
+ {
+ if (!inside_class(cctx, cl))
+ {
+ semsg(_(e_enumvalue_str_cannot_be_modified),
+ cl->class_name, m->ocm_name);
+ return FALSE;
+ }
+ if (lhs->lhs_type->tt_type == VAR_OBJECT &&
+ lhs->lhs_member_idx < 2)
+ {
+ char *msg = lhs->lhs_member_idx == 0 ?
+ e_enum_str_name_cannot_be_modified :
+ e_enum_str_ordinal_cannot_be_modified;
+ semsg(_(msg), cl->class_name);
+ return FALSE;
+ }
+ }
+
// If it is private member variable, then accessing it outside the
// class is not allowed.
// If it is a read only class variable, then it can be modified
@@ -2304,7 +2333,7 @@ compile_load_lhs_with_index(lhs_T *lhs, char_u *var_start, cctx_T *cctx)
if (compile_load_lhs(lhs, var_start, lhs->lhs_type, cctx) == FAIL)
return FAIL;
}
- if (cl->class_flags & CLASS_INTERFACE)
+ if (IS_INTERFACE(cl))
return generate_GET_ITF_MEMBER(cctx, cl, lhs->lhs_member_idx, type);
return generate_GET_OBJ_MEMBER(cctx, lhs->lhs_member_idx, type);
}
@@ -2394,7 +2423,7 @@ compile_assign_unlet(
return FAIL;
}
if (dest_type == VAR_DICT
- && may_generate_2STRING(-1, FALSE, cctx) == FAIL)
+ && may_generate_2STRING(-1, TOSTRING_NONE, cctx) == FAIL)
return FAIL;
if (dest_type == VAR_LIST || dest_type == VAR_BLOB)
{
@@ -2453,7 +2482,7 @@ compile_assign_unlet(
{
class_T *cl = lhs->lhs_type->tt_class;
- if (cl->class_flags & CLASS_INTERFACE)
+ if (IS_INTERFACE(cl))
{
// "this.value": load "this" object and get the value
// at index for an object or class member get the type
@@ -2948,7 +2977,7 @@ compile_assignment(
if (*op == '.')
{
- if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
+ if (may_generate_2STRING(-1, TOSTRING_NONE, cctx) == FAIL)
goto theend;
}
else
@@ -2999,8 +3028,9 @@ compile_assignment(
else
{
if (is_decl && cmdidx == CMD_const && (lhs.lhs_dest == dest_script
- || lhs.lhs_dest == dest_global
- || lhs.lhs_dest == dest_local))
+ || lhs.lhs_dest == dest_script_v9
+ || lhs.lhs_dest == dest_global
+ || lhs.lhs_dest == dest_local))
// ":const var": lock the value, but not referenced variables
generate_LOCKCONST(cctx);
@@ -3244,254 +3274,185 @@ add_def_function(ufunc_T *ufunc)
}
/*
- * After ex_function() has collected all the function lines: parse and compile
- * the lines into instructions.
- * Adds the function to "def_functions".
- * When "check_return_type" is set then set ufunc->uf_ret_type to the type of
- * the return statement (used for lambda). When uf_ret_type is already set
- * then check that it matches.
- * When "profiling" is true add ISN_PROF_START instructions.
- * "outer_cctx" is set for a nested function.
- * This can be used recursively through compile_lambda(), which may reallocate
- * "def_functions".
- * Returns OK or FAIL.
+ * For an object constructor, generate instruction to setup "this" (the first
+ * local variable) and to initialize the object variables.
*/
- int
-compile_def_function(
- ufunc_T *ufunc,
- int check_return_type,
- compiletype_T compile_type,
- cctx_T *outer_cctx)
+ static int
+obj_constructor_prologue(ufunc_T *ufunc, cctx_T *cctx)
{
- char_u *line = NULL;
- garray_T lines_to_free;
- char_u *p;
- char *errormsg = NULL; // error message
- cctx_T cctx;
- garray_T *instr;
- int did_emsg_before = did_emsg;
- int did_emsg_silent_before = did_emsg_silent;
- int ret = FAIL;
- sctx_T save_current_sctx = current_sctx;
- int save_estack_compiling = estack_compiling;
- int save_cmod_flags = cmdmod.cmod_flags;
- int do_estack_push;
- int new_def_function = FALSE;
-#ifdef FEAT_PROFILE
- int prof_lnum = -1;
-#endif
- int debug_lnum = -1;
-
- // allocated lines are freed at the end
- ga_init2(&lines_to_free, sizeof(char_u *), 50);
+ generate_CONSTRUCT(cctx, ufunc->uf_class);
- // When using a function that was compiled before: Free old instructions.
- // The index is reused. Otherwise add a new entry in "def_functions".
- if (ufunc->uf_dfunc_idx > 0)
+ for (int i = 0; i < ufunc->uf_class->class_obj_member_count; ++i)
{
- dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
- + ufunc->uf_dfunc_idx;
- isn_T *instr_dest = NULL;
+ ocmember_T *m = &ufunc->uf_class->class_obj_members[i];
- switch (compile_type)
+ if (i < 2 && IS_ENUM(ufunc->uf_class))
+ // The first two object variables in an enum are the name
+ // and the ordinal. These are set by the ISN_CONSTRUCT
+ // instruction. So don't generate instructions to set
+ // these variables.
+ continue;
+
+ if (m->ocm_init != NULL)
{
- case CT_PROFILE:
-#ifdef FEAT_PROFILE
- instr_dest = dfunc->df_instr_prof; break;
-#endif
- case CT_NONE: instr_dest = dfunc->df_instr; break;
- case CT_DEBUG: instr_dest = dfunc->df_instr_debug; break;
+ char_u *expr = m->ocm_init;
+
+ if (compile_expr0(&expr, cctx) == FAIL)
+ return FAIL;
+
+ if (!ends_excmd2(m->ocm_init, expr))
+ {
+ semsg(_(e_trailing_characters_str), expr);
+ return FAIL;
+ }
+
+ type_T *type = get_type_on_stack(cctx, 0);
+ if (m->ocm_type->tt_type == VAR_ANY
+ && !(m->ocm_flags & OCMFLAG_HAS_TYPE)
+ && type->tt_type != VAR_SPECIAL)
+ {
+ // If the member variable type is not yet set, then use
+ // the initialization expression type.
+ m->ocm_type = type;
+ }
+ else if (m->ocm_type->tt_type != type->tt_type)
+ {
+ // The type of the member initialization expression is
+ // determined at run time. Add a runtime type check.
+ where_T where = WHERE_INIT;
+ where.wt_kind = WT_MEMBER;
+ where.wt_func_name = (char *)m->ocm_name;
+ if (need_type_where(type, m->ocm_type, FALSE, -1,
+ where, cctx, FALSE, FALSE) == FAIL)
+ return FAIL;
+ }
}
- if (instr_dest != NULL)
- // Was compiled in this mode before: Free old instructions.
- delete_def_function_contents(dfunc, FALSE);
- ga_clear_strings(&dfunc->df_var_names);
- dfunc->df_defer_var_idx = 0;
- }
- else
- {
- if (add_def_function(ufunc) == FAIL)
- return FAIL;
- new_def_function = TRUE;
- }
+ else
+ push_default_value(cctx, m->ocm_type->tt_type, FALSE, NULL);
- if ((ufunc->uf_flags & FC_CLOSURE) && outer_cctx == NULL)
- {
- semsg(_(e_compiling_closure_without_context_str),
- printable_func_name(ufunc));
- return FAIL;
+ generate_STORE_THIS(cctx, i);
}
- ufunc->uf_def_status = UF_COMPILING;
-
- CLEAR_FIELD(cctx);
+ return OK;
+}
- cctx.ctx_compile_type = compile_type;
- cctx.ctx_ufunc = ufunc;
- cctx.ctx_lnum = -1;
- cctx.ctx_outer = outer_cctx;
- ga_init2(&cctx.ctx_locals, sizeof(lvar_T), 10);
- // Each entry on the type stack consists of two type pointers.
- ga_init2(&cctx.ctx_type_stack, sizeof(type2_T), 50);
- cctx.ctx_type_list = &ufunc->uf_type_list;
- ga_init2(&cctx.ctx_instr, sizeof(isn_T), 50);
- instr = &cctx.ctx_instr;
+/*
+ * For an object method and an constructor, generate instruction to setup
+ * "this" (the first local variable). For a constructor, generate instructions
+ * to initialize the object variables.
+ */
+ static int
+obj_method_prologue(ufunc_T *ufunc, cctx_T *cctx)
+{
+ dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
- // Set the context to the function, it may be compiled when called from
- // another script. Set the script version to the most modern one.
- // The line number will be set in next_line_from_context().
- current_sctx = ufunc->uf_script_ctx;
- current_sctx.sc_version = SCRIPT_VERSION_VIM9;
+ if (GA_GROW_FAILS(&dfunc->df_var_names, 1))
+ return FAIL;
- // Don't use the flag from ":legacy" here.
- cmdmod.cmod_flags &= ~CMOD_LEGACY;
+ ((char_u **)dfunc->df_var_names.ga_data)[0] =
+ vim_strsave((char_u *)"this");
+ ++dfunc->df_var_names.ga_len;
- // Make sure error messages are OK.
- do_estack_push = !estack_top_is_ufunc(ufunc, 1);
- if (do_estack_push)
- estack_push_ufunc(ufunc, 1);
- estack_compiling = TRUE;
+ // In the constructor allocate memory for the object and initialize the
+ // object members.
+ if (IS_CONSTRUCTOR_METHOD(ufunc))
+ return obj_constructor_prologue(ufunc, cctx);
- if (check_args_shadowing(ufunc, &cctx) == FAIL)
- goto erret;
+ return OK;
+}
- // For an object method and constructor "this" is the first local variable.
- if (ufunc->uf_flags & (FC_OBJECT|FC_NEW))
+/*
+ * Produce instructions for the default values of optional arguments.
+ */
+ static int
+compile_def_function_default_args(
+ ufunc_T *ufunc,
+ cctx_T *cctx,
+ garray_T *instr)
+{
+ int count = ufunc->uf_def_args.ga_len;
+ int first_def_arg = ufunc->uf_args.ga_len - count;
+ int i;
+ int off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0);
+ int did_set_arg_type = FALSE;
+
+ // Produce instructions for the default values of optional arguments.
+ SOURCING_LNUM = 0; // line number unknown
+ for (i = 0; i < count; ++i)
{
- dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
- + ufunc->uf_dfunc_idx;
- if (GA_GROW_FAILS(&dfunc->df_var_names, 1))
- goto erret;
- ((char_u **)dfunc->df_var_names.ga_data)[0] =
- vim_strsave((char_u *)"this");
- ++dfunc->df_var_names.ga_len;
+ char_u *arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
+ if (STRCMP(arg, "v:none") == 0)
+ // "arg = v:none" means the argument is optional without
+ // setting a value when the argument is missing.
+ continue;
- // In the constructor allocate memory for the object and initialize the
- // object members.
- if (IS_CONSTRUCTOR_METHOD(ufunc))
- {
- generate_CONSTRUCT(&cctx, ufunc->uf_class);
+ type_T *val_type;
+ int arg_idx = first_def_arg + i;
+ where_T where = WHERE_INIT;
+ int jump_instr_idx = instr->ga_len;
+ isn_T *isn;
- for (int i = 0; i < ufunc->uf_class->class_obj_member_count; ++i)
- {
- ocmember_T *m = &ufunc->uf_class->class_obj_members[i];
- if (m->ocm_init != NULL)
- {
- char_u *expr = m->ocm_init;
- if (compile_expr0(&expr, &cctx) == FAIL)
- goto erret;
- if (!ends_excmd2(m->ocm_init, expr))
- {
- semsg(_(e_trailing_characters_str), expr);
- goto erret;
- }
+ // Use a JUMP_IF_ARG_SET instruction to skip if the value was given.
+ if (generate_JUMP_IF_ARG(cctx, ISN_JUMP_IF_ARG_SET,
+ i - count - off) == FAIL)
+ return FAIL;
- type_T *type = get_type_on_stack(&cctx, 0);
- if (m->ocm_type->tt_type == VAR_ANY
- && !(m->ocm_flags & OCMFLAG_HAS_TYPE)
- && type->tt_type != VAR_SPECIAL)
- {
- // If the member variable type is not yet set, then use
- // the initialization expression type.
- m->ocm_type = type;
- }
- else if (m->ocm_type->tt_type != type->tt_type)
- {
- // The type of the member initialization expression is
- // determined at run time. Add a runtime type check.
- where_T where = WHERE_INIT;
- where.wt_kind = WT_MEMBER;
- where.wt_func_name = (char *)m->ocm_name;
- if (need_type_where(type, m->ocm_type, FALSE, -1,
- where, &cctx, FALSE, FALSE) == FAIL)
- goto erret;
- }
- }
- else
- push_default_value(&cctx, m->ocm_type->tt_type,
- FALSE, NULL);
- generate_STORE_THIS(&cctx, i);
- }
- }
- }
+ // Make sure later arguments are not found.
+ ufunc->uf_args_visible = arg_idx;
- if (ufunc->uf_def_args.ga_len > 0)
- {
- int count = ufunc->uf_def_args.ga_len;
- int first_def_arg = ufunc->uf_args.ga_len - count;
- int i;
- int off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0);
- int did_set_arg_type = FALSE;
-
- // Produce instructions for the default values of optional arguments.
- SOURCING_LNUM = 0; // line number unknown
- for (i = 0; i < count; ++i)
+ int r = compile_expr0(&arg, cctx);
+ if (r == FAIL)
+ return FAIL;
+
+ // If no type specified use the type of the default value.
+ // Otherwise check that the default value type matches the
+ // specified type.
+ val_type = get_type_on_stack(cctx, 0);
+ where.wt_index = arg_idx + 1;
+ where.wt_kind = WT_ARGUMENT;
+ if (ufunc->uf_arg_types[arg_idx] == &t_unknown)
{
- char_u *arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
- if (STRCMP(arg, "v:none") == 0)
- // "arg = v:none" means the argument is optional without
- // setting a value when the argument is missing.
- continue;
+ did_set_arg_type = TRUE;
+ ufunc->uf_arg_types[arg_idx] = val_type;
+ }
+ else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx],
+ FALSE, -1, where, cctx, FALSE, FALSE) == FAIL)
+ return FAIL;
- type_T *val_type;
- int arg_idx = first_def_arg + i;
- where_T where = WHERE_INIT;
- int jump_instr_idx = instr->ga_len;
- isn_T *isn;
-
- // Use a JUMP_IF_ARG_SET instruction to skip if the value was given.
- if (generate_JUMP_IF_ARG(&cctx, ISN_JUMP_IF_ARG_SET,
- i - count - off) == FAIL)
- goto erret;
-
- // Make sure later arguments are not found.
- ufunc->uf_args_visible = arg_idx;
-
- int r = compile_expr0(&arg, &cctx);
- if (r == FAIL)
- goto erret;
-
- // If no type specified use the type of the default value.
- // Otherwise check that the default value type matches the
- // specified type.
- val_type = get_type_on_stack(&cctx, 0);
- where.wt_index = arg_idx + 1;
- where.wt_kind = WT_ARGUMENT;
- if (ufunc->uf_arg_types[arg_idx] == &t_unknown)
- {
- did_set_arg_type = TRUE;
- ufunc->uf_arg_types[arg_idx] = val_type;
- }
- else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx],
- FALSE, -1, where, &cctx, FALSE, FALSE) == FAIL)
- goto erret;
+ if (generate_STORE(cctx, ISN_STORE, i - count - off, NULL) == FAIL)
+ return FAIL;
- if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL)
- goto erret;
+ // set instruction index in JUMP_IF_ARG_SET to here
+ isn = ((isn_T *)instr->ga_data) + jump_instr_idx;
+ isn->isn_arg.jumparg.jump_where = instr->ga_len;
+ }
- // set instruction index in JUMP_IF_ARG_SET to here
- isn = ((isn_T *)instr->ga_data) + jump_instr_idx;
- isn->isn_arg.jumparg.jump_where = instr->ga_len;
- }
+ if (did_set_arg_type)
+ set_function_type(ufunc);
- if (did_set_arg_type)
- set_function_type(ufunc);
- }
- ufunc->uf_args_visible = ufunc->uf_args.ga_len;
+ return OK;
+}
- // Compiling a function in an interface is done to get the function type.
- // No code is actually compiled.
- if (ufunc->uf_class != NULL
- && (ufunc->uf_class->class_flags & CLASS_INTERFACE))
- {
- ufunc->uf_def_status = UF_NOT_COMPILED;
- ret = OK;
- goto erret;
- }
+/*
+ * Compile def function body. Loop over all the lines in the function and
+ * generate instructions.
+ */
+ static int
+compile_def_function_body(
+ cctx_T *cctx,
+ int last_func_lnum,
+ int check_return_type,
+ garray_T *lines_to_free,
+ char **errormsg)
+{
+ char_u *line = NULL;
+ char_u *p;
+ int did_emsg_before = did_emsg;
+#ifdef FEAT_PROFILE
+ int prof_lnum = -1;
+#endif
+ int debug_lnum = -1;
- /*
- * Loop over all the lines of the function and generate instructions.
- */
for (;;)
{
exarg_T ea;
@@ -3502,29 +3463,29 @@ compile_def_function(
// Bail out on the first error to avoid a flood of errors and report
// the right line number when inside try/catch.
if (did_emsg_before != did_emsg)
- goto erret;
+ return FAIL;
if (line != NULL && *line == '|')
// the line continues after a '|'
++line;
else if (line != NULL && *skipwhite(line) != NUL
- && !(*line == '#' && (line == cctx.ctx_line_start
+ && !(*line == '#' && (line == cctx->ctx_line_start
|| VIM_ISWHITE(line[-1]))))
{
semsg(_(e_trailing_characters_str), line);
- goto erret;
+ return FAIL;
}
else if (line != NULL && vim9_bad_comment(skipwhite(line)))
- goto erret;
+ return FAIL;
else
{
- line = next_line_from_context(&cctx, FALSE);
- if (cctx.ctx_lnum >= ufunc->uf_lines.ga_len)
+ line = next_line_from_context(cctx, FALSE);
+ if (cctx->ctx_lnum >= last_func_lnum)
{
// beyond the last line
#ifdef FEAT_PROFILE
- if (cctx.ctx_skip != SKIP_YES)
- may_generate_prof_end(&cctx, prof_lnum);
+ if (cctx->ctx_skip != SKIP_YES)
+ may_generate_prof_end(cctx, prof_lnum);
#endif
break;
}
@@ -3533,42 +3494,42 @@ compile_def_function(
if (line != NULL)
{
line = vim_strsave(line);
- if (ga_add_string(&lines_to_free, line) == FAIL)
- goto erret;
+ if (ga_add_string(lines_to_free, line) == FAIL)
+ return FAIL;
}
}
CLEAR_FIELD(ea);
ea.cmdlinep = &line;
ea.cmd = skipwhite(line);
- ea.skip = cctx.ctx_skip == SKIP_YES;
+ ea.skip = cctx->ctx_skip == SKIP_YES;
if (*ea.cmd == '#')
{
// "#" starts a comment, but "#{" is an error
if (vim9_bad_comment(ea.cmd))
- goto erret;
+ return FAIL;
line = (char_u *)"";
continue;
}
#ifdef FEAT_PROFILE
- if (cctx.ctx_compile_type == CT_PROFILE && cctx.ctx_lnum != prof_lnum
- && cctx.ctx_skip != SKIP_YES)
+ if (cctx->ctx_compile_type == CT_PROFILE && cctx->ctx_lnum != prof_lnum
+ && cctx->ctx_skip != SKIP_YES)
{
- may_generate_prof_end(&cctx, prof_lnum);
+ may_generate_prof_end(cctx, prof_lnum);
- prof_lnum = cctx.ctx_lnum;
- generate_instr(&cctx, ISN_PROF_START);
+ prof_lnum = cctx->ctx_lnum;
+ generate_instr(cctx, ISN_PROF_START);
}
#endif
- if (cctx.ctx_compile_type == CT_DEBUG && cctx.ctx_lnum != debug_lnum
- && cctx.ctx_skip != SKIP_YES)
+ if (cctx->ctx_compile_type == CT_DEBUG && cctx->ctx_lnum != debug_lnum
+ && cctx->ctx_skip != SKIP_YES)
{
- debug_lnum = cctx.ctx_lnum;
- generate_instr_debug(&cctx);
+ debug_lnum = cctx->ctx_lnum;
+ generate_instr_debug(cctx);
}
- cctx.ctx_prev_lnum = cctx.ctx_lnum + 1;
+ cctx->ctx_prev_lnum = cctx->ctx_lnum + 1;
// Some things can be recognized by the first character.
switch (*ea.cmd)
@@ -3576,18 +3537,18 @@ compile_def_function(
case '}':
{
// "}" ends a block scope
- scopetype_T stype = cctx.ctx_scope == NULL
- ? NO_SCOPE : cctx.ctx_scope->se_type;
+ scopetype_T stype = cctx->ctx_scope == NULL
+ ? NO_SCOPE : cctx->ctx_scope->se_type;
if (stype == BLOCK_SCOPE)
{
- compile_endblock(&cctx);
+ compile_endblock(cctx);
line = ea.cmd;
}
else
{
emsg(_(e_using_rcurly_outside_if_block_scope));
- goto erret;
+ return FAIL;
}
if (line != NULL)
line = skipwhite(ea.cmd + 1);
@@ -3599,7 +3560,7 @@ compile_def_function(
// "{'a': 1}->func() is something else
if (ends_excmd(*skipwhite(ea.cmd + 1)))
{
- line = compile_block(ea.cmd, &cctx);
+ line = compile_block(ea.cmd, cctx);
continue;
}
break;
@@ -3608,11 +3569,11 @@ compile_def_function(
/*
* COMMAND MODIFIERS
*/
- cctx.ctx_has_cmdmod = FALSE;
- if (parse_command_modifiers(&ea, &errormsg, &local_cmdmod, FALSE)
+ cctx->ctx_has_cmdmod = FALSE;
+ if (parse_command_modifiers(&ea, errormsg, &local_cmdmod, FALSE)
== FAIL)
- goto erret;
- generate_cmdmods(&cctx, &local_cmdmod);
+ return FAIL;
+ generate_cmdmods(cctx, &local_cmdmod);
undo_cmdmod(&local_cmdmod);
// Check if there was a colon after the last command modifier or before
@@ -3643,11 +3604,11 @@ compile_def_function(
int assign;
// Check for assignment after command modifiers.
- assign = may_compile_assignment(&ea, &line, &cctx);
+ assign = may_compile_assignment(&ea, &line, cctx);
if (assign == OK)
goto nextline;
if (assign == FAIL)
- goto erret;
+ return FAIL;
}
}
@@ -3675,13 +3636,13 @@ compile_def_function(
&& !(local_cmdmod.cmod_flags & CMOD_LEGACY))
{
semsg(_(e_colon_required_before_range_str), cmd);
- goto erret;
+ return FAIL;
}
ea.addr_count = 1;
if (ends_excmd2(line, ea.cmd))
{
// A range without a command: jump to the line.
- generate_EXEC(&cctx, ISN_EXECRANGE,
+ generate_EXEC(cctx, ISN_EXECRANGE,
vim_strnsave(cmd, ea.cmd - cmd));
line = ea.cmd;
goto nextline;
@@ -3690,13 +3651,13 @@ compile_def_function(
}
p = find_ex_command(&ea, NULL,
starts_with_colon || (local_cmdmod.cmod_flags & CMOD_LEGACY)
- ? NULL : item_exists, &cctx);
+ ? NULL : item_exists, cctx);
if (p == NULL)
{
- if (cctx.ctx_skip != SKIP_YES)
+ if (cctx->ctx_skip != SKIP_YES)
semsg(_(e_ambiguous_use_of_user_defined_command_str), ea.cmd);
- goto erret;
+ return FAIL;
}
// When using ":legacy cmd" always use compile_exec().
@@ -3721,7 +3682,7 @@ compile_def_function(
case CMD_finally:
case CMD_endtry:
semsg(_(e_cannot_use_legacy_with_command_str), ea.cmd);
- goto erret;
+ return FAIL;
default: break;
}
@@ -3738,7 +3699,7 @@ compile_def_function(
// "p" is equal to "ea.cmd" for a valid command.
if (ea.cmdidx == CMD_eval || ea.cmdidx == CMD_var)
;
- else if (cctx.ctx_skip == SKIP_YES)
+ else if (cctx->ctx_skip == SKIP_YES)
{
line += STRLEN(line);
goto nextline;
@@ -3746,11 +3707,11 @@ compile_def_function(
else
{
semsg(_(e_command_not_recognized_str), ea.cmd);
- goto erret;
+ return FAIL;
}
}
- if ((cctx.ctx_had_return || cctx.ctx_had_throw)
+ if ((cctx->ctx_had_return || cctx->ctx_had_throw)
&& ea.cmdidx != CMD_elseif
&& ea.cmdidx != CMD_else
&& ea.cmdidx != CMD_endif
@@ -3762,10 +3723,10 @@ compile_def_function(
&& !ignore_unreachable_code_for_testing)
{
semsg(_(e_unreachable_code_after_str),
- cctx.ctx_had_return ? "return" : "throw");
- goto erret;
+ cctx->ctx_had_return ? "return" : "throw");
+ return FAIL;
}
- cctx.ctx_had_throw = FALSE;
+ cctx->ctx_had_throw = FALSE;
p = skipwhite(p);
if (ea.cmdidx != CMD_SIZE
@@ -3781,7 +3742,7 @@ compile_def_function(
if ((ea.argt & EX_RANGE) == 0 && ea.addr_count > 0)
{
emsg(_(e_no_range_allowed));
- goto erret;
+ return FAIL;
}
}
@@ -3790,13 +3751,13 @@ compile_def_function(
case CMD_def:
case CMD_function:
ea.arg = p;
- line = compile_nested_function(&ea, &cctx, &lines_to_free);
+ line = compile_nested_function(&ea, cctx, lines_to_free);
break;
case CMD_return:
line = compile_return(p, check_return_type,
- local_cmdmod.cmod_flags & CMOD_LEGACY, &cctx);
- cctx.ctx_had_return = TRUE;
+ local_cmdmod.cmod_flags & CMOD_LEGACY, cctx);
+ cctx->ctx_had_return = TRUE;
break;
case CMD_let:
@@ -3807,7 +3768,7 @@ compile_def_function(
case CMD_const:
case CMD_increment:
case CMD_decrement:
- line = compile_assignment(p, &ea, ea.cmdidx, &cctx);
+ line = compile_assignment(p, &ea, ea.cmdidx, cctx);
if (line == p)
{
emsg(_(e_invalid_assignment));
@@ -3818,7 +3779,7 @@ compile_def_function(
case CMD_unlet:
case CMD_unlockvar:
case CMD_lockvar:
- line = compile_unletlock(p, &ea, &cctx);
+ line = compile_unletlock(p, &ea, cctx);
break;
case CMD_import:
@@ -3827,67 +3788,67 @@ compile_def_function(
break;
case CMD_if:
- line = compile_if(p, &cctx);
+ line = compile_if(p, cctx);
break;
case CMD_elseif:
- line = compile_elseif(p, &cctx);
- cctx.ctx_had_return = FALSE;
+ line = compile_elseif(p, cctx);
+ cctx->ctx_had_return = FALSE;
break;
case CMD_else:
- line = compile_else(p, &cctx);
- cctx.ctx_had_return = FALSE;
+ line = compile_else(p, cctx);
+ cctx->ctx_had_return = FALSE;
break;
case CMD_endif:
- line = compile_endif(p, &cctx);
+ line = compile_endif(p, cctx);
break;
case CMD_while:
- line = compile_while(p, &cctx);
+ line = compile_while(p, cctx);
break;
case CMD_endwhile:
- line = compile_endwhile(p, &cctx);
- cctx.ctx_had_return = FALSE;
+ line = compile_endwhile(p, cctx);
+ cctx->ctx_had_return = FALSE;
break;
case CMD_for:
- line = compile_for(p, &cctx);
+ line = compile_for(p, cctx);
break;
case CMD_endfor:
- line = compile_endfor(p, &cctx);
- cctx.ctx_had_return = FALSE;
+ line = compile_endfor(p, cctx);
+ cctx->ctx_had_return = FALSE;
break;
case CMD_continue:
- line = compile_continue(p, &cctx);
+ line = compile_continue(p, cctx);
break;
case CMD_break:
- line = compile_break(p, &cctx);
+ line = compile_break(p, cctx);
break;
case CMD_try:
- line = compile_try(p, &cctx);
+ line = compile_try(p, cctx);
break;
case CMD_catch:
- line = compile_catch(p, &cctx);
- cctx.ctx_had_return = FALSE;
+ line = compile_catch(p, cctx);
+ cctx->ctx_had_return = FALSE;
break;
case CMD_finally:
- line = compile_finally(p, &cctx);
- cctx.ctx_had_return = FALSE;
+ line = compile_finally(p, cctx);
+ cctx->ctx_had_return = FALSE;
break;
case CMD_endtry:
- line = compile_endtry(p, &cctx);
+ line = compile_endtry(p, cctx);
break;
case CMD_throw:
- line = compile_throw(p, &cctx);
- cctx.ctx_had_throw = TRUE;
+ line = compile_throw(p, cctx);
+ cctx->ctx_had_throw = TRUE;
break;
case CMD_eval:
- line = compile_eval(p, &cctx);
+ line = compile_eval(p, cctx);
break;
case CMD_defer:
- line = compile_defer(p, &cctx);
+ line = compile_defer(p, cctx);
break;
#ifdef HAS_MESSAGE_WINDOW
@@ -3898,7 +3859,7 @@ compile_def_function(
line = NULL;
else
line = compile_mult_expr(p, ea.cmdidx,
- cmd_count, &cctx);
+ cmd_count, cctx);
}
break;
#endif
@@ -3908,29 +3869,29 @@ compile_def_function(
case CMD_echoerr:
case CMD_echomsg:
case CMD_execute:
- line = compile_mult_expr(p, ea.cmdidx, 0, &cctx);
+ line = compile_mult_expr(p, ea.cmdidx, 0, cctx);
break;
case CMD_put:
ea.cmd = cmd;
- line = compile_put(p, &ea, &cctx);
+ line = compile_put(p, &ea, cctx);
break;
case CMD_substitute:
if (check_global_and_subst(ea.cmd, p) == FAIL)
- goto erret;
- if (cctx.ctx_skip == SKIP_YES)
+ return FAIL;
+ if (cctx->ctx_skip == SKIP_YES)
line = (char_u *)"";
else
{
ea.arg = p;
- line = compile_substitute(line, &ea, &cctx);
+ line = compile_substitute(line, &ea, cctx);
}
break;
case CMD_redir:
ea.arg = p;
- line = compile_redir(line, &ea, &cctx);
+ line = compile_redir(line, &ea, cctx);
break;
case CMD_cexpr:
@@ -3941,7 +3902,7 @@ compile_def_function(
case CMD_lgetexpr:
#ifdef FEAT_QUICKFIX
ea.arg = p;
- line = compile_cexpr(line, &ea, &cctx);
+ line = compile_cexpr(line, &ea, cctx);
#else
ex_ni(&ea);
line = NULL;
@@ -3955,13 +3916,13 @@ compile_def_function(
case CMD_t:
case CMD_xit:
not_in_vim9(&ea);
- goto erret;
+ return FAIL;
case CMD_SIZE:
- if (cctx.ctx_skip != SKIP_YES)
+ if (cctx->ctx_skip != SKIP_YES)
{
semsg(_(e_invalid_command_str), ea.cmd);
- goto erret;
+ return FAIL;
}
// We don't check for a next command here.
line = (char_u *)"";
@@ -3978,52 +3939,189 @@ compile_def_function(
case CMD_tcl:
ea.arg = p;
if (vim_strchr(line, '\n') == NULL)
- line = compile_exec(line, &ea, &cctx);
+ line = compile_exec(line, &ea, cctx);
else
// heredoc lines have been concatenated with NL
// characters in get_function_body()
- line = compile_script(line, &cctx);
+ line = compile_script(line, cctx);
break;
case CMD_vim9script:
- if (cctx.ctx_skip != SKIP_YES)
+ if (cctx->ctx_skip != SKIP_YES)
{
emsg(_(e_vim9script_can_only_be_used_in_script));
- goto erret;
+ return FAIL;
}
line = (char_u *)"";
break;
+ case CMD_class:
+ emsg(_(e_class_can_only_be_used_in_script));
+ return FAIL;
+
case CMD_type:
emsg(_(e_type_can_only_be_used_in_script));
- goto erret;
- break;
+ return FAIL;
case CMD_global:
if (check_global_and_subst(ea.cmd, p) == FAIL)
- goto erret;
+ return FAIL;
// FALLTHROUGH
default:
// Not recognized, execute with do_cmdline_cmd().
ea.arg = p;
- line = compile_exec(line, &ea, &cctx);
+ line = compile_exec(line, &ea, cctx);
break;
}
nextline:
if (line == NULL)
- goto erret;
+ return FAIL;
line = skipwhite(line);
// Undo any command modifiers.
- generate_undo_cmdmods(&cctx);
+ generate_undo_cmdmods(cctx);
- if (cctx.ctx_type_stack.ga_len < 0)
+ if (cctx->ctx_type_stack.ga_len < 0)
{
iemsg("Type stack underflow");
- goto erret;
+ return FAIL;
}
} // END of the loop over all the function body lines.
+ return OK;
+}
+
+/*
+ * After ex_function() has collected all the function lines: parse and compile
+ * the lines into instructions.
+ * Adds the function to "def_functions".
+ * When "check_return_type" is set then set ufunc->uf_ret_type to the type of
+ * the return statement (used for lambda). When uf_ret_type is already set
+ * then check that it matches.
+ * When "profiling" is true add ISN_PROF_START instructions.
+ * "outer_cctx" is set for a nested function.
+ * This can be used recursively through compile_lambda(), which may reallocate
+ * "def_functions".
+ * Returns OK or FAIL.
+ */
+ int
+compile_def_function(
+ ufunc_T *ufunc,
+ int check_return_type,
+ compiletype_T compile_type,
+ cctx_T *outer_cctx)
+{
+ garray_T lines_to_free;
+ char *errormsg = NULL; // error message
+ cctx_T cctx;
+ garray_T *instr;
+ int did_emsg_before = did_emsg;
+ int did_emsg_silent_before = did_emsg_silent;
+ int ret = FAIL;
+ sctx_T save_current_sctx = current_sctx;
+ int save_estack_compiling = estack_compiling;
+ int save_cmod_flags = cmdmod.cmod_flags;
+ int do_estack_push;
+ int new_def_function = FALSE;
+
+ // allocated lines are freed at the end
+ ga_init2(&lines_to_free, sizeof(char_u *), 50);
+
+ // When using a function that was compiled before: Free old instructions.
+ // The index is reused. Otherwise add a new entry in "def_functions".
+ if (ufunc->uf_dfunc_idx > 0)
+ {
+ dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
+ + ufunc->uf_dfunc_idx;
+ isn_T *instr_dest = NULL;
+
+ switch (compile_type)
+ {
+ case CT_PROFILE:
+#ifdef FEAT_PROFILE
+ instr_dest = dfunc->df_instr_prof; break;
+#endif
+ case CT_NONE: instr_dest = dfunc->df_instr; break;
+ case CT_DEBUG: instr_dest = dfunc->df_instr_debug; break;
+ }
+ if (instr_dest != NULL)
+ // Was compiled in this mode before: Free old instructions.
+ delete_def_function_contents(dfunc, FALSE);
+ ga_clear_strings(&dfunc->df_var_names);
+ dfunc->df_defer_var_idx = 0;
+ }
+ else
+ {
+ if (add_def_function(ufunc) == FAIL)
+ return FAIL;
+ new_def_function = TRUE;
+ }
+
+ if ((ufunc->uf_flags & FC_CLOSURE) && outer_cctx == NULL)
+ {
+ semsg(_(e_compiling_closure_without_context_str),
+ printable_func_name(ufunc));
+ return FAIL;
+ }
+
+ ufunc->uf_def_status = UF_COMPILING;
+
+ CLEAR_FIELD(cctx);
+
+ cctx.ctx_compile_type = compile_type;
+ cctx.ctx_ufunc = ufunc;
+ cctx.ctx_lnum = -1;
+ cctx.ctx_outer = outer_cctx;
+ ga_init2(&cctx.ctx_locals, sizeof(lvar_T), 10);
+ // Each entry on the type stack consists of two type pointers.
+ ga_init2(&cctx.ctx_type_stack, sizeof(type2_T), 50);
+ cctx.ctx_type_list = &ufunc->uf_type_list;
+ ga_init2(&cctx.ctx_instr, sizeof(isn_T), 50);
+ instr = &cctx.ctx_instr;
+
+ // Set the context to the function, it may be compiled when called from
+ // another script. Set the script version to the most modern one.
+ // The line number will be set in next_line_from_context().
+ current_sctx = ufunc->uf_script_ctx;
+ current_sctx.sc_version = SCRIPT_VERSION_VIM9;
+
+ // Don't use the flag from ":legacy" here.
+ cmdmod.cmod_flags &= ~CMOD_LEGACY;
+
+ // Make sure error messages are OK.
+ do_estack_push = !estack_top_is_ufunc(ufunc, 1);
+ if (do_estack_push)
+ estack_push_ufunc(ufunc, 1);
+ estack_compiling = TRUE;
+
+ if (check_args_shadowing(ufunc, &cctx) == FAIL)
+ goto erret;
+
+ // For an object method and a constructor generate instructions to
+ // initialize "this" and the object variables.
+ if (ufunc->uf_flags & (FC_OBJECT|FC_NEW))
+ if (obj_method_prologue(ufunc, &cctx) == FAIL)
+ goto erret;
+
+ if (ufunc->uf_def_args.ga_len > 0)
+ if (compile_def_function_default_args(ufunc, &cctx, instr) == FAIL)
+ goto erret;
+ ufunc->uf_args_visible = ufunc->uf_args.ga_len;
+
+ // Compiling a function in an interface is done to get the function type.
+ // No code is actually compiled.
+ if (ufunc->uf_class != NULL && IS_INTERFACE(ufunc->uf_class))
+ {
+ ufunc->uf_def_status = UF_NOT_COMPILED;
+ ret = OK;
+ goto erret;
+ }
+
+ // compile the function body
+ if (compile_def_function_body(&cctx, ufunc->uf_lines.ga_len,
+ check_return_type, &lines_to_free, &errormsg) == FAIL)
+ goto erret;
+
if (cctx.ctx_scope != NULL)
{
if (cctx.ctx_scope->se_type == IF_SCOPE)
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 1efed35..3a3960a 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -260,7 +260,10 @@ exe_newdict(int count, ectx_T *ectx)
if (count > 0)
ectx->ec_stack.ga_len -= 2 * count - 1;
else if (GA_GROW_FAILS(&ectx->ec_stack, 1))
+ {
+ dict_unref(dict);
return FAIL;
+ }
else
++ectx->ec_stack.ga_len;
tv = STACK_TV_BOT(-1);
@@ -1635,7 +1638,7 @@ store_var(char_u *name, typval_T *tv)
* Return FAIL if not allowed.
*/
static int
-do_2string(typval_T *tv, int is_2string_any, int tolerant)
+do_2string(typval_T *tv, int is_2string_any, int tostring_flags)
{
if (tv->v_type == VAR_STRING)
return OK;
@@ -1650,10 +1653,11 @@ do_2string(typval_T *tv, int is_2string_any, int tolerant)
case VAR_BOOL:
case VAR_NUMBER:
case VAR_FLOAT:
+ case VAR_DICT:
case VAR_BLOB: break;
case VAR_LIST:
- if (tolerant)
+ if (tostring_flags & TOSTRING_TOLERANT)
{
char_u *s, *e, *p;
garray_T ga;
@@ -1686,6 +1690,8 @@ do_2string(typval_T *tv, int is_2string_any, int tolerant)
tv->vval.v_string = ga.ga_data;
return OK;
}
+ if (tostring_flags & TOSTRING_INTERPOLATE)
+ break;
// FALLTHROUGH
default: to_string_error(tv->v_type);
return FAIL;
@@ -3255,6 +3261,12 @@ exec_instructions(ectx_T *ectx)
++tv->vval.v_object->obj_class->class_refcount;
tv->vval.v_object->obj_refcount = 1;
object_created(tv->vval.v_object);
+
+ // When creating an enum value object, initialize the name and
+ // ordinal object variables.
+ class_T *en = tv->vval.v_object->obj_class;
+ if (IS_ENUM(en))
+ enum_set_internal_obj_vars(en, tv->vval.v_object);
break;
// execute Ex command line
@@ -3830,11 +3842,19 @@ exec_instructions(ectx_T *ectx)
case ISN_STOREEXPORT:
{
int sid = iptr->isn_arg.loadstore.ls_sid;
- hashtab_T *ht = &SCRIPT_VARS(sid);
char_u *name = iptr->isn_arg.loadstore.ls_name;
- dictitem_T *di = find_var_in_ht(ht, 0,
- iptr->isn_type == ISN_STORES
+ dictitem_T *di = NULL;
+ // First check for a variable from an exported autoload
+ // with an autoload_prefix; it would be in globals.
+ if (iptr->isn_type == ISN_STOREEXPORT)
+ di = find_var_autoload_prefix(name, sid, NULL, NULL);
+ // Then look for a variable in the script's variables.
+ if (di == NULL)
+ {
+ hashtab_T *ht = &SCRIPT_VARS(sid);
+ di = find_var_in_ht(ht, 0, STRNCMP("s:", name, 2) == 0
? name + 2 : name, TRUE);
+ }
--ectx->ec_stack.ga_len;
SOURCING_LNUM = iptr->isn_lnum;
@@ -4564,6 +4584,7 @@ exec_instructions(ectx_T *ectx)
{
SOURCING_LNUM = iptr->isn_lnum;
iemsg("ufunc unexpectedly NULL for FUNCREF");
+ vim_free(pt);
goto theend;
}
if (fill_partial_and_closure(pt, ufunc,
@@ -5674,7 +5695,7 @@ exec_instructions(ectx_T *ectx)
SOURCING_LNUM = iptr->isn_lnum;
if (do_2string(STACK_TV_BOT(iptr->isn_arg.tostring.offset),
iptr->isn_type == ISN_2STRING_ANY,
- iptr->isn_arg.tostring.tolerant) == FAIL)
+ iptr->isn_arg.tostring.flags) == FAIL)
goto on_error;
break;
diff --git a/src/vim9expr.c b/src/vim9expr.c
index 9d67aea..8c412b8 100644
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -142,7 +142,7 @@ compile_member(int is_slice, int *keeping_dict, cctx_T *cctx)
typep->type_curr = &t_any;
typep->type_decl = &t_any;
}
- if (may_generate_2STRING(-1, FALSE, cctx) == FAIL
+ if (may_generate_2STRING(-1, TOSTRING_NONE, cctx) == FAIL
|| generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL)
return FAIL;
if (keeping_dict != NULL)
@@ -446,7 +446,7 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
if (m_idx >= 0)
{
ufunc_T *fp = cl->class_obj_methods[m_idx];
- // Private methods are not accessible outside the class
+ // Private object methods are not accessible outside the class
if (*name == '_' && !inside_class(cctx, cl))
{
semsg(_(e_cannot_access_protected_method_str), fp->uf_name);
@@ -488,7 +488,7 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
if (m_idx >= 0)
{
ufunc_T *fp = cl->class_class_functions[m_idx];
- // Private methods are not accessible outside the class
+ // Private class methods are not accessible outside the class
if (*name == '_' && !inside_class(cctx, cl))
{
semsg(_(e_cannot_access_protected_method_str), fp->uf_name);
@@ -546,6 +546,9 @@ compile_load_scriptvar(
int done = FALSE;
int res = OK;
+ check_script_symlink(import->imp_sid);
+ import_check_sourced_sid(&import->imp_sid);
+
// Need to lookup the member.
if (*p != '.')
{
@@ -1561,7 +1564,10 @@ compile_dict(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
if (d == NULL)
return FAIL;
if (generate_ppconst(cctx, ppconst) == FAIL)
+ {
+ dict_unref(d);
return FAIL;
+ }
for (;;)
{
char_u *key = NULL;
@@ -1595,7 +1601,7 @@ compile_dict(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
}
if (isn->isn_type == ISN_PUSHS)
key = isn->isn_arg.string;
- else if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
+ else if (may_generate_2STRING(-1, TOSTRING_NONE, cctx) == FAIL)
return FAIL;
*arg = skipwhite(*arg);
if (**arg != ']')
@@ -2462,7 +2468,8 @@ compile_subscript(
return FAIL;
ppconst->pp_is_const = FALSE;
- if ((type = get_type_on_stack(cctx, 0)) != &t_unknown
+ type = get_type_on_stack(cctx, 0);
+ if (type != &t_unknown
&& (type->tt_type == VAR_CLASS
|| type->tt_type == VAR_OBJECT))
{
@@ -3010,8 +3017,8 @@ compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
ppconst->pp_is_const = FALSE;
if (*op == '.')
{
- if (may_generate_2STRING(-2, FALSE, cctx) == FAIL
- || may_generate_2STRING(-1, FALSE, cctx) == FAIL)
+ if (may_generate_2STRING(-2, TOSTRING_NONE, cctx) == FAIL
+ || may_generate_2STRING(-1, TOSTRING_NONE, cctx) == FAIL)
return FAIL;
if (generate_CONCAT(cctx, 2) == FAIL)
return FAIL;
diff --git a/src/vim9instr.c b/src/vim9instr.c
index a2179f3..ad8beb1 100644
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -191,10 +191,12 @@ generate_STORE_THIS(cctx_T *cctx, int idx)
/*
* If type at "offset" isn't already VAR_STRING then generate ISN_2STRING.
* But only for simple types.
- * When "tolerant" is TRUE convert most types to string, e.g. a List.
+ * When tostring_flags has TOSTRING_TOLERANT, convert a List to a series of
+ * strings. When tostring_flags has TOSTRING_INTERPOLATE, convert a List or a
+ * Dict to the corresponding textual representation.
*/
int
-may_generate_2STRING(int offset, int tolerant, cctx_T *cctx)
+may_generate_2STRING(int offset, int tostring_flags, cctx_T *cctx)
{
isn_T *isn;
isntype_T isntype = ISN_2STRING;
@@ -222,11 +224,14 @@ may_generate_2STRING(int offset, int tolerant, cctx_T *cctx)
// conversion possible when tolerant
case VAR_LIST:
- if (tolerant)
+ case VAR_DICT:
+ if (tostring_flags & TOSTRING_TOLERANT)
{
isntype = ISN_2STRING_ANY;
break;
}
+ if (tostring_flags & TOSTRING_INTERPOLATE)
+ break;
// FALLTHROUGH
// conversion not possible
@@ -234,7 +239,6 @@ may_generate_2STRING(int offset, int tolerant, cctx_T *cctx)
case VAR_BLOB:
case VAR_FUNC:
case VAR_PARTIAL:
- case VAR_DICT:
case VAR_JOB:
case VAR_CHANNEL:
case VAR_INSTR:
@@ -249,7 +253,7 @@ may_generate_2STRING(int offset, int tolerant, cctx_T *cctx)
if ((isn = generate_instr(cctx, isntype)) == NULL)
return FAIL;
isn->isn_arg.tostring.offset = offset;
- isn->isn_arg.tostring.tolerant = tolerant;
+ isn->isn_arg.tostring.flags = tostring_flags;
return OK;
}
@@ -2390,6 +2394,7 @@ generate_store_var(
case dest_vimvar:
return generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
case dest_script:
+ case dest_script_v9:
{
int scriptvar_idx = lhs->lhs_scriptvar_idx;
int scriptvar_sid = lhs->lhs_scriptvar_sid;
@@ -2397,10 +2402,14 @@ generate_store_var(
{
isntype_T isn_type = ISN_STORES;
+ // If "sn_import_autoload", generate ISN_STOREEXPORT (not
+ // ISN_STORES) if destination is in a vim9script or if
+ // there is no "sn_autoload_prefix".
if (SCRIPT_ID_VALID(scriptvar_sid)
&& SCRIPT_ITEM(scriptvar_sid)->sn_import_autoload
- && SCRIPT_ITEM(scriptvar_sid)->sn_autoload_prefix
- == NULL)
+ && ((SCRIPT_ITEM(scriptvar_sid)
+ ->sn_autoload_prefix == NULL)
+ || lhs->lhs_dest == dest_script_v9))
{
// "import autoload './dir/script.vim'" - load script
// first
diff --git a/src/vim9script.c b/src/vim9script.c
index a64ce72..3035889 100644
--- a/src/vim9script.c
+++ b/src/vim9script.c
@@ -456,15 +456,24 @@ handle_import(
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
char_u *tail = gettail(si->sn_name);
char_u *from_name;
+ int sourced_from_nofile_buf = FALSE;
- // Relative to current script: "./name.vim", "../../name.vim".
- len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2;
- from_name = alloc((int)len);
- if (from_name == NULL)
- goto erret;
- vim_strncpy(from_name, si->sn_name, tail - si->sn_name);
- add_pathsep(from_name);
- STRCAT(from_name, tv.vval.v_string);
+ if (STRNCMP(si->sn_name, ":source buffer=", 15) == 0)
+ sourced_from_nofile_buf = TRUE;
+
+ if (!sourced_from_nofile_buf)
+ {
+ // Relative to current script: "./name.vim", "../../name.vim".
+ len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2;
+ from_name = alloc((int)len);
+ if (from_name == NULL)
+ goto erret;
+ vim_strncpy(from_name, si->sn_name, tail - si->sn_name);
+ add_pathsep(from_name);
+ STRCAT(from_name, tv.vval.v_string);
+ }
+ else
+ from_name = vim_strsave(tv.vval.v_string);
simplify_filename(from_name);
res = handle_import_fname(from_name, is_autoload, &sid);
diff --git a/src/vim9type.c b/src/vim9type.c
index 0d004c8..775291e 100644
--- a/src/vim9type.c
+++ b/src/vim9type.c
@@ -209,6 +209,59 @@ set_tv_type_recurse(type_T *type)
}
/*
+ * Set the type of Dict "d" to "type"
+ */
+ static void
+set_tv_type_dict(dict_T *d, type_T *type)
+{
+ if (d->dv_type == type)
+ return;
+
+ free_type(d->dv_type);
+ d->dv_type = alloc_type(type);
+
+ // Need to recursively set the type of dict items?
+ if (!set_tv_type_recurse(type))
+ return;
+
+ int todo = (int)d->dv_hashtab.ht_used;
+ hashitem_T *hi;
+ dictitem_T *di;
+
+ FOR_ALL_HASHTAB_ITEMS(&d->dv_hashtab, hi, todo)
+ {
+ if (!HASHITEM_EMPTY(hi))
+ {
+ --todo;
+ di = HI2DI(hi);
+ set_tv_type(&di->di_tv, type->tt_member);
+ }
+ }
+}
+
+/*
+ * Set the type of List "l" to "type"
+ */
+ static void
+set_tv_type_list(list_T *l, type_T *type)
+{
+ if (l->lv_type == type)
+ return;
+
+ free_type(l->lv_type);
+ l->lv_type = alloc_type(type);
+
+ // Need to recursively set the type of list items?
+ if (l->lv_first == &range_list_item || !set_tv_type_recurse(type))
+ return;
+
+ listitem_T *li;
+
+ FOR_ALL_LIST_ITEMS(l, li)
+ set_tv_type(&li->li_tv, type->tt_member);
+}
+
+/*
* Set the type of "tv" to "type" if it is a list or dict.
*/
void
@@ -218,49 +271,11 @@ set_tv_type(typval_T *tv, type_T *type)
// If the variable type is "any", then keep the value type.
// e.g. var x: any = [1, 2] or var y: any = {v: 1}
return;
- if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL)
- {
- dict_T *d = tv->vval.v_dict;
-
- if (d->dv_type != type)
- {
- free_type(d->dv_type);
- d->dv_type = alloc_type(type);
- if (set_tv_type_recurse(type))
- {
- int todo = (int)d->dv_hashtab.ht_used;
- hashitem_T *hi;
- dictitem_T *di;
- FOR_ALL_HASHTAB_ITEMS(&d->dv_hashtab, hi, todo)
- {
- if (!HASHITEM_EMPTY(hi))
- {
- --todo;
- di = HI2DI(hi);
- set_tv_type(&di->di_tv, type->tt_member);
- }
- }
- }
- }
- }
+ if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL)
+ set_tv_type_dict(tv->vval.v_dict, type);
else if (tv->v_type == VAR_LIST && tv->vval.v_list != NULL)
- {
- list_T *l = tv->vval.v_list;
-
- if (l->lv_type != type)
- {
- free_type(l->lv_type);
- l->lv_type = alloc_type(type);
- if (l->lv_first != &range_list_item && set_tv_type_recurse(type))
- {
- listitem_T *li;
-
- FOR_ALL_LIST_ITEMS(l, li)
- set_tv_type(&li->li_tv, type->tt_member);
- }
- }
- }
+ set_tv_type_list(tv->vval.v_list, type);
}
type_T *
@@ -414,192 +429,238 @@ func_type_add_arg_types(
type_any_or_unknown(type_T *type)
{
return type == NULL || type->tt_type == VAR_ANY
- || type->tt_type == VAR_UNKNOWN;
+ || type->tt_type == VAR_UNKNOWN;
}
/*
- * Get a type_T for a typval_T.
- * "type_gap" is used to temporarily create types in.
- * When "flags" has TVTT_DO_MEMBER also get the member type, otherwise use
- * "any".
- * When "flags" has TVTT_MORE_SPECIFIC get the more specific member type if it
- * is "any".
+ * Get a type_T for a "special" typval in "tv".
*/
static type_T *
-typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int flags)
+special_typval2type(typval_T *tv)
{
- type_T *type;
- type_T *member_type = NULL;
- class_T *class_type = NULL;
- int argcount = 0;
- int min_argcount = 0;
-
- if (tv->v_type == VAR_NUMBER)
- return &t_number;
- if (tv->v_type == VAR_BOOL)
- return &t_bool;
- if (tv->v_type == VAR_SPECIAL)
+ switch (tv->vval.v_number)
{
- if (tv->vval.v_number == VVAL_NULL)
+ case VVAL_NULL:
return &t_null;
- if (tv->vval.v_number == VVAL_NONE)
+
+ case VVAL_NONE:
return &t_none;
- if (tv->vval.v_number == VVAL_TRUE
- || tv->vval.v_number == VVAL_FALSE)
+
+ case VVAL_TRUE:
+ case VVAL_FALSE:
return &t_bool;
- return &t_unknown;
+
+ default:
+ return &t_unknown;
}
- if (tv->v_type == VAR_STRING)
- return &t_string;
- if (tv->v_type == VAR_BLOB)
+}
+
+/*
+ * Get a type_T for a List typval in "tv".
+ * When "flags" has TVTT_DO_MEMBER also get the member type, otherwise use
+ * "any".
+ * When "flags" has TVTT_MORE_SPECIFIC get the more specific member type if it
+ * is "any".
+ */
+ static type_T *
+list_typval2type(typval_T *tv, int copyID, garray_T *type_gap, int flags)
+{
+ list_T *l = tv->vval.v_list;
+ listitem_T *li;
+ type_T *member_type = NULL;
+
+ // An empty list has type list<unknown>, unless the type was specified
+ // and is not list<any>. This matters when assigning to a variable
+ // with a specific list type.
+ if (l == NULL || (l->lv_first == NULL
+ && (l->lv_type == NULL || l->lv_type->tt_member == &t_any)))
+ return &t_list_empty;
+
+ if ((flags & TVTT_DO_MEMBER) == 0)
+ return &t_list_any;
+
+ // If the type is list<any> go through the members, it may end up a
+ // more specific type.
+ if (l->lv_type != NULL && (l->lv_first == NULL
+ || (flags & TVTT_MORE_SPECIFIC) == 0
+ || l->lv_type->tt_member != &t_any))
+ // make a copy, lv_type may be freed if the list is freed
+ return copy_type_deep(l->lv_type, type_gap);
+
+ if (l->lv_first == &range_list_item)
+ return &t_list_number;
+
+ if (l->lv_copyID == copyID)
+ // avoid recursion
+ return &t_list_any;
+
+ l->lv_copyID = copyID;
+
+ // Use the common type of all members.
+ member_type = typval2type(&l->lv_first->li_tv, copyID, type_gap,
+ TVTT_DO_MEMBER);
+ for (li = l->lv_first->li_next; li != NULL; li = li->li_next)
+ common_type(typval2type(&li->li_tv, copyID, type_gap, TVTT_DO_MEMBER),
+ member_type, &member_type, type_gap);
+
+ return get_list_type(member_type, type_gap);
+}
+
+/*
+ * Get a type_T for a Dict typval in "tv".
+ * When "flags" has TVTT_DO_MEMBER also get the member type, otherwise use
+ * "any".
+ * When "flags" has TVTT_MORE_SPECIFIC get the more specific member type if it
+ * is "any".
+ */
+ static type_T *
+dict_typval2type(typval_T *tv, int copyID, garray_T *type_gap, int flags)
+{
+ dict_iterator_T iter;
+ typval_T *value;
+ dict_T *d = tv->vval.v_dict;
+ type_T *member_type = NULL;
+
+ if (d == NULL || (d->dv_hashtab.ht_used == 0 && d->dv_type == NULL))
+ return &t_dict_empty;
+
+ if ((flags & TVTT_DO_MEMBER) == 0)
+ return &t_dict_any;
+
+ // If the type is dict<any> go through the members, it may end up a
+ // more specific type.
+ if (d->dv_type != NULL && (d->dv_hashtab.ht_used == 0
+ || (flags & TVTT_MORE_SPECIFIC) == 0
+ || d->dv_type->tt_member != &t_any))
+ return d->dv_type;
+
+ if (d->dv_copyID == copyID)
+ // avoid recursion
+ return &t_dict_any;
+
+ d->dv_copyID = copyID;
+
+ // Use the common type of all values.
+ dict_iterate_start(tv, &iter);
+ dict_iterate_next(&iter, &value);
+ member_type = typval2type(value, copyID, type_gap, TVTT_DO_MEMBER);
+
+ while (dict_iterate_next(&iter, &value) != NULL)
+ common_type(typval2type(value, copyID, type_gap, TVTT_DO_MEMBER),
+ member_type, &member_type, type_gap);
+
+ return get_dict_type(member_type, type_gap);
+}
+
+/*
+ * Get a type_T for a "partial" typval in "tv".
+ */
+ static type_T *
+partial_typval2type(typval_T *tv, ufunc_T *ufunc, garray_T *type_gap)
+{
+ partial_T *pt = tv->vval.v_partial;
+ type_T *type;
+
+ type = get_type_ptr(type_gap);
+ if (type == NULL)
+ return NULL;
+
+ *type = *ufunc->uf_func_type;
+ if (type->tt_argcount >= 0 && pt->pt_argc > 0)
{
- if (tv->vval.v_blob == NULL)
- return &t_blob_null;
- return &t_blob;
+ type->tt_argcount -= pt->pt_argc;
+ type->tt_min_argcount -= pt->pt_argc;
+ if (type->tt_argcount > 0 && func_type_add_arg_types(type,
+ type->tt_argcount, type_gap) == OK)
+ for (int i = 0; i < type->tt_argcount; ++i)
+ type->tt_args[i] =
+ ufunc->uf_func_type->tt_args[i + pt->pt_argc];
}
+ if (pt->pt_func != NULL)
+ type->tt_member = pt->pt_func->uf_ret_type;
+
+ return type;
+}
- if (tv->v_type == VAR_LIST)
+/*
+ * Get a type_T for a "class" or an "object" typval in "tv".
+ */
+ static type_T *
+oc_typval2type(typval_T *tv)
+{
+ if (tv->v_type == VAR_CLASS)
{
- list_T *l = tv->vval.v_list;
- listitem_T *li;
-
- // An empty list has type list<unknown>, unless the type was specified
- // and is not list<any>. This matters when assigning to a variable
- // with a specific list type.
- if (l == NULL || (l->lv_first == NULL
- && (l->lv_type == NULL || l->lv_type->tt_member == &t_any)))
- return &t_list_empty;
- if ((flags & TVTT_DO_MEMBER) == 0)
- return &t_list_any;
- // If the type is list<any> go through the members, it may end up a
- // more specific type.
- if (l->lv_type != NULL && (l->lv_first == NULL
- || (flags & TVTT_MORE_SPECIFIC) == 0
- || l->lv_type->tt_member != &t_any))
- // make a copy, lv_type may be freed if the list is freed
- return copy_type_deep(l->lv_type, type_gap);
- if (l->lv_first == &range_list_item)
- return &t_list_number;
- if (l->lv_copyID == copyID)
- // avoid recursion
- return &t_list_any;
- l->lv_copyID = copyID;
-
- // Use the common type of all members.
- member_type = typval2type(&l->lv_first->li_tv, copyID, type_gap,
- TVTT_DO_MEMBER);
- for (li = l->lv_first->li_next; li != NULL; li = li->li_next)
- common_type(typval2type(&li->li_tv, copyID, type_gap,
- TVTT_DO_MEMBER),
- member_type, &member_type, type_gap);
- return get_list_type(member_type, type_gap);
+ if (tv->vval.v_class == NULL)
+ return &t_class;
+
+ return &tv->vval.v_class->class_type;
}
- if (tv->v_type == VAR_DICT)
+ if (tv->vval.v_object != NULL)
+ return &tv->vval.v_object->obj_class->class_object_type;
+
+ return &t_object;
+}
+
+/*
+ * Get a type_T for a "function" or a "partial"
+ */
+ static type_T *
+fp_typval2type(typval_T *tv, garray_T *type_gap)
+{
+ char_u *name = NULL;
+ ufunc_T *ufunc = NULL;
+ type_T *type;
+ type_T *member_type = NULL;
+ int argcount = 0;
+ int min_argcount = 0;
+
+ if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL)
{
- dict_iterator_T iter;
- typval_T *value;
- dict_T *d = tv->vval.v_dict;
-
- if (d == NULL || (d->dv_hashtab.ht_used == 0 && d->dv_type == NULL))
- return &t_dict_empty;
- if ((flags & TVTT_DO_MEMBER) == 0)
- return &t_dict_any;
- // If the type is dict<any> go through the members, it may end up a
- // more specific type.
- if (d->dv_type != NULL && (d->dv_hashtab.ht_used == 0
- || (flags & TVTT_MORE_SPECIFIC) == 0
- || d->dv_type->tt_member != &t_any))
- return d->dv_type;
- if (d->dv_copyID == copyID)
- // avoid recursion
- return &t_dict_any;
- d->dv_copyID = copyID;
-
- // Use the common type of all values.
- dict_iterate_start(tv, &iter);
- dict_iterate_next(&iter, &value);
- member_type = typval2type(value, copyID, type_gap, TVTT_DO_MEMBER);
- while (dict_iterate_next(&iter, &value) != NULL)
- common_type(typval2type(value, copyID, type_gap, TVTT_DO_MEMBER),
- member_type, &member_type, type_gap);
- return get_dict_type(member_type, type_gap);
+ if (tv->vval.v_partial->pt_func != NULL)
+ ufunc = tv->vval.v_partial->pt_func;
+ else
+ name = tv->vval.v_partial->pt_name;
}
+ else
+ name = tv->vval.v_string;
- if (tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL)
+ if (name == NULL && ufunc == NULL)
+ return &t_func_unknown;
+
+ if (name != NULL)
{
- char_u *name = NULL;
- ufunc_T *ufunc = NULL;
+ int idx = find_internal_func(name);
- if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL)
+ if (idx >= 0)
{
- if (tv->vval.v_partial->pt_func != NULL)
- ufunc = tv->vval.v_partial->pt_func;
- else
- name = tv->vval.v_partial->pt_name;
- }
- else
- name = tv->vval.v_string;
- if (name == NULL && ufunc == NULL)
- return &t_func_unknown;
- if (name != NULL)
- {
- int idx = find_internal_func(name);
-
- if (idx >= 0)
- {
- type_T *decl_type; // unused
+ type_T *decl_type; // unused
- internal_func_get_argcount(idx, &argcount, &min_argcount);
- member_type = internal_func_ret_type(idx, 0, NULL, &decl_type,
- type_gap);
- }
- else
- ufunc = find_func(name, FALSE);
+ internal_func_get_argcount(idx, &argcount, &min_argcount);
+ member_type = internal_func_ret_type(idx, 0, NULL, &decl_type,
+ type_gap);
}
- if (ufunc != NULL)
+ else
+ ufunc = find_func(name, FALSE);
+ }
+ if (ufunc != NULL)
+ {
+ // May need to get the argument types from default values by
+ // compiling the function.
+ if (ufunc->uf_def_status == UF_TO_BE_COMPILED
+ && compile_def_function(ufunc, TRUE, CT_NONE, NULL)
+ == FAIL)
+ return NULL;
+ if (ufunc->uf_func_type == NULL)
+ set_function_type(ufunc);
+ if (ufunc->uf_func_type != NULL)
{
- // May need to get the argument types from default values by
- // compiling the function.
- if (ufunc->uf_def_status == UF_TO_BE_COMPILED
- && compile_def_function(ufunc, TRUE, CT_NONE, NULL)
- == FAIL)
- return NULL;
- if (ufunc->uf_func_type == NULL)
- set_function_type(ufunc);
- if (ufunc->uf_func_type != NULL)
- {
- if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL
- && tv->vval.v_partial->pt_argc > 0)
- {
- type = get_type_ptr(type_gap);
- if (type == NULL)
- return NULL;
- *type = *ufunc->uf_func_type;
- if (type->tt_argcount >= 0)
- {
- type->tt_argcount -= tv->vval.v_partial->pt_argc;
- type->tt_min_argcount -= tv->vval.v_partial->pt_argc;
- if (type->tt_argcount > 0
- && func_type_add_arg_types(type,
- type->tt_argcount, type_gap) == OK)
- for (int i = 0; i < type->tt_argcount; ++i)
- type->tt_args[i] =
- ufunc->uf_func_type->tt_args[
- i + tv->vval.v_partial->pt_argc];
- }
- return type;
- }
- return ufunc->uf_func_type;
- }
+ if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL)
+ return partial_typval2type(tv, ufunc, type_gap);
+ return ufunc->uf_func_type;
}
}
- if (tv->v_type == VAR_CLASS)
- class_type = tv->vval.v_class;
- else if (tv->v_type == VAR_OBJECT && tv->vval.v_object != NULL)
- class_type = tv->vval.v_object->obj_class;
-
type = get_type_ptr(type_gap);
if (type == NULL)
return NULL;
@@ -607,18 +668,90 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int flags)
type->tt_argcount = argcount;
type->tt_min_argcount = min_argcount;
if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL
- && tv->vval.v_partial->pt_argc > 0)
+ && tv->vval.v_partial->pt_argc > 0)
{
type->tt_argcount -= tv->vval.v_partial->pt_argc;
type->tt_min_argcount -= tv->vval.v_partial->pt_argc;
}
type->tt_member = member_type;
- type->tt_class = class_type;
return type;
}
/*
+ * Get a type_T for a typval_T.
+ * "type_gap" is used to temporarily create types in.
+ * When "flags" has TVTT_DO_MEMBER also get the member type, otherwise use
+ * "any".
+ * When "flags" has TVTT_MORE_SPECIFIC get the more specific member type if it
+ * is "any".
+ */
+ static type_T *
+typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int flags)
+{
+ switch (tv->v_type)
+ {
+ case VAR_UNKNOWN:
+ return &t_unknown;
+
+ case VAR_ANY:
+ return &t_any;
+
+ case VAR_VOID:
+ return &t_void;
+
+ case VAR_BOOL:
+ return &t_bool;
+
+ case VAR_SPECIAL:
+ return special_typval2type(tv);
+
+ case VAR_NUMBER:
+ return &t_number;
+
+ case VAR_FLOAT:
+ return &t_float;
+
+ case VAR_STRING:
+ return &t_string;
+
+ case VAR_BLOB:
+ if (tv->vval.v_blob == NULL)
+ return &t_blob_null;
+ return &t_blob;
+
+ case VAR_LIST:
+ return list_typval2type(tv, copyID, type_gap, flags);
+
+ case VAR_DICT:
+ return dict_typval2type(tv, copyID, type_gap, flags);
+
+ case VAR_JOB:
+ return &t_job;
+
+ case VAR_CHANNEL:
+ return &t_channel;
+
+ case VAR_CLASS:
+ case VAR_OBJECT:
+ return oc_typval2type(tv);
+
+ case VAR_TYPEALIAS:
+ return &t_typealias;
+
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ return fp_typval2type(tv, type_gap);
+
+ case VAR_INSTR:
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+/*
* Return TRUE if "tv" is not a bool but should be converted to bool.
*/
int
@@ -719,7 +852,7 @@ check_typval_type(type_T *expected, typval_T *actual_tv, where_T where)
if (expected == NULL)
return OK; // didn't expect anything.
- //
+
ga_init2(&type_list, sizeof(type_T *), 10);
// A null_function and null_partial are special cases, they can be used to
@@ -737,12 +870,14 @@ check_typval_type(type_T *expected, typval_T *actual_tv, where_T where)
{
res = check_type_maybe(expected, actual_type, TRUE, where);
if (res == MAYBE && !(actual_type->tt_type == VAR_FUNC
- && actual_type->tt_member == &t_unknown))
+ && (actual_type->tt_member == &t_unknown
+ || actual_type->tt_member == NULL)))
{
// If a type check is needed that means assigning "any" or
// "unknown" to a more specific type, which fails here.
// Except when it looks like a lambda, since they have an
- // incomplete type.
+ // incomplete type. A legacy lambda function has a NULL return
+ // type.
type_mismatch_where(expected, actual_type, where);
res = FAIL;
}
@@ -1149,6 +1284,194 @@ parse_type_member(
}
/*
+ * Parse a "func" type at "*arg" and advance over it.
+ * When "give_error" is TRUE give error messages, otherwise be quiet.
+ * Return NULL for failure.
+ */
+ static type_T *
+parse_type_func(char_u **arg, size_t len, garray_T *type_gap, int give_error)
+{
+ char_u *p;
+ type_T *type;
+ type_T *ret_type = &t_unknown;
+ int argcount = -1;
+ int flags = 0;
+ int first_optional = -1;
+ type_T *arg_type[MAX_FUNC_ARGS + 1];
+
+ // func({type}, ...{type}): {type}
+ *arg += len;
+ if (**arg == '(')
+ {
+ // "func" may or may not return a value, "func()" does
+ // not return a value.
+ ret_type = &t_void;
+
+ p = ++*arg;
+ argcount = 0;
+ while (*p != NUL && *p != ')')
+ {
+ if (*p == '?')
+ {
+ if (first_optional == -1)
+ first_optional = argcount;
+ ++p;
+ }
+ else if (STRNCMP(p, "...", 3) == 0)
+ {
+ flags |= TTFLAG_VARARGS;
+ p += 3;
+ }
+ else if (first_optional != -1)
+ {
+ if (give_error)
+ emsg(_(e_mandatory_argument_after_optional_argument));
+ return NULL;
+ }
+
+ type = parse_type(&p, type_gap, give_error);
+ if (type == NULL)
+ return NULL;
+ if ((flags & TTFLAG_VARARGS) != 0 && type->tt_type != VAR_LIST)
+ {
+ char *tofree;
+ semsg(_(e_variable_arguments_type_must_be_list_str),
+ type_name(type, &tofree));
+ vim_free(tofree);
+ return NULL;
+ }
+ arg_type[argcount++] = type;
+
+ // Nothing comes after "...{type}".
+ if (flags & TTFLAG_VARARGS)
+ break;
+
+ if (*p != ',' && *skipwhite(p) == ',')
+ {
+ if (give_error)
+ semsg(_(e_no_white_space_allowed_before_str_str),
+ ",", p);
+ return NULL;
+ }
+ if (*p == ',')
+ {
+ ++p;
+ if (!VIM_ISWHITE(*p))
+ {
+ if (give_error)
+ semsg(_(e_white_space_required_after_str_str),
+ ",", p - 1);
+ return NULL;
+ }
+ }
+ p = skipwhite(p);
+ if (argcount == MAX_FUNC_ARGS)
+ {
+ if (give_error)
+ emsg(_(e_too_many_argument_types));
+ return NULL;
+ }
+ }
+
+ p = skipwhite(p);
+ if (*p != ')')
+ {
+ if (give_error)
+ emsg(_(e_missing_closing_paren));
+ return NULL;
+ }
+ *arg = p + 1;
+ }
+ if (**arg == ':')
+ {
+ // parse return type
+ ++*arg;
+ if (!VIM_ISWHITE(**arg) && give_error)
+ semsg(_(e_white_space_required_after_str_str), ":", *arg - 1);
+ *arg = skipwhite(*arg);
+ ret_type = parse_type(arg, type_gap, give_error);
+ if (ret_type == NULL)
+ return NULL;
+ }
+ if (flags == 0 && first_optional == -1 && argcount <= 0)
+ type = get_func_type(ret_type, argcount, type_gap);
+ else
+ {
+ type = alloc_func_type(ret_type, argcount, type_gap);
+ type->tt_flags = flags;
+ if (argcount > 0)
+ {
+ type->tt_argcount = argcount;
+ type->tt_min_argcount = first_optional == -1
+ ? argcount : first_optional;
+ if (func_type_add_arg_types(type, argcount, type_gap) == FAIL)
+ return NULL;
+ mch_memmove(type->tt_args, arg_type, sizeof(type_T *) * argcount);
+ }
+ }
+
+ return type;
+}
+
+/*
+ * Parse a user defined type at "*arg" and advance over it.
+ * It can be a class or an interface or a typealias name, possibly imported.
+ * Return NULL if a type is not found.
+ */
+ static type_T *
+parse_type_user_defined(
+ char_u **arg,
+ size_t len,
+ garray_T *type_gap,
+ int give_error)
+{
+ int did_emsg_before = did_emsg;
+ typval_T tv;
+
+ tv.v_type = VAR_UNKNOWN;
+ if (eval_variable_import(*arg, &tv) == OK)
+ {
+ if (tv.v_type == VAR_CLASS && tv.vval.v_class != NULL)
+ {
+ type_T *type = get_type_ptr(type_gap);
+ if (type != NULL)
+ {
+ // Although the name is that of a class or interface, the type
+ // uses will be an object.
+ type->tt_type = VAR_OBJECT;
+ type->tt_class = tv.vval.v_class;
+ clear_tv(&tv);
+
+ *arg += len;
+ // Skip over ".ClassName".
+ while (ASCII_ISALNUM(**arg) || **arg == '_' || **arg == '.')
+ ++*arg;
+
+ return type;
+ }
+ }
+ else if (tv.v_type == VAR_TYPEALIAS)
+ {
+ // user defined type
+ type_T *type = copy_type(tv.vval.v_typealias->ta_type, type_gap);
+ *arg += len;
+ clear_tv(&tv);
+ // Skip over ".TypeName".
+ while (ASCII_ISALNUM(**arg) || **arg == '_' || **arg == '.')
+ ++*arg;
+ return type;
+ }
+
+ clear_tv(&tv);
+ }
+
+ if (give_error && (did_emsg == did_emsg_before))
+ semsg(_(e_type_not_recognized_str), *arg);
+
+ return NULL;
+}
+
+/*
* Parse a type at "arg" and advance over it.
* When "give_error" is TRUE give error messages, otherwise be quiet.
* Return NULL for failure.
@@ -1207,130 +1530,7 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
return &t_float;
}
if (len == 4 && STRNCMP(*arg, "func", len) == 0)
- {
- type_T *type;
- type_T *ret_type = &t_unknown;
- int argcount = -1;
- int flags = 0;
- int first_optional = -1;
- type_T *arg_type[MAX_FUNC_ARGS + 1];
-
- // func({type}, ...{type}): {type}
- *arg += len;
- if (**arg == '(')
- {
- // "func" may or may not return a value, "func()" does
- // not return a value.
- ret_type = &t_void;
-
- p = ++*arg;
- argcount = 0;
- while (*p != NUL && *p != ')')
- {
- if (*p == '?')
- {
- if (first_optional == -1)
- first_optional = argcount;
- ++p;
- }
- else if (STRNCMP(p, "...", 3) == 0)
- {
- flags |= TTFLAG_VARARGS;
- p += 3;
- }
- else if (first_optional != -1)
- {
- if (give_error)
- emsg(_(e_mandatory_argument_after_optional_argument));
- return NULL;
- }
-
- type = parse_type(&p, type_gap, give_error);
- if (type == NULL)
- return NULL;
- if ((flags & TTFLAG_VARARGS) != 0
- && type->tt_type != VAR_LIST)
- {
- char *tofree;
- semsg(_(e_variable_arguments_type_must_be_list_str),
- type_name(type, &tofree));
- vim_free(tofree);
- return NULL;
- }
- arg_type[argcount++] = type;
-
- // Nothing comes after "...{type}".
- if (flags & TTFLAG_VARARGS)
- break;
-
- if (*p != ',' && *skipwhite(p) == ',')
- {
- if (give_error)
- semsg(_(e_no_white_space_allowed_before_str_str),
- ",", p);
- return NULL;
- }
- if (*p == ',')
- {
- ++p;
- if (!VIM_ISWHITE(*p))
- {
- if (give_error)
- semsg(_(e_white_space_required_after_str_str),
- ",", p - 1);
- return NULL;
- }
- }
- p = skipwhite(p);
- if (argcount == MAX_FUNC_ARGS)
- {
- if (give_error)
- emsg(_(e_too_many_argument_types));
- return NULL;
- }
- }
-
- p = skipwhite(p);
- if (*p != ')')
- {
- if (give_error)
- emsg(_(e_missing_closing_paren));
- return NULL;
- }
- *arg = p + 1;
- }
- if (**arg == ':')
- {
- // parse return type
- ++*arg;
- if (!VIM_ISWHITE(**arg) && give_error)
- semsg(_(e_white_space_required_after_str_str),
- ":", *arg - 1);
- *arg = skipwhite(*arg);
- ret_type = parse_type(arg, type_gap, give_error);
- if (ret_type == NULL)
- return NULL;
- }
- if (flags == 0 && first_optional == -1 && argcount <= 0)
- type = get_func_type(ret_type, argcount, type_gap);
- else
- {
- type = alloc_func_type(ret_type, argcount, type_gap);
- type->tt_flags = flags;
- if (argcount > 0)
- {
- type->tt_argcount = argcount;
- type->tt_min_argcount = first_optional == -1
- ? argcount : first_optional;
- if (func_type_add_arg_types(type, argcount,
- type_gap) == FAIL)
- return NULL;
- mch_memmove(type->tt_args, arg_type,
- sizeof(type_T *) * argcount);
- }
- }
- return type;
- }
+ return parse_type_func(arg, len, type_gap, give_error);
break;
case 'j':
if (len == 3 && STRNCMP(*arg, "job", len) == 0)
@@ -1370,50 +1570,8 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
break;
}
- // It can be a class or interface name, possibly imported.
- int did_emsg_before = did_emsg;
- typval_T tv;
-
- tv.v_type = VAR_UNKNOWN;
- if (eval_variable_import(*arg, &tv) == OK)
- {
- if (tv.v_type == VAR_CLASS && tv.vval.v_class != NULL)
- {
- type_T *type = get_type_ptr(type_gap);
- if (type != NULL)
- {
- // Although the name is that of a class or interface, the type
- // uses will be an object.
- type->tt_type = VAR_OBJECT;
- type->tt_class = tv.vval.v_class;
- clear_tv(&tv);
-
- *arg += len;
- // Skip over ".ClassName".
- while (ASCII_ISALNUM(**arg) || **arg == '_' || **arg == '.')
- ++*arg;
-
- return type;
- }
- }
- else if (tv.v_type == VAR_TYPEALIAS)
- {
- // user defined type
- type_T *type = copy_type(tv.vval.v_typealias->ta_type, type_gap);
- *arg += len;
- clear_tv(&tv);
- // Skip over ".TypeName".
- while (ASCII_ISALNUM(**arg) || **arg == '_' || **arg == '.')
- ++*arg;
- return type;
- }
-
- clear_tv(&tv);
- }
-
- if (give_error && (did_emsg == did_emsg_before))
- semsg(_(e_type_not_recognized_str), *arg);
- return NULL;
+ // User defined type
+ return parse_type_user_defined(arg, len, type_gap, give_error);
}
/*
@@ -1470,6 +1628,60 @@ equal_type(type_T *type1, type_T *type2, int flags)
}
/*
+ * Find the common type of "type1" (VAR_FUNC) and "type2" (VAR_FUNC) and put it
+ * in "dest". "type2" and "dest" may be the same.
+ */
+ static void
+common_type_var_func(
+ type_T *type1,
+ type_T *type2,
+ type_T **dest,
+ garray_T *type_gap)
+{
+ type_T *common;
+
+ // When one of the types is t_func_unknown return the other one.
+ // Useful if a list or dict item is null_func.
+ if (type1 == &t_func_unknown)
+ {
+ *dest = type2;
+ return;
+ }
+ if (type2 == &t_func_unknown)
+ {
+ *dest = type1;
+ return;
+ }
+
+ common_type(type1->tt_member, type2->tt_member, &common, type_gap);
+ if (type1->tt_argcount == type2->tt_argcount
+ && type1->tt_argcount >= 0)
+ {
+ int argcount = type1->tt_argcount;
+ int i;
+
+ *dest = alloc_func_type(common, argcount, type_gap);
+ if (type1->tt_args != NULL && type2->tt_args != NULL)
+ {
+ if (func_type_add_arg_types(*dest, argcount,
+ type_gap) == OK)
+ for (i = 0; i < argcount; ++i)
+ common_type(type1->tt_args[i], type2->tt_args[i],
+ &(*dest)->tt_args[i], type_gap);
+ }
+ }
+ else
+ // Use -1 for "tt_argcount" to indicate an unknown number of
+ // arguments.
+ *dest = alloc_func_type(common, -1, type_gap);
+
+ // Use the minimum of min_argcount.
+ (*dest)->tt_min_argcount =
+ type1->tt_min_argcount < type2->tt_min_argcount
+ ? type1->tt_min_argcount : type2->tt_min_argcount;
+}
+
+/*
* Find the common type of "type1" and "type2" and put it in "dest".
* "type2" and "dest" may be the same.
*/
@@ -1508,49 +1720,10 @@ common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap)
*dest = get_dict_type(common, type_gap);
return;
}
+
if (type1->tt_type == VAR_FUNC)
{
- type_T *common;
-
- // When one of the types is t_func_unknown return the other one.
- // Useful if a list or dict item is null_func.
- if (type1 == &t_func_unknown)
- {
- *dest = type2;
- return;
- }
- if (type2 == &t_func_unknown)
- {
- *dest = type1;
- return;
- }
-
- common_type(type1->tt_member, type2->tt_member, &common, type_gap);
- if (type1->tt_argcount == type2->tt_argcount
- && type1->tt_argcount >= 0)
- {
- int argcount = type1->tt_argcount;
- int i;
-
- *dest = alloc_func_type(common, argcount, type_gap);
- if (type1->tt_args != NULL && type2->tt_args != NULL)
- {
- if (func_type_add_arg_types(*dest, argcount,
- type_gap) == OK)
- for (i = 0; i < argcount; ++i)
- common_type(type1->tt_args[i], type2->tt_args[i],
- &(*dest)->tt_args[i], type_gap);
- }
- }
- else
- // Use -1 for "tt_argcount" to indicate an unknown number of
- // arguments.
- *dest = alloc_func_type(common, -1, type_gap);
-
- // Use the minimum of min_argcount.
- (*dest)->tt_min_argcount =
- type1->tt_min_argcount < type2->tt_min_argcount
- ? type1->tt_min_argcount : type2->tt_min_argcount;
+ common_type_var_func(type1, type2, dest, type_gap);
return;
}
}
@@ -1705,113 +1878,156 @@ vartype_name(vartype_T type)
}
/*
- * Return the name of a type.
+ * Return the type name of a List (list<type>) or Dict (dict<type>).
* The result may be in allocated memory, in which case "tofree" is set.
*/
- char *
-type_name(type_T *type, char **tofree)
+ static char *
+type_name_list_or_dict(char *name, type_T *type, char **tofree)
{
- char *name;
- char *arg_free = NULL;
+ char *member_free;
+ char *member_name;
- *tofree = NULL;
- if (type == NULL)
- return "[unknown]";
- name = vartype_name(type->tt_type);
+ if (type->tt_member->tt_type == VAR_UNKNOWN)
+ member_name = type_name(&t_any, &member_free);
+ else
+ member_name = type_name(type->tt_member, &member_free);
+
+ size_t len = STRLEN(name) + STRLEN(member_name) + 3;
+ *tofree = alloc(len);
+ if (*tofree == NULL)
+ return name;
+
+ vim_snprintf(*tofree, len, "%s<%s>", name, member_name);
+ vim_free(member_free);
+ return *tofree;
+}
+
+/*
+ * Return the type name of a Class (class<name>) or Object (object<name>).
+ * The result may be in allocated memory, in which case "tofree" is set.
+ */
+ static char *
+type_name_class_or_obj(char *name, type_T *type, char **tofree)
+{
+ char_u *class_name;
- if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
+ if (type->tt_class != NULL)
{
- char *member_free;
- char *member_name;
- if (type->tt_member->tt_type == VAR_UNKNOWN)
- member_name = type_name(&t_any, &member_free);
- else
- member_name = type_name(type->tt_member, &member_free);
- size_t len = STRLEN(name) + STRLEN(member_name) + 3;
- *tofree = alloc(len);
- if (*tofree != NULL)
- {
- vim_snprintf(*tofree, len, "%s<%s>", name, member_name);
- vim_free(member_free);
- return *tofree;
- }
+ class_name = type->tt_class->class_name;
+ if (IS_ENUM(type->tt_class))
+ name = "enum";
}
+ else
+ class_name = (char_u *)"Unknown";
- if (type->tt_type == VAR_OBJECT || type->tt_type == VAR_CLASS)
+ size_t len = STRLEN(name) + STRLEN(class_name) + 3;
+ *tofree = alloc(len);
+ if (*tofree == NULL)
+ return name;
+
+ vim_snprintf(*tofree, len, "%s<%s>", name, class_name);
+ return *tofree;
+}
+
+/*
+ * Return the type name of a function.
+ * The result may be in allocated memory, in which case "tofree" is set.
+ */
+ static char *
+type_name_func(type_T *type, char **tofree)
+{
+ garray_T ga;
+ int i;
+ int varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0;
+ char *arg_free = NULL;
+
+ ga_init2(&ga, 1, 100);
+ if (ga_grow(&ga, 20) == FAIL)
+ goto failed;
+ STRCPY(ga.ga_data, "func(");
+ ga.ga_len += 5;
+
+ for (i = 0; i < type->tt_argcount; ++i)
{
- char_u *class_name = type->tt_class == NULL ? (char_u *)"Unknown"
- : type->tt_class->class_name;
- size_t len = STRLEN(name) + STRLEN(class_name) + 3;
- *tofree = alloc(len);
- if (*tofree != NULL)
+ char *arg_type;
+ int len;
+
+ if (type->tt_args == NULL)
+ arg_type = "[unknown]";
+ else
+ arg_type = type_name(type->tt_args[i], &arg_free);
+ if (i > 0)
{
- vim_snprintf(*tofree, len, "%s<%s>", name, class_name);
- return *tofree;
+ STRCPY((char *)ga.ga_data + ga.ga_len, ", ");
+ ga.ga_len += 2;
}
+ len = (int)STRLEN(arg_type);
+ if (ga_grow(&ga, len + 8) == FAIL)
+ goto failed;
+ if (varargs && i == type->tt_argcount - 1)
+ ga_concat(&ga, (char_u *)"...");
+ else if (i >= type->tt_min_argcount)
+ *((char *)ga.ga_data + ga.ga_len++) = '?';
+ ga_concat(&ga, (char_u *)arg_type);
+ VIM_CLEAR(arg_free);
}
+ if (type->tt_argcount < 0)
+ // any number of arguments
+ ga_concat(&ga, (char_u *)"...");
- if (type->tt_type == VAR_FUNC)
+ if (type->tt_member == &t_void)
+ STRCPY((char *)ga.ga_data + ga.ga_len, ")");
+ else
{
- garray_T ga;
- int i;
- int varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0;
+ char *ret_free;
+ char *ret_name = type_name(type->tt_member, &ret_free);
+ int len;
- ga_init2(&ga, 1, 100);
- if (ga_grow(&ga, 20) == FAIL)
+ len = (int)STRLEN(ret_name) + 4;
+ if (ga_grow(&ga, len) == FAIL)
goto failed;
- STRCPY(ga.ga_data, "func(");
- ga.ga_len += 5;
-
- for (i = 0; i < type->tt_argcount; ++i)
- {
- char *arg_type;
- int len;
+ STRCPY((char *)ga.ga_data + ga.ga_len, "): ");
+ STRCPY((char *)ga.ga_data + ga.ga_len + 3, ret_name);
+ vim_free(ret_free);
+ }
+ *tofree = ga.ga_data;
+ return ga.ga_data;
- if (type->tt_args == NULL)
- arg_type = "[unknown]";
- else
- arg_type = type_name(type->tt_args[i], &arg_free);
- if (i > 0)
- {
- STRCPY((char *)ga.ga_data + ga.ga_len, ", ");
- ga.ga_len += 2;
- }
- len = (int)STRLEN(arg_type);
- if (ga_grow(&ga, len + 8) == FAIL)
- goto failed;
- if (varargs && i == type->tt_argcount - 1)
- ga_concat(&ga, (char_u *)"...");
- else if (i >= type->tt_min_argcount)
- *((char *)ga.ga_data + ga.ga_len++) = '?';
- ga_concat(&ga, (char_u *)arg_type);
- VIM_CLEAR(arg_free);
- }
- if (type->tt_argcount < 0)
- // any number of arguments
- ga_concat(&ga, (char_u *)"...");
+failed:
+ vim_free(arg_free);
+ ga_clear(&ga);
+ return "[unknown]";
+}
- if (type->tt_member == &t_void)
- STRCPY((char *)ga.ga_data + ga.ga_len, ")");
- else
- {
- char *ret_free;
- char *ret_name = type_name(type->tt_member, &ret_free);
- int len;
-
- len = (int)STRLEN(ret_name) + 4;
- if (ga_grow(&ga, len) == FAIL)
- goto failed;
- STRCPY((char *)ga.ga_data + ga.ga_len, "): ");
- STRCPY((char *)ga.ga_data + ga.ga_len + 3, ret_name);
- vim_free(ret_free);
- }
- *tofree = ga.ga_data;
- return ga.ga_data;
+/*
+ * Return the name of a type.
+ * The result may be in allocated memory, in which case "tofree" is set.
+ */
+ char *
+type_name(type_T *type, char **tofree)
+{
+ char *name;
-failed:
- vim_free(arg_free);
- ga_clear(&ga);
+ *tofree = NULL;
+ if (type == NULL)
return "[unknown]";
+ name = vartype_name(type->tt_type);
+
+ switch (type->tt_type)
+ {
+ case VAR_LIST:
+ case VAR_DICT:
+ return type_name_list_or_dict(name, type, tofree);
+
+ case VAR_CLASS:
+ case VAR_OBJECT:
+ return type_name_class_or_obj(name, type, tofree);
+
+ case VAR_FUNC:
+ return type_name_func(type, tofree);
+
+ default:
+ break;
}
return name;
@@ -1869,18 +2085,26 @@ check_typval_is_value(typval_T *tv)
{
if (tv == NULL)
return OK;
- if (tv->v_type == VAR_CLASS)
- {
- if (tv->vval.v_class != NULL)
- semsg(_(e_using_class_as_value_str), tv->vval.v_class->class_name);
- else
- emsg(e_using_class_as_var_val);
- return FAIL;
- }
- else if (tv->v_type == VAR_TYPEALIAS)
+
+ switch (tv->v_type)
{
- semsg(_(e_using_typealias_as_value_str), tv->vval.v_typealias->ta_name);
- return FAIL;
+ case VAR_CLASS:
+ {
+ class_T *cl = tv->vval.v_class;
+ if (IS_ENUM(cl))
+ semsg(_(e_using_enum_as_value_str), cl->class_name);
+ else
+ semsg(_(e_using_class_as_value_str), cl->class_name);
+ }
+ return FAIL;
+
+ case VAR_TYPEALIAS:
+ semsg(_(e_using_typealias_as_value_str),
+ tv->vval.v_typealias->ta_name);
+ return FAIL;
+
+ default:
+ break;
}
return OK;
}
@@ -1893,17 +2117,25 @@ check_type_is_value(type_T *type)
{
if (type == NULL)
return OK;
- if (type->tt_type == VAR_CLASS)
+ switch (type->tt_type)
{
- semsg(_(e_using_class_as_value_str), type->tt_class->class_name);
- return FAIL;
- }
- else if (type->tt_type == VAR_TYPEALIAS)
- {
- // TODO: Not sure what could be done here to get a name.
- // Maybe an optional argument?
- emsg(_(e_using_typealias_as_var_val));
- return FAIL;
+ case VAR_CLASS:
+ if (IS_ENUM(type->tt_class))
+ semsg(_(e_using_enum_as_value_str),
+ type->tt_class->class_name);
+ else
+ semsg(_(e_using_class_as_value_str),
+ type->tt_class->class_name);
+ return FAIL;
+
+ case VAR_TYPEALIAS:
+ // TODO: Not sure what could be done here to get a name.
+ // Maybe an optional argument?
+ emsg(_(e_using_typealias_as_var_val));
+ return FAIL;
+
+ default:
+ break;
}
return OK;
}
diff --git a/src/window.c b/src/window.c
index 9ffca77..7322905 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2475,6 +2475,7 @@ win_init_empty(win_T *wp)
wp->w_topfill = 0;
#endif
wp->w_botline = 2;
+ wp->w_valid = 0;
#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL)
wp->w_s = &wp->w_buffer->b_s;
#endif
@@ -4437,8 +4438,7 @@ win_init_popup_win(win_T *wp, buf_T *buf)
++buf->b_nwindows;
win_init_empty(wp); // set cursor and topline to safe values
- // Make sure w_localdir and globaldir are NULL to avoid a chdir() in
- // win_enter_ext().
+ // Make sure w_localdir is NULL to avoid a chdir() in win_enter_ext().
VIM_CLEAR(wp->w_localdir);
}
@@ -5445,8 +5445,8 @@ win_enter(win_T *wp, int undo_sync)
* Used after making another window the current one: change directory if
* needed.
*/
- static void
-fix_current_dir(void)
+ void
+win_fix_current_dir(void)
{
if (curwin->w_localdir != NULL || curtab->tp_localdir != NULL)
{
@@ -5567,7 +5567,7 @@ win_enter_ext(win_T *wp, int flags)
}
#endif
- fix_current_dir();
+ win_fix_current_dir();
#ifdef FEAT_JOB_CHANNEL
entering_window(curwin);