summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GvimExt/Make_ming.mak4
-rw-r--r--src/GvimExt/Make_mvc.mak25
-rw-r--r--src/INSTALL6
-rw-r--r--src/Make_cyg_ming.mak58
-rw-r--r--src/Make_mvc.mak363
-rw-r--r--src/Makefile12
-rw-r--r--src/arglist.c6
-rwxr-xr-xsrc/auto/configure37
-rw-r--r--src/autocmd.c13
-rw-r--r--src/buffer.c39
-rw-r--r--src/bufwrite.c4
-rw-r--r--src/change.c4
-rw-r--r--src/channel.c2
-rw-r--r--src/charset.c34
-rw-r--r--src/cmdexpand.c15
-rw-r--r--src/config.h.in7
-rw-r--r--src/configure.ac19
-rw-r--r--src/dict.c7
-rw-r--r--src/edit.c8
-rw-r--r--src/errors.h41
-rw-r--r--src/eval.c106
-rw-r--r--src/evalfunc.c245
-rw-r--r--src/evalvars.c2
-rw-r--r--src/ex_cmds.c25
-rw-r--r--src/ex_cmds2.c2
-rw-r--r--src/ex_docmd.c125
-rw-r--r--src/ex_getln.c65
-rw-r--r--src/fileio.c4
-rw-r--r--src/filepath.c14
-rw-r--r--src/findfile.c70
-rw-r--r--src/fold.c5
-rw-r--r--src/getchar.c227
-rw-r--r--src/globals.h68
-rw-r--r--src/gui.c2
-rw-r--r--src/gui_gtk_x11.c4
-rw-r--r--src/gui_w32.c9
-rw-r--r--src/help.c4
-rw-r--r--src/highlight.c4
-rw-r--r--src/if_mzsch.c21
-rw-r--r--src/if_py_both.h16
-rw-r--r--src/if_python3.c58
-rw-r--r--src/indent.c2
-rw-r--r--src/insexpand.c229
-rw-r--r--src/list.c7
-rw-r--r--src/macros.h6
-rw-r--r--src/map.c46
-rw-r--r--src/mark.c32
-rw-r--r--src/mbyte.c11
-rw-r--r--src/memline.c10
-rw-r--r--src/misc1.c22
-rw-r--r--src/misc2.c2
-rw-r--r--src/move.c9
-rw-r--r--src/netbeans.c2
-rw-r--r--src/normal.c10
-rw-r--r--src/ops.c31
-rw-r--r--src/option.h27
-rw-r--r--src/optiondefs.h16
-rw-r--r--src/optionstr.c25
-rw-r--r--src/os_mswin.c255
-rw-r--r--src/os_unix.c42
-rw-r--r--src/os_w32dll.c2
-rw-r--r--src/os_w32exe.c72
-rw-r--r--src/os_win32.c71
-rw-r--r--src/po/Make_cyg.mak10
-rw-r--r--src/po/Make_ming.mak12
-rw-r--r--src/po/Make_mvc.mak167
-rw-r--r--src/po/Makefile101
-rw-r--r--src/po/README.txt17
-rw-r--r--src/po/README_mvc.txt18
-rw-r--r--src/po/ca.po4
-rw-r--r--src/po/cleanup.vim12
-rw-r--r--src/po/cs.cp1250.po2
-rw-r--r--src/po/da.po4
-rw-r--r--src/po/de.po4
-rw-r--r--src/po/eo.po4
-rw-r--r--src/po/es.po4
-rw-r--r--src/po/fi.po4
-rw-r--r--src/po/fixfilenames.vim8
-rw-r--r--src/po/fr.po4
-rw-r--r--src/po/ga.po4
-rw-r--r--src/po/hu.po4
-rw-r--r--src/po/it.po91
-rw-r--r--src/po/ja.euc-jp.po181
-rw-r--r--src/po/ja.po181
-rw-r--r--src/po/ja.sjis.po181
-rw-r--r--src/po/ko.UTF-8.po4
-rw-r--r--src/po/ko.po10
-rw-r--r--src/po/nb.po5
-rw-r--r--src/po/nl.po4
-rw-r--r--src/po/no.po5
-rw-r--r--src/po/pl.UTF-8.po4
-rw-r--r--src/po/pl.cp1250.po6
-rw-r--r--src/po/pl.po4
-rw-r--r--src/po/pt_BR.po39
-rw-r--r--src/po/ru.cp1251.po329
-rw-r--r--src/po/ru.po2
-rw-r--r--src/po/sk.cp1250.po2
-rw-r--r--src/po/sr.po68
-rw-r--r--src/po/sv.po4
-rw-r--r--src/po/tojavascript.vim13
-rw-r--r--src/po/tr.po180
-rw-r--r--src/po/uk.cp1251.po4
-rw-r--r--src/po/uk.po4
-rw-r--r--src/po/zh_CN.UTF-8.po4
-rw-r--r--src/po/zh_CN.cp936.po6
-rw-r--r--src/po/zh_CN.po6
-rw-r--r--src/po/zh_TW.po2
-rw-r--r--src/popupmenu.c21
-rw-r--r--src/popupwin.c54
-rw-r--r--src/proto/autocmd.pro1
-rw-r--r--src/proto/dict.pro2
-rw-r--r--src/proto/findfile.pro2
-rw-r--r--src/proto/list.pro2
-rw-r--r--src/proto/mark.pro1
-rw-r--r--src/proto/mbyte.pro1
-rw-r--r--src/proto/memline.pro2
-rw-r--r--src/proto/option.pro1
-rw-r--r--src/proto/optionstr.pro1
-rw-r--r--src/proto/os_mswin.pro2
-rw-r--r--src/proto/os_unix.pro1
-rw-r--r--src/proto/popupwin.pro1
-rw-r--r--src/proto/search.pro1
-rw-r--r--src/proto/sign.pro2
-rw-r--r--src/proto/tag.pro1
-rw-r--r--src/proto/typval.pro3
-rw-r--r--src/proto/userfunc.pro3
-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/regexp.c58
-rw-r--r--src/regexp_bt.c8
-rw-r--r--src/regexp_nfa.c9
-rw-r--r--src/search.c172
-rw-r--r--src/sign.c37
-rw-r--r--src/spellfile.c8
-rw-r--r--src/strings.c64
-rw-r--r--src/structs.h23
-rw-r--r--src/syntax.c119
-rw-r--r--src/tag.c12
-rw-r--r--src/terminal.c18
-rw-r--r--src/testdir/Make_all.mak18
-rw-r--r--src/testdir/Make_mvc.mak8
-rw-r--r--src/testdir/Makefile4
-rw-r--r--src/testdir/README.txt83
-rw-r--r--src/testdir/commondumps.vim76
-rw-r--r--src/testdir/crash/dialog_changed_uafbin0 -> 552 bytes
-rw-r--r--src/testdir/crash/double_freebin0 -> 561 bytes
-rw-r--r--src/testdir/crash/heap_overflow3bin0 -> 700 bytes
-rw-r--r--src/testdir/crash/nullpointerbin0 -> 315 bytes
-rw-r--r--src/testdir/crash/reverse_text_overflowbin0 -> 314 bytes
-rw-r--r--src/testdir/dumps/Test_breakindent_with_double_width_wrap_1.dump6
-rw-r--r--src/testdir/dumps/Test_cmdwin_no_terminal.dump2
-rw-r--r--src/testdir/dumps/Test_matchparen_mbyte_1.dump10
-rw-r--r--src/testdir/dumps/Test_matchparen_mbyte_2.dump10
-rw-r--r--src/testdir/dumps/Test_matchparen_mbyte_3.dump10
-rw-r--r--src/testdir/dumps/Test_matchparen_mbyte_4.dump10
-rw-r--r--src/testdir/dumps/Test_matchparen_mbyte_5.dump10
-rw-r--r--src/testdir/dumps/Test_matchparen_mbyte_6.dump10
-rw-r--r--src/testdir/dumps/Test_matchparen_mbyte_7.dump10
-rw-r--r--src/testdir/dumps/Test_matchparen_mbyte_8.dump10
-rw-r--r--src/testdir/dumps/Test_popup_setbuf_01.dump10
-rw-r--r--src/testdir/dumps/Test_popup_setbuf_02.dump10
-rw-r--r--src/testdir/dumps/Test_popup_setbuf_03.dump10
-rw-r--r--src/testdir/dumps/Test_popup_setbuf_04.dump10
-rw-r--r--src/testdir/dumps/Test_popup_setbuf_05.dump10
-rw-r--r--src/testdir/dumps/Test_popup_setbuf_06.dump10
-rw-r--r--src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_2.dump3
-rw-r--r--src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_3.dump3
-rw-r--r--src/testdir/dumps/Test_pum_highlights_10.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_11.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_12.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_13.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_14.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_15.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_16.dump20
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_11.dump2
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_12.dump2
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_13.dump2
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_22.dump4
-rw-r--r--src/testdir/gen_opt_test.vim1
-rw-r--r--src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mobin0 -> 875 bytes
-rw-r--r--src/testdir/samples/Test_tohtml_basic.c.html47
-rw-r--r--src/testdir/samples/Test_tohtml_basic_no_css.c.html40
-rw-r--r--src/testdir/samples/test.zipbin0 -> 464 bytes
-rw-r--r--src/testdir/samples/testa.zipbin0 -> 1236 bytes
-rw-r--r--src/testdir/test28.in13
-rw-r--r--src/testdir/test28.ok3
-rw-r--r--src/testdir/test_arglist.vim23
-rw-r--r--src/testdir/test_assert.vim9
-rw-r--r--src/testdir/test_autocmd.vim174
-rw-r--r--src/testdir/test_breakindent.vim11
-rw-r--r--src/testdir/test_buffer.vim46
-rw-r--r--src/testdir/test_cd.vim8
-rw-r--r--src/testdir/test_cmdline.vim39
-rw-r--r--src/testdir/test_codestyle.vim12
-rw-r--r--src/testdir/test_cpoptions.vim119
-rw-r--r--src/testdir/test_crash.vim40
-rw-r--r--src/testdir/test_eval_stuff.vim27
-rw-r--r--src/testdir/test_ex_mode.vim100
-rw-r--r--src/testdir/test_excmd.vim2
-rw-r--r--src/testdir/test_filetype.vim217
-rw-r--r--src/testdir/test_findfile.vim35
-rw-r--r--src/testdir/test_fnamemodify.vim2
-rw-r--r--src/testdir/test_fold.vim35
-rw-r--r--src/testdir/test_functions.vim32
-rw-r--r--src/testdir/test_gettext.vim18
-rw-r--r--src/testdir/test_gettext_cp1251.vim35
-rw-r--r--src/testdir/test_gettext_make.vim72
-rw-r--r--src/testdir/test_gettext_makefile_in1.vim7
-rw-r--r--src/testdir/test_gettext_makefile_in2.vim6
-rw-r--r--src/testdir/test_gettext_makefile_in3.vim4
-rw-r--r--src/testdir/test_gettext_makefile_in4.vim6
-rw-r--r--src/testdir/test_gettext_utf8.vim35
-rw-r--r--src/testdir/test_getvar.vim8
-rw-r--r--src/testdir/test_goto.vim7
-rw-r--r--src/testdir/test_gui.vim3
-rw-r--r--src/testdir/test_increment.vim38
-rw-r--r--src/testdir/test_ins_complete.vim118
-rw-r--r--src/testdir/test_jumplist.vim68
-rw-r--r--src/testdir/test_listdict.vim92
-rw-r--r--src/testdir/test_listlbr_utf8.vim6
-rw-r--r--src/testdir/test_mapping.vim43
-rw-r--r--src/testdir/test_matchparen.vim30
-rw-r--r--src/testdir/test_menu.vim41
-rw-r--r--src/testdir/test_normal.vim3
-rw-r--r--src/testdir/test_options.vim10
-rw-r--r--src/testdir/test_partial.vim22
-rw-r--r--src/testdir/test_paste.vim2
-rw-r--r--src/testdir/test_popup.vim93
-rw-r--r--src/testdir/test_popupwin.vim82
-rw-r--r--src/testdir/test_put.vim8
-rw-r--r--src/testdir/test_quickfix.vim4
-rw-r--r--src/testdir/test_regexp_utf8.vim32
-rw-r--r--src/testdir/test_search.vim31
-rw-r--r--src/testdir/test_selectmode.vim16
-rw-r--r--src/testdir/test_signs.vim40
-rw-r--r--src/testdir/test_spell.vim15
-rw-r--r--src/testdir/test_spellfile.vim16
-rw-r--r--src/testdir/test_substitute.vim15
-rw-r--r--src/testdir/test_tabpage.vim58
-rw-r--r--src/testdir/test_tagjump.vim57
-rw-r--r--src/testdir/test_taglist.vim47
-rw-r--r--src/testdir/test_termcodes.vim11
-rw-r--r--src/testdir/test_termdebug.vim205
-rw-r--r--src/testdir/test_textobjects.vim12
-rw-r--r--src/testdir/test_textprop.vim4
-rw-r--r--src/testdir/test_tohtml.vim72
-rw-r--r--src/testdir/test_usercommands.vim4
-rw-r--r--src/testdir/test_vim9_builtin.vim66
-rw-r--r--src/testdir/test_vim9_class.vim469
-rw-r--r--src/testdir/test_vim9_cmd.vim9
-rw-r--r--src/testdir/test_vim9_disassemble.vim90
-rw-r--r--src/testdir/test_vim9_func.vim10
-rw-r--r--src/testdir/test_vim9_script.vim18
-rw-r--r--src/testdir/test_vimscript.vim25
-rw-r--r--src/testdir/test_winfixbuf.vim1
-rw-r--r--src/testdir/test_xxd.vim16
-rw-r--r--src/testdir/test_zip_plugin.vim237
-rw-r--r--src/testdir/view_util.vim2
-rw-r--r--src/testdir/viewdumps.vim11
-rw-r--r--src/testing.c11
-rw-r--r--src/textobject.c11
-rw-r--r--src/textprop.c2
-rw-r--r--src/typval.c89
-rw-r--r--src/undo.c4
-rw-r--r--src/usercmd.c510
-rw-r--r--src/userfunc.c95
-rw-r--r--src/version.c404
-rw-r--r--src/vim.h10
-rw-r--r--src/vim9.h3
-rw-r--r--src/vim9class.c127
-rw-r--r--src/vim9cmds.c4
-rw-r--r--src/vim9compile.c13
-rw-r--r--src/vim9execute.c81
-rw-r--r--src/vim9expr.c24
-rw-r--r--src/vim9instr.c6
-rw-r--r--src/vim9type.c16
-rw-r--r--src/viminfo.c2
-rw-r--r--src/window.c76
-rw-r--r--src/xxd/Make_ming.mak2
-rw-r--r--src/xxd/Make_mvc.mak2
281 files changed, 8143 insertions, 2392 deletions
diff --git a/src/GvimExt/Make_ming.mak b/src/GvimExt/Make_ming.mak
index 85017d8..06ec7b6 100644
--- a/src/GvimExt/Make_ming.mak
+++ b/src/GvimExt/Make_ming.mak
@@ -29,7 +29,7 @@ LDFLAGS += -static-libgcc -static-libstdc++
endif
ifeq ($(CROSS),yes)
-DEL = rm
+DEL = rm -f
ifeq ($(MINGWOLD),yes)
CXXFLAGS := -O2 -fvtable-thunks
else
@@ -38,7 +38,7 @@ endif
else
CXXFLAGS := -O2
ifneq (sh.exe, $(SHELL))
-DEL = rm
+DEL = rm -f
else
DEL = del
endif
diff --git a/src/GvimExt/Make_mvc.mak b/src/GvimExt/Make_mvc.mak
index 7068d8f..132a584 100644
--- a/src/GvimExt/Make_mvc.mak
+++ b/src/GvimExt/Make_mvc.mak
@@ -19,25 +19,24 @@ WINVER = 0x0601
NODEBUG = 1
!endif
-!ifdef PROCESSOR_ARCHITECTURE
-# On Windows NT
-! ifndef CPU
+!ifndef CPU
CPU = i386
-! if !defined(PLATFORM) && defined(TARGET_CPU)
+! ifndef PLATFORM
+! ifdef TARGET_CPU
PLATFORM = $(TARGET_CPU)
+! elseif defined(VSCMD_ARG_TGT_ARCH)
+PLATFORM = $(VSCMD_ARG_TGT_ARCH)
! endif
-! ifdef PLATFORM
-! if ("$(PLATFORM)" == "x64") || ("$(PLATFORM)" == "X64")
+! endif
+! ifdef PLATFORM
+! if ("$(PLATFORM)" == "x64") || ("$(PLATFORM)" == "X64")
CPU = AMD64
-! elseif ("$(PLATFORM)" == "arm64") || ("$(PLATFORM)" == "ARM64")
+! elseif ("$(PLATFORM)" == "arm64") || ("$(PLATFORM)" == "ARM64")
CPU = ARM64
-! elseif ("$(PLATFORM)" != "x86") && ("$(PLATFORM)" != "X86")
-! error *** ERROR Unknown target platform "$(PLATFORM)". Make aborted.
-! endif
+! elseif ("$(PLATFORM)" != "x86") && ("$(PLATFORM)" != "X86")
+! error *** ERROR Unknown target platform "$(PLATFORM)". Make aborted.
! endif
! endif
-!else
-CPU = i386
!endif
!ifdef SDK_INCLUDE_DIR
@@ -80,7 +79,6 @@ all: gvimext.dll
gvimext.dll: gvimext.obj \
gvimext.res
$(link) $(lflags) -dll -def:gvimext.def -base:$(OFFSET) -out:$*.dll $** $(olelibsdll) shell32.lib comctl32.lib -subsystem:$(SUBSYSTEM)
- if exist $*.dll.manifest mt -nologo -manifest $*.dll.manifest -outputresource:$*.dll;2
gvimext.obj: gvimext.h
@@ -96,4 +94,3 @@ clean:
- if exist gvimext.exp del gvimext.exp
- if exist gvimext.obj del gvimext.obj
- if exist gvimext.res del gvimext.res
- - if exist gvimext.dll.manifest del gvimext.dll.manifest
diff --git a/src/INSTALL b/src/INSTALL
index efa03da..79d7584 100644
--- a/src/INSTALL
+++ b/src/INSTALL
@@ -178,12 +178,6 @@ There used to be a KDE version of Vim, using Qt libraries, but since it didn't
work very well and there was no maintainer it was dropped.
-Unix: COMPILING ON LINUX
-
-On Linux, when using -g to compile (which is default for gcc), the executable
-will probably be statically linked. If you don't want this, remove the -g
-option from CFLAGS.
-
Unix: PUTTING vimrc IN /etc
Some Linux distributions prefer to put the global vimrc file in /etc, and the
diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak
index 20ed903..8aeba67 100644
--- a/src/Make_cyg_ming.mak
+++ b/src/Make_cyg_ming.mak
@@ -130,7 +130,6 @@ ifndef STATIC_STDCPLUS
STATIC_STDCPLUS=no
endif
-
# Link against the shared version of libwinpthread by default. Set
# STATIC_WINPTHREAD to "yes" to link against static version instead.
ifndef STATIC_WINPTHREAD
@@ -140,6 +139,12 @@ endif
# This is used when STATIC_STDCPLUS=yes.
HAS_GCC_EH=yes
+# Reduce the size of the executables by using the --gc-sections linker
+# option. Set USE_GC_SECTIONS to "no" if you see any issues with this.
+ifndef USE_GC_SECTIONS
+USE_GC_SECTIONS=yes
+endif
+
# If the user doesn't want gettext, undefine it.
ifeq (no, $(GETTEXT))
GETTEXT=
@@ -179,7 +184,7 @@ ifeq ($(CROSS),yes)
ifndef CROSS_COMPILE
CROSS_COMPILE = i586-pc-mingw32msvc-
endif
-DEL = rm
+DEL = rm -f
MKDIR = mkdir -p
DIRSLASH = /
else
@@ -207,7 +212,7 @@ CROSS_COMPILE =
# In this case, unix-like commands can be used.
#
ifneq (sh.exe, $(SHELL))
-DEL = rm
+DEL = rm -f
MKDIR = mkdir -p
DIRSLASH = /
else
@@ -386,14 +391,19 @@ endif
# Python3 interface:
# PYTHON3=[Path to Python3 directory] (Set inside Make_cyg.mak or Make_ming.mak)
# DYNAMIC_PYTHON3=yes (to load the Python3 DLL dynamically)
-# PYTHON3_VER=[Python3 version, eg 31, 32] (default is 36)
+# PYTHON3_VER=[Python3 version, eg 31, 32] (default is 38)
ifdef PYTHON3
ifndef DYNAMIC_PYTHON3
DYNAMIC_PYTHON3=yes
endif
+ ifndef DYNAMIC_PYTHON3_STABLE_ABI
+ ifeq (yes,$(DYNAMIC_PYTHON3))
+DYNAMIC_PYTHON3_STABLE_ABI=yes
+ endif
+ endif
ifndef PYTHON3_VER
-PYTHON3_VER=36
+PYTHON3_VER=38
endif
ifeq ($(DYNAMIC_PYTHON3_STABLE_ABI),yes)
PYTHON3_NAME=python3
@@ -1001,6 +1011,9 @@ EXELFLAGS += -s
endif
ifeq ($(COVERAGE),yes)
EXELFLAGS += --coverage
+ else ifndef MZSCHEME
+EXELFLAGS += -nostdlib
+EXECFLAGS = -DUSE_OWNSTARTUP
endif
DEFINES += $(DEF_GUI) -DVIMDLL
OBJ += $(GUIOBJ) $(CUIOBJ)
@@ -1093,6 +1106,16 @@ LIB += -lgcc_eh
LIB += -Wl,-Bstatic -lwinpthread -Wl,-Bdynamic
endif
+# To reduce the file size
+ifeq (yes, $(USE_GC_SECTIONS))
+CFLAGS += -ffunction-sections -fno-asynchronous-unwind-tables
+CXXFLAGS += -fasynchronous-unwind-tables
+LFLAGS += -Wl,--gc-sections
+ ifeq (yes, $(VIMDLL))
+EXELFLAGS += -Wl,--gc-sections
+ endif
+endif
+
ifeq (yes, $(MAP))
LFLAGS += -Wl,-Map=$(TARGET).map
endif
@@ -1122,14 +1145,25 @@ $(EXEOBJG): | $(OUTDIR)
$(EXEOBJC): | $(OUTDIR)
ifeq ($(VIMDLL),yes)
+ ifneq ($(findstring -nostdlib,$(EXELFLAGS)),)
+ # -Wl,--entry needs to be specified when -nostdlib is used.
+ ifeq ($(ARCH),x86-64)
+EXEENTRYC = -Wl,--entry=wmainCRTStartup
+EXEENTRYG = -Wl,--entry=wWinMainCRTStartup
+ else ifeq ($(ARCH),i686)
+EXEENTRYC = -Wl,--entry=_wmainCRTStartup
+EXEENTRYG = -Wl,--entry=_wWinMainCRTStartup@0
+ endif
+ endif
+
$(TARGET): $(OBJ)
$(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid -lgdi32 $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(SODIUMLIB)
$(GVIMEXE): $(EXEOBJG) $(VIMDLLBASE).dll
- $(CC) -L. $(EXELFLAGS) -mwindows -o $@ $(EXEOBJG) -l$(VIMDLLBASE)
+ $(CC) -L. $(EXELFLAGS) -mwindows -o $@ $(EXEOBJG) -l$(VIMDLLBASE) $(EXEENTRYG)
$(VIMEXE): $(EXEOBJC) $(VIMDLLBASE).dll
- $(CC) -L. $(EXELFLAGS) -o $@ $(EXEOBJC) -l$(VIMDLLBASE)
+ $(CC) -L. $(EXELFLAGS) -o $@ $(EXEOBJC) -l$(VIMDLLBASE) $(EXEENTRYC)
else
$(TARGET): $(OBJ)
$(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(SODIUMLIB)
@@ -1160,10 +1194,13 @@ notags:
clean:
-$(DEL) $(OUTDIR)$(DIRSLASH)*.o
+ -$(DEL) $(OUTDIR)$(DIRSLASH)*.gcno
+ -$(DEL) $(OUTDIR)$(DIRSLASH)*.gcda
-$(DEL) $(OUTDIR)$(DIRSLASH)*.res
-$(DEL) $(OUTDIR)$(DIRSLASH)pathdef.c
-rmdir $(OUTDIR)
-$(DEL) $(MAIN_TARGET) vimrun.exe install.exe uninstall.exe
+ -$(DEL) *.gcno *.gcda
-$(DEL) *.map
ifdef PERL
-$(DEL) if_perl.c
@@ -1297,6 +1334,9 @@ $(OUTDIR)/gui_w32.o: gui_w32.c $(INCL) $(GUI_INCL) version.h
$(OUTDIR)/if_cscope.o: if_cscope.c $(INCL)
$(CC) -c $(CFLAGS) if_cscope.c -o $@
+$(OUTDIR)/if_lua.o: if_lua.c $(INCL)
+ $(CC) -c $(CFLAGS:-fno-asynchronous-unwind-tables=) if_lua.c -o $@
+
$(OUTDIR)/if_mzsch.o: if_mzsch.c $(INCL) $(MZSCHEME_INCL) $(MZ_EXTRA_DEP)
$(CC) -c $(CFLAGS) if_mzsch.c -o $@
@@ -1330,10 +1370,10 @@ $(OUTDIR)/netbeans.o: netbeans.c $(INCL) $(NBDEBUG_INCL) $(NBDEBUG_SRC)
$(CC) -c $(CFLAGS) netbeans.c -o $@
$(OUTDIR)/os_w32exec.o: os_w32exe.c $(INCL)
- $(CC) -c $(CFLAGS) -UFEAT_GUI_MSWIN os_w32exe.c -o $@
+ $(CC) -c $(CFLAGS) -UFEAT_GUI_MSWIN $(EXECFLAGS) os_w32exe.c -o $@
$(OUTDIR)/os_w32exeg.o: os_w32exe.c $(INCL)
- $(CC) -c $(CFLAGS) os_w32exe.c -o $@
+ $(CC) -c $(CFLAGS) $(EXECFLAGS) os_w32exe.c -o $@
$(OUTDIR)/os_win32.o: os_win32.c $(INCL) $(MZSCHEME_INCL)
$(CC) -c $(CFLAGS) os_win32.c -o $@
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index e58814b..49d8a33 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -80,7 +80,7 @@
# Python3 interface:
# PYTHON3=[Path to Python3 directory]
# DYNAMIC_PYTHON3=yes (to load the Python3 DLL dynamically)
-# PYTHON3_VER=[Python3 version, eg 30, 31] (default is 36)
+# PYTHON3_VER=[Python3 version, eg 30, 31] (default is 38)
#
# Ruby interface:
# RUBY=[Path to Ruby directory]
@@ -127,15 +127,20 @@
#
# Optimization: OPTIMIZE=[SPACE, SPEED, MAXSPEED] (default is MAXSPEED)
#
-# Processor Version: CPUNR=[any, i686, sse, sse2, avx, avx2] (default is
-# sse2)
+# Processor Version:
+# For x86: CPUNR=[any, i686, sse, sse2, avx, avx2, avx512]
+# For x64: CPUNR=[sse2, avx, avx2, avx512]
+# (default is sse2 (both x86 and x64))
# avx is available on Visual C++ 2010 and after.
# avx2 is available on Visual C++ 2013 Update 2 and after.
+# avx512 is available on Visual C++ 2017 and after.
+# For ARM64:
+# See: https://learn.microsoft.com/en-us/cpp/build/reference/arch-arm64
#
# Version Support: WINVER=[0x0601, 0x0602, 0x0603, 0x0A00] (default is
# 0x0601)
# Supported versions depends on your target SDK, check SDKDDKVer.h
-# See https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt
+# See https://learn.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt
#
# Debug version: DEBUG=yes
# Mapfile: MAP=[no, yes or lines] (default is yes)
@@ -157,53 +162,56 @@
# 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
+RM = del /f /q
-PSFLAGS= -NoLogo -NoProfile -Command
+# Read MAJOR and MINOR from version.h.
+!IF ![for /f "tokens=2,3" %I in (version.h) do \
+ @if "%I"=="VIM_VERSION_MAJOR" ( \
+ echo MAJOR=%J> .\major.tmp \
+ ) else if "%I"=="VIM_VERSION_MINOR" ( \
+ echo MINOR=%J> .\minor.tmp && exit \
+ )]
+!ENDIF
-!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}]
+!IF EXIST(.\major.tmp)
! INCLUDE .\major.tmp
! IF [$(RM) .\major.tmp]
! ENDIF
!ELSE
# Change this value for the new version
-MAJOR= 9
+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}]
+!IF EXIST(.\minor.tmp)
! INCLUDE .\minor.tmp
! IF [$(RM) .\minor.tmp]
! ENDIF
!ELSE
# Change this value for the new version
-MINOR= 1
+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}]
+# Read PATCHLEVEL from version.c.
+!IF ![cmd.exe /V:ON /Q /C "set LINE=0&& set FIND=0&& \
+ for /f "tokens=1,3 delims=, " %I in (version.c) do ( \
+ set /A LINE+=1 > NUL && \
+ if "%J"=="included_patches[^]" ( \
+ set /A FIND=LINE+3 > NUL \
+ ) else if "!LINE!"=="!FIND!" ( \
+ echo PATCHLEVEL=%I> .\patchlvl.tmp && exit \
+ ) \
+ )"]
+!ENDIF
+!IF EXIST(.\patchlvl.tmp)
! INCLUDE .\patchlvl.tmp
! IF [$(RM) .\patchlvl.tmp]
! ENDIF
!ENDIF
-
-# Build on Windows NT/XP
-
-TARGETOS = WINNT
-
!IFDEF PATCHLEVEL
-RCFLAGS= -DVIM_VERSION_PATCHLEVEL=$(PATCHLEVEL)
+RCFLAGS = -DVIM_VERSION_PATCHLEVEL=$(PATCHLEVEL)
!ENDIF
+!message Vim version: $(MAJOR).$(MINOR).$(PATCHLEVEL)
!if "$(VIMDLL)" == "yes"
@@ -257,38 +265,29 @@ OBJDIR = $(OBJDIR)V
OBJDIR = $(OBJDIR)d
!endif
-!ifdef PROCESSOR_ARCHITECTURE
-# We're on Windows NT or using VC 6+
-! ifdef CPU
-ASSEMBLY_ARCHITECTURE=$(CPU)
-# Using I386 for $ASSEMBLY_ARCHITECTURE doesn't work for VC7.
-! if "$(CPU)" == "I386"
+!ifdef CPU
+! if "$(CPU)" == "I386"
CPU = i386
-! endif
-! else # !CPU
+! endif
+!else # !CPU
CPU = i386
-! ifndef PLATFORM
-! ifdef TARGET_CPU
+! ifndef PLATFORM
+! ifdef TARGET_CPU
PLATFORM = $(TARGET_CPU)
-! elseif defined(VSCMD_ARG_TGT_ARCH)
+! elseif defined(VSCMD_ARG_TGT_ARCH)
PLATFORM = $(VSCMD_ARG_TGT_ARCH)
-! endif
! endif
-! ifdef PLATFORM
-! if ("$(PLATFORM)" == "x64") || ("$(PLATFORM)" == "X64")
+! endif
+! ifdef PLATFORM
+! if ("$(PLATFORM)" == "x64") || ("$(PLATFORM)" == "X64")
CPU = AMD64
-! elseif ("$(PLATFORM)" == "arm64") || ("$(PLATFORM)" == "ARM64")
+! elseif ("$(PLATFORM)" == "arm64") || ("$(PLATFORM)" == "ARM64")
CPU = ARM64
-! elseif ("$(PLATFORM)" != "x86") && ("$(PLATFORM)" != "X86")
-! error *** ERROR Unknown target platform "$(PLATFORM)". Make aborted.
-! endif
-! endif # !PLATFORM
-! endif
-!else # !PROCESSOR_ARCHITECTURE
-# We're on Windows 95
-CPU = i386
-!endif # !PROCESSOR_ARCHITECTURE
-ASSEMBLY_ARCHITECTURE=$(CPU)
+! elseif ("$(PLATFORM)" != "x86") && ("$(PLATFORM)" != "X86")
+! error *** ERROR Unknown target platform "$(PLATFORM)". Make aborted.
+! endif
+! endif # !PLATFORM
+!endif
OBJDIR = $(OBJDIR)$(CPU)
# Build a retail version by default
@@ -303,7 +302,9 @@ MAKEFLAGS_GVIMEXT = DEBUG=yes
LINK = link
# Check VC version.
-!if [echo MSVCVER=_MSC_VER> msvcver.c && $(CC) /EP msvcver.c > msvcver.~ 2> nul]
+!if [echo MSVCVER=_MSC_VER> msvcver.c && \
+ echo MSVC_FULL=_MSC_FULL_VER>> msvcver.c && \
+ $(CC) /EP msvcver.c > msvcver.~ 2> nul]
! message *** ERROR
! message Cannot run Visual C to determine its version. Make sure cl.exe is in your PATH.
! message This can usually be done by running "vcvarsall.bat", located in the bin directory where Visual Studio was installed.
@@ -324,19 +325,6 @@ LINK = link
MSVC_MAJOR = ($(MSVCVER) / 100 - 5)
MSVCRT_VER = ($(MSVCVER) / 100 * 10 - 50)
-# Calculate MSVC_FULL.
-!if [echo MSVC_FULL=_MSC_FULL_VER> msvcfullver.c && $(CC) /EP msvcfullver.c > msvcfullver.~ 2> nul]
-! message *** ERROR
-! message Cannot run Visual C to determine its version. Make sure cl.exe is in your PATH.
-! message This can usually be done by running "vcvarsall.bat", located in the bin directory where Visual Studio was installed.
-! error Make aborted.
-!else
-! include msvcfullver.~
-! if [del msvcfullver.c msvcfullver.~]
-! endif
-!endif
-
-
# Calculate MSVCRT_VER
!if [(set /a MSVCRT_VER="$(MSVCRT_VER)" > nul) && set MSVCRT_VER > msvcrtver.~] == 0
! include msvcrtver.~
@@ -344,6 +332,11 @@ MSVCRT_VER = ($(MSVCVER) / 100 * 10 - 50)
! endif
!endif
+# Show the versions (for debugging).
+#!message _MSC_VER=$(MSVCVER)
+#!message _MSC_FULL_VER=$(MSVC_FULL)
+#!message MSVCRT_VER=$(MSVCRT_VER)
+
# Base name of the msvcrXX.dll (vcruntimeXXX.dll)
MSVCRT_NAME = vcruntime$(MSVCRT_VER)
@@ -355,7 +348,7 @@ WINVER = 0x0601
# Use multiprocess build
USE_MP = yes
-!if "$(FEATURES)"==""
+!if "$(FEATURES)" == ""
FEATURES = HUGE
!endif
@@ -374,7 +367,7 @@ CSCOPE_DEFS = -DFEAT_CSCOPE
!endif
!ifndef TERMINAL
-! if "$(FEATURES)"=="HUGE"
+! if "$(FEATURES)" == "HUGE"
TERMINAL = yes
! else
TERMINAL = no
@@ -384,15 +377,15 @@ TERMINAL = no
!if "$(TERMINAL)" == "yes"
TERM_OBJ = \
$(OBJDIR)/terminal.obj \
- $(OBJDIR)/vterm_encoding.obj \
- $(OBJDIR)/vterm_keyboard.obj \
- $(OBJDIR)/vterm_mouse.obj \
- $(OBJDIR)/vterm_parser.obj \
- $(OBJDIR)/vterm_pen.obj \
- $(OBJDIR)/vterm_screen.obj \
- $(OBJDIR)/vterm_state.obj \
- $(OBJDIR)/vterm_unicode.obj \
- $(OBJDIR)/vterm_vterm.obj
+ $(OBJDIR)/libvterm/encoding.obj \
+ $(OBJDIR)/libvterm/keyboard.obj \
+ $(OBJDIR)/libvterm/mouse.obj \
+ $(OBJDIR)/libvterm/parser.obj \
+ $(OBJDIR)/libvterm/pen.obj \
+ $(OBJDIR)/libvterm/screen.obj \
+ $(OBJDIR)/libvterm/state.obj \
+ $(OBJDIR)/libvterm/unicode.obj \
+ $(OBJDIR)/libvterm/vterm.obj
TERM_DEFS = -DFEAT_TERMINAL
TERM_DEPS = \
libvterm/include/vterm.h \
@@ -403,7 +396,7 @@ TERM_DEPS = \
!endif
!ifndef SOUND
-! if "$(FEATURES)"=="HUGE"
+! if "$(FEATURES)" == "HUGE"
SOUND = yes
! else
SOUND = no
@@ -444,7 +437,7 @@ NETBEANS = $(GUI)
!endif
!ifndef CHANNEL
-! if "$(FEATURES)"=="HUGE" || "$(TERMINAL)"=="yes"
+! if "$(FEATURES)" == "HUGE" || "$(TERMINAL)" == "yes"
CHANNEL = yes
! else
CHANNEL = $(GUI)
@@ -538,9 +531,10 @@ CON_LIB = $(CON_LIB) /DELAYLOAD:comdlg32.dll /DELAYLOAD:ole32.dll DelayImp.lib
#VIMRUNTIMEDIR = somewhere
CFLAGS = -c /W3 /GF /nologo -I. -Iproto -DHAVE_PATHDEF -DWIN32 -DHAVE_STDINT_H \
- $(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \
+ $(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) \
$(NBDEBUG_DEFS) $(XPM_DEFS) $(SOD_DEFS) $(SOD_INC) \
- $(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) \
+ $(CHANNEL_DEFS) $(DEFINES) \
+ -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) \
/source-charset:utf-8
#>>>>> end of choices
@@ -548,41 +542,57 @@ CFLAGS = -c /W3 /GF /nologo -I. -Iproto -DHAVE_PATHDEF -DWIN32 -DHAVE_STDINT_H \
DEL_TREE = rmdir /s /q
-INTDIR=$(OBJDIR)
-OUTDIR=$(OBJDIR)
+INTDIR = $(OBJDIR)
+OUTDIR = $(OBJDIR)
### Validate CPUNR
-!ifndef CPUNR
+!if "$(CPU)" == "i386" || "$(CPU)" == "AMD64"
+! ifndef CPUNR
# default to SSE2
CPUNR = sse2
-!elseif "$(CPUNR)" == "i386" || "$(CPUNR)" == "i486" || "$(CPUNR)" == "i586"
+! elseif "$(CPU)" == "i386" \
+ && ("$(CPUNR)" == "i386" || "$(CPUNR)" == "i486" || "$(CPUNR)" == "i586")
# alias i386, i486 and i586 to i686
-! message *** WARNING CPUNR=$(CPUNR) is not a valid target architecture.
-! message Windows 7 is the minimum target OS, with a minimum target
-! message architecture of i686.
-! message Retargeting to i686
+! message *** WARNING CPUNR=$(CPUNR) is not a valid target architecture.
+! message Windows 7 is the minimum target OS, with a minimum target
+! message architecture of i686.
+! message Retargeting to i686
CPUNR = i686
-!elseif "$(CPUNR)" == "pentium4"
+! elseif "$(CPUNR)" == "pentium4"
# alias pentium4 to sse2
-! message *** WARNING CPUNR=pentium4 is deprecated in favour of sse2.
-! message Retargeting to sse2.
+! message *** WARNING CPUNR=pentium4 is deprecated in favour of sse2.
+! message Retargeting to sse2.
CPUNR = sse2
-!elseif "$(CPUNR)" != "any" && "$(CPUNR)" != "i686" && "$(CPUNR)" != "sse" && "$(CPUNR)" != "sse2" && "$(CPUNR)" != "avx" && "$(CPUNR)" != "avx2"
-! error *** ERROR Unknown target architecture "$(CPUNR)". Make aborted.
+! elseif ("$(CPU)" != "i386" \
+ || ("$(CPUNR)" != "any" && "$(CPUNR)" != "i686" \
+ && "$(CPUNR)" != "sse" )) \
+ && "$(CPUNR)" != "sse2" && "$(CPUNR)" != "avx" \
+ && "$(CPUNR)" != "avx2" && "$(CPUNR)" != "avx512"
+! error *** ERROR Unknown target architecture "$(CPUNR)". Make aborted.
+! endif
+!elseif "$(CPU)" == "ARM64"
+# TODO: Validate CPUNR.
!endif
# Convert processor ID to MVC-compatible number
+!if "$(CPU)" == "i386" || "$(CPU)" == "AMD64"
# IA32/SSE/SSE2 are only supported on x86
-!if "$(ASSEMBLY_ARCHITECTURE)" == "i386" && ("$(CPUNR)" == "i686" || "$(CPUNR)" == "any")
+! if "$(CPU)" == "i386" \
+ && ("$(CPUNR)" == "i686" || "$(CPUNR)" == "any")
CPUARG = /arch:IA32
-!elseif "$(ASSEMBLY_ARCHITECTURE)" == "i386" && "$(CPUNR)" == "sse"
+! elseif "$(CPU)" == "i386" && "$(CPUNR)" == "sse"
CPUARG = /arch:SSE
-!elseif "$(ASSEMBLY_ARCHITECTURE)" == "i386" && "$(CPUNR)" == "sse2"
+! elseif "$(CPU)" == "i386" && "$(CPUNR)" == "sse2"
CPUARG = /arch:SSE2
-!elseif "$(CPUNR)" == "avx"
+! elseif "$(CPUNR)" == "avx"
CPUARG = /arch:AVX
-!elseif "$(CPUNR)" == "avx2"
+! elseif "$(CPUNR)" == "avx2"
CPUARG = /arch:AVX2
+! elseif "$(CPUNR)" == "avx512"
+CPUARG = /arch:AVX512
+! endif
+!elseif "$(CPU)" == "ARM64" && defined(CPUNR)
+CPUARG = /arch:$(CPUNR)
!endif
# Pass CPUARG to GvimExt, to avoid using version-dependent defaults
@@ -590,7 +600,7 @@ MAKEFLAGS_GVIMEXT = $(MAKEFLAGS_GVIMEXT) CPUARG="$(CPUARG)"
!if "$(VIMDLL)" == "yes"
VIMDLLBASE = vim
-! if "$(ASSEMBLY_ARCHITECTURE)" == "i386"
+! if "$(CPU)" == "i386"
VIMDLLBASE = $(VIMDLLBASE)32
! else
VIMDLLBASE = $(VIMDLLBASE)64
@@ -797,6 +807,13 @@ OBJ = $(OBJ) $(OUTDIR)\os_w32dll.obj $(OUTDIR)\vimd.res
EXEOBJC = $(OUTDIR)\os_w32exec.obj $(OUTDIR)\vimc.res
EXEOBJG = $(OUTDIR)\os_w32exeg.obj $(OUTDIR)\vimg.res
CFLAGS = $(CFLAGS) -DVIMDLL
+! ifdef MZSCHEME
+EXECFLAGS =
+EXELIBC = $(LIBC)
+! else
+EXECFLAGS = -DUSE_OWNSTARTUP /GS-
+EXELIBC =
+! endif
!else
OBJ = $(OBJ) $(OUTDIR)\os_w32exe.obj $(OUTDIR)\vim.res
!endif
@@ -949,11 +966,9 @@ LUA_LIB = "$(LUA)\lib\lua$(LUA_VER).lib"
! endif
!endif
-!ifdef PYTHON
-! ifdef PYTHON3
-DYNAMIC_PYTHON=yes
-DYNAMIC_PYTHON3=yes
-! endif
+!if defined(PYTHON) && defined(PYTHON3)
+DYNAMIC_PYTHON = yes
+DYNAMIC_PYTHON3 = yes
!endif
# PYTHON interface
@@ -979,8 +994,13 @@ PYTHON_LIB = "$(PYTHON)\libs\python$(PYTHON_VER).lib"
# PYTHON3 interface
!ifdef PYTHON3
+! ifndef DYNAMIC_PYTHON3_STABLE_ABI
+! if "$(DYNAMIC_PYTHON3)" == "yes"
+DYNAMIC_PYTHON3_STABLE_ABI = yes
+! endif
+! endif
! ifndef PYTHON3_VER
-PYTHON3_VER = 36
+PYTHON3_VER = 38
! endif
! if "$(DYNAMIC_PYTHON3_STABLE_ABI)" == "yes"
PYTHON3_NAME = python3
@@ -1018,13 +1038,13 @@ PYTHON3_LIB = "$(PYTHON3)\libs\$(PYTHON3_NAME).lib"
MZSCHEME_VER = 3m_a0solc
! endif
! ifndef MZSCHEME_COLLECTS
-MZSCHEME_COLLECTS=$(MZSCHEME)\collects
+MZSCHEME_COLLECTS = $(MZSCHEME)\collects
! endif
CFLAGS = $(CFLAGS) -DFEAT_MZSCHEME -I "$(MZSCHEME)\include"
! if EXIST("$(MZSCHEME)\lib\msvc\libmzsch$(MZSCHEME_VER).lib")
-MZSCHEME_MAIN_LIB=mzsch
+MZSCHEME_MAIN_LIB = mzsch
! else
-MZSCHEME_MAIN_LIB=racket
+MZSCHEME_MAIN_LIB = racket
! endif
! if (EXIST("$(MZSCHEME)\lib\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).dll") \
&& !EXIST("$(MZSCHEME)\lib\libmzgc$(MZSCHEME_VER).dll")) \
@@ -1062,7 +1082,7 @@ MZSCHEME_LIB = "$(MZSCHEME)\lib\msvc\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).lib"
! endif
! else
MZSCHEME_LIB = "$(MZSCHEME)\lib\msvc\libmzgc$(MZSCHEME_VER).lib" \
- "$(MZSCHEME)\lib\msvc\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).lib"
+ "$(MZSCHEME)\lib\msvc\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).lib"
! endif
! endif
MZSCHEME_OBJ = $(OUTDIR)\if_mzsch.obj
@@ -1164,7 +1184,8 @@ RUBY_INSTALL_NAME = x64-$(RUBY_MSVCRT_NAME)-ruby$(RUBY_API_VER)
! message Ruby requested (version $(RUBY_VER)) - root dir is "$(RUBY)"
CFLAGS = $(CFLAGS) -DFEAT_RUBY
RUBY_OBJ = $(OUTDIR)\if_ruby.obj
-RUBY_INC = /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)" /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)\$(RUBY_PLATFORM)"
+RUBY_INC = /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)" \
+ /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)\$(RUBY_PLATFORM)"
RUBY_LIB = "$(RUBY)\lib\$(RUBY_INSTALL_NAME).lib"
# Do we want to load Ruby dynamically?
! if "$(DYNAMIC_RUBY)" == "yes"
@@ -1214,14 +1235,15 @@ LINK_PDB = /PDB:$(VIM).pdb -debug
!message
# CFLAGS with /Fo$(OUTDIR)/
-CFLAGS_OUTDIR=$(CFLAGS) /Fo$(OUTDIR)/
+CFLAGS_OUTDIR = $(CFLAGS) /Fo$(OUTDIR)/
PATHDEF_SRC = $(OUTDIR)\pathdef.c
LINKARGS1 = /nologo
LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(LIBC) $(OLE_LIB) \
- $(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \
- $(TCL_LIB) $(SOUND_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(SOD_LIB) $(LINK_PDB)
+ $(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) \
+ $(PYTHON3_LIB) $(RUBY_LIB) $(TCL_LIB) $(SOUND_LIB) \
+ $(NETBEANS_LIB) $(XPM_LIB) $(SOD_LIB) $(LINK_PDB)
!ifdef NODEBUG
# Add /opt:ref to remove unreferenced functions and data even when /DEBUG is
@@ -1281,36 +1303,40 @@ all: $(MAIN_TARGET) \
!if "$(VIMDLL)" == "yes"
-$(VIMDLLBASE).dll: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \
- $(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \
- $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \
- version.c version.h
+$(VIMDLLBASE).dll: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) \
+ $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) $(LUA_OBJ) $(PERL_OBJ) \
+ $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \
+ $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \
+ $(XPM_OBJ) version.c version.h
$(CC) $(CFLAGS_OUTDIR) version.c
$(LINK) @<<
-$(LINKARGS1) /dll -out:$(VIMDLLBASE).dll $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ)
-$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ)
-$(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ)
-$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2)
+$(LINKARGS1) /dll -out:$(VIMDLLBASE).dll $(OBJ) $(XDIFF_OBJ)
+$(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ)
+$(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ)
+$(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2)
<<
$(GVIM).exe: $(OUTDIR) $(EXEOBJG) $(VIMDLLBASE).dll
- $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(GVIM).exe $(EXEOBJG) $(VIMDLLBASE).lib $(LIBC)
+ $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(GVIM).exe \
+ $(EXEOBJG) $(VIMDLLBASE).lib $(EXELIBC)
$(VIM).exe: $(OUTDIR) $(EXEOBJC) $(VIMDLLBASE).dll
- $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM_CON) -out:$(VIM).exe $(EXEOBJC) $(VIMDLLBASE).lib $(LIBC)
+ $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM_CON) -out:$(VIM).exe \
+ $(EXEOBJC) $(VIMDLLBASE).lib $(EXELIBC)
!else
-$(VIM).exe: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \
- $(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \
- $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \
- version.c version.h
+$(VIM).exe: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) \
+ $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) $(LUA_OBJ) $(PERL_OBJ) \
+ $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \
+ $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \
+ $(XPM_OBJ) version.c version.h
$(CC) $(CFLAGS_OUTDIR) version.c
$(LINK) @<<
-$(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ)
-$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ)
-$(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ)
-$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2)
+$(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ)
+$(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ)
+$(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ)
+$(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2)
<<
!endif
@@ -1320,18 +1346,20 @@ $(VIM): $(VIM).exe
$(OUTDIR):
if not exist $(OUTDIR)/nul mkdir $(OUTDIR:/=\)
-CFLAGS_INST = /nologo /O2 -DNDEBUG -DWIN32 -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) $(CFLAGS_DEPR)
+$(OUTDIR)/libvterm: $(OUTDIR)
+ if not exist $(OUTDIR)/libvterm/nul mkdir $(OUTDIR:/=\)\libvterm
+
+CFLAGS_INST = /nologo /O2 -DNDEBUG -DWIN32 -DWINVER=$(WINVER) \
+ -D_WIN32_WINNT=$(WINVER) $(CFLAGS_DEPR)
!IFDEF PATCHLEVEL
-CFLAGS_INST= $(CFLAGS_INST) -DVIM_VERSION_PATCHLEVEL=$(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 \
+ $(CC) $(CFLAGS_INST) /Fe$@ dosinst.c kernel32.lib shell32.lib \
user32.lib ole32.lib advapi32.lib uuid.lib \
-link -subsystem:$(SUBSYSTEM_TOOLS)
- - if exist install.exe del install.exe
- ren dosinst.exe install.exe
uninstall.exe: uninstall.c dosinst.h version.h
$(CC) $(CFLAGS_INST) uninstall.c shell32.lib advapi32.lib \
@@ -1366,12 +1394,16 @@ clean: testclean
- if exist $(OUTDIR)/nul $(DEL_TREE) $(OUTDIR)
- if exist *.obj del *.obj
- if exist $(VIM).exe del $(VIM).exe
+ - if exist $(VIM).exp del $(VIM).exp
+ - if exist $(VIM).lib del $(VIM).lib
- if exist $(VIM).ilk del $(VIM).ilk
- if exist $(VIM).pdb del $(VIM).pdb
- if exist $(VIM).map del $(VIM).map
- if exist $(VIM).ncb del $(VIM).ncb
!if "$(VIMDLL)" == "yes"
- if exist $(GVIM).exe del $(GVIM).exe
+ - if exist $(GVIM).exp del $(GVIM).exp
+ - if exist $(GVIM).lib del $(GVIM).lib
- if exist $(GVIM).map del $(GVIM).map
- if exist $(VIMDLLBASE).dll del $(VIMDLLBASE).dll
- if exist $(VIMDLLBASE).ilk del $(VIMDLLBASE).ilk
@@ -1409,7 +1441,8 @@ cmdidxs: ex_cmds.h
# - change nv_cmds[] in nv_cmds.h to add the new normal/visual mode command.
# - run "make nvcmdidxs" to generate nv_cmdidxs.h
nvcmdidxs: nv_cmds.h
- $(CC) /nologo -I. -Iproto -DNDEBUG create_nvcmdidxs.c -link -subsystem:$(SUBSYSTEM_TOOLS)
+ $(CC) /nologo -I. -Iproto -DNDEBUG create_nvcmdidxs.c \
+ -link -subsystem:$(SUBSYSTEM_TOOLS)
vim --clean -N -X --not-a-term -u create_nvcmdidxs.vim -c quit
-del create_nvcmdidxs.exe
@@ -1420,7 +1453,7 @@ test:
testgvim testgui:
cd testdir
- $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\gvim
+ $(MAKE) /NOLOGO -f Make_mvc.mak "VIMPROG=..\gvim.exe"
cd ..
testtiny:
@@ -1430,7 +1463,7 @@ testtiny:
testgvimtiny:
cd testdir
- $(MAKE) /NOLOGO -f Make_mvc.mak tiny VIMPROG=..\gvim
+ $(MAKE) /NOLOGO -f Make_mvc.mak "VIMPROG=..\gvim.exe" tiny
cd ..
testclean:
@@ -1471,15 +1504,15 @@ test_vim9:
###########################################################################
# Create a default rule for transforming .c files to .obj files in $(OUTDIR)
-.c{$(OUTDIR)/}.obj::
+.c{$(OUTDIR)}.obj::
$(CC) $(CFLAGS_OUTDIR) $<
# Create a default rule for xdiff.
-{xdiff/}.c{$(OUTDIR)/}.obj::
+{xdiff}.c{$(OUTDIR)}.obj::
$(CC) $(CFLAGS_OUTDIR) $<
# Create a default rule for transforming .cpp files to .obj files in $(OUTDIR)
-.cpp{$(OUTDIR)/}.obj::
+.cpp{$(OUTDIR)}.obj::
$(CC) $(CFLAGS_OUTDIR) $<
$(OUTDIR)/alloc.obj: $(OUTDIR) alloc.c $(INCL)
@@ -1605,8 +1638,7 @@ $(OUTDIR)/if_cscope.obj: $(OUTDIR) if_cscope.c $(INCL)
$(OUTDIR)/if_lua.obj: $(OUTDIR) if_lua.c $(INCL)
$(CC) $(CFLAGS_OUTDIR) $(LUA_INC) if_lua.c
-auto/if_perl.c : if_perl.xs typemap
- -if not exist auto/nul mkdir auto
+auto/if_perl.c: if_perl.xs typemap
$(XSUBPP) -prototypes -typemap $(XSUBPP_TYPEMAP) \
-typemap typemap if_perl.xs -output $@
@@ -1638,7 +1670,6 @@ $(OUTDIR)/if_tcl.obj: $(OUTDIR) if_tcl.c $(INCL)
$(CC) $(CFLAGS_OUTDIR) $(TCL_INC) if_tcl.c
$(OUTDIR)/iscygpty.obj: $(OUTDIR) iscygpty.c $(CUI_INCL)
- $(CC) $(CFLAGS_OUTDIR) iscygpty.c
$(OUTDIR)/job.obj: $(OUTDIR) job.c $(INCL)
@@ -1701,10 +1732,10 @@ $(OUTDIR)/os_w32dll.obj: $(OUTDIR) os_w32dll.c
$(OUTDIR)/os_w32exe.obj: $(OUTDIR) os_w32exe.c $(INCL)
$(OUTDIR)/os_w32exec.obj: $(OUTDIR) os_w32exe.c $(INCL)
- $(CC) $(CFLAGS:-DFEAT_GUI_MSWIN=) /Fo$@ os_w32exe.c
+ $(CC) $(CFLAGS:-DFEAT_GUI_MSWIN=) $(EXECFLAGS) /Fo$@ os_w32exe.c
$(OUTDIR)/os_w32exeg.obj: $(OUTDIR) os_w32exe.c $(INCL)
- $(CC) $(CFLAGS) /Fo$@ os_w32exe.c
+ $(CC) $(CFLAGS) $(EXECFLAGS) /Fo$@ os_w32exe.c
$(OUTDIR)/pathdef.obj: $(OUTDIR) $(PATHDEF_SRC) $(INCL)
$(CC) $(CFLAGS_OUTDIR) $(PATHDEF_SRC)
@@ -1804,7 +1835,8 @@ $(OUTDIR)/vimg.res: $(OUTDIR) vim.rc vim.manifest version.h gui_w32_rc.h \
$(OUTDIR)/vimd.res: $(OUTDIR) vim.rc version.h gui_w32_rc.h \
tools.bmp tearoff.bmp vim.ico vim_error.ico \
vim_alert.ico vim_info.ico vim_quest.ico
- $(RC) /nologo /l 0x409 /Fo$@ $(RCFLAGS) -DRCDLL -DVIMDLLBASE=\"$(VIMDLLBASE)\" vim.rc
+ $(RC) /nologo /l 0x409 /Fo$@ $(RCFLAGS) \
+ -DRCDLL -DVIMDLLBASE=\"$(VIMDLLBASE)\" vim.rc
!else
$(OUTDIR)/vim.res: $(OUTDIR) vim.rc vim.manifest version.h gui_w32_rc.h \
tools.bmp tearoff.bmp vim.ico vim_error.ico \
@@ -1825,32 +1857,27 @@ CCCTERM = $(CC) $(CFLAGS) -Ilibvterm/include -DINLINE="" \
-DGET_SPECIAL_PTY_TYPE_FUNCTION=get_special_pty_type \
-D_CRT_SECURE_NO_WARNINGS
-$(OUTDIR)/vterm_encoding.obj: $(OUTDIR) libvterm/src/encoding.c $(TERM_DEPS)
- $(CCCTERM) /Fo$@ libvterm/src/encoding.c
+# Create a default rule for vterm.
+{libvterm/src}.c{$(OUTDIR)/libvterm}.obj::
+ $(CCCTERM) /Fo$(OUTDIR)/libvterm/ $<
+
+$(OUTDIR)/libvterm/encoding.obj: $(OUTDIR)/libvterm libvterm/src/encoding.c $(TERM_DEPS)
-$(OUTDIR)/vterm_keyboard.obj: $(OUTDIR) libvterm/src/keyboard.c $(TERM_DEPS)
- $(CCCTERM) /Fo$@ libvterm/src/keyboard.c
+$(OUTDIR)/libvterm/keyboard.obj: $(OUTDIR)/libvterm libvterm/src/keyboard.c $(TERM_DEPS)
-$(OUTDIR)/vterm_mouse.obj: $(OUTDIR) libvterm/src/mouse.c $(TERM_DEPS)
- $(CCCTERM) /Fo$@ libvterm/src/mouse.c
+$(OUTDIR)/libvterm/mouse.obj: $(OUTDIR)/libvterm libvterm/src/mouse.c $(TERM_DEPS)
-$(OUTDIR)/vterm_parser.obj: $(OUTDIR) libvterm/src/parser.c $(TERM_DEPS)
- $(CCCTERM) /Fo$@ libvterm/src/parser.c
+$(OUTDIR)/libvterm/parser.obj: $(OUTDIR)/libvterm libvterm/src/parser.c $(TERM_DEPS)
-$(OUTDIR)/vterm_pen.obj: $(OUTDIR) libvterm/src/pen.c $(TERM_DEPS)
- $(CCCTERM) /Fo$@ libvterm/src/pen.c
+$(OUTDIR)/libvterm/pen.obj: $(OUTDIR)/libvterm libvterm/src/pen.c $(TERM_DEPS)
-$(OUTDIR)/vterm_screen.obj: $(OUTDIR) libvterm/src/screen.c $(TERM_DEPS)
- $(CCCTERM) /Fo$@ libvterm/src/screen.c
+$(OUTDIR)/libvterm/screen.obj: $(OUTDIR)/libvterm libvterm/src/screen.c $(TERM_DEPS)
-$(OUTDIR)/vterm_state.obj: $(OUTDIR) libvterm/src/state.c $(TERM_DEPS)
- $(CCCTERM) /Fo$@ libvterm/src/state.c
+$(OUTDIR)/libvterm/state.obj: $(OUTDIR)/libvterm libvterm/src/state.c $(TERM_DEPS)
-$(OUTDIR)/vterm_unicode.obj: $(OUTDIR) libvterm/src/unicode.c $(TERM_DEPS)
- $(CCCTERM) /Fo$@ libvterm/src/unicode.c
+$(OUTDIR)/libvterm/unicode.obj: $(OUTDIR)/libvterm libvterm/src/unicode.c $(TERM_DEPS)
-$(OUTDIR)/vterm_vterm.obj: $(OUTDIR) libvterm/src/vterm.c $(TERM_DEPS)
- $(CCCTERM) /Fo$@ libvterm/src/vterm.c
+$(OUTDIR)/libvterm/vterm.obj: $(OUTDIR)/libvterm libvterm/src/vterm.c $(TERM_DEPS)
# $CFLAGS may contain backslashes, quotes and chevrons, escape them all.
diff --git a/src/Makefile b/src/Makefile
index 71578eb..257742f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2189,7 +2189,7 @@ test check: unittests $(TERM_TEST) scripttests
scripttests:
$(MAKE) -f Makefile $(VIMTARGET)
if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \
- cd $(PODIR); $(MAKE) -f Makefile check VIM=../$(VIMTARGET); \
+ cd $(PODIR); $(MAKE) -f Makefile check VIMPROG=../$(VIMTARGET); \
fi
-if test $(VIMTARGET) != vim -a ! -r vim; then \
ln -s $(VIMTARGET) vim; \
@@ -2354,10 +2354,8 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(VIMTARGET) $(DEST_RT) \
cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)" -a -f tags; then \
mv -f tags tags.dist; fi
@echo generating help tags
- # We can assume Vim was build, but it may not have been installed,
- # thus use the executable in the current directory.
- -@BUILD_DIR="`pwd`"; cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)"; then \
- $(MAKE) VIMEXE="$$BUILD_DIR/$(VIMTARGET)" vimtags; fi
+ -@BUILD_DIR=`pwd`; cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)"; then \
+ $(MAKE) VIMPROG="$$BUILD_DIR/$(VIMTARGET)" vimtags; fi
cd $(HELPSOURCE); \
files=`ls *.txt tags`; \
files="$$files `ls *.??x tags-?? 2>/dev/null || true`"; \
@@ -2626,7 +2624,7 @@ ICONTHEMEPATH = $(DATADIR)/icons/hicolor
DESKTOPPATH = $(DESTDIR)$(DATADIR)/applications
KDEPATH = $(HOME)/.kde/share/icons
install-icons:
- if test -n "$(DESTDIR)"; then \
+ if test -n "$(DESTDIR)$(DATADIR)"; then \
$(MKDIR_P) $(ICON48PATH) $(ICON32PATH) \
$(ICON16PATH) $(DESKTOPPATH); \
fi
@@ -2847,6 +2845,8 @@ uninstall_runtime:
-rm -f $(SYS_OPTWIN_FILE)
-rm -f $(DEST_COL)/*.vim $(DEST_COL)/README.txt
-rm -rf $(DEST_COL)/tools
+ -rm -f $(DESKTOPPATH)/vim.desktop $(DESKTOPPATH)/gvim.desktop
+ -rm -f $(ICON16PATH)/gvim.png $(ICON32PATH)/gvim.png $(ICON48PATH)/gvim.png
-rm -rf $(DEST_COL)/lists
-rm -f $(DEST_SYN)/shared/*.vim $(DEST_SYN)/shared/README.txt
-rm -f $(DEST_SYN)/modula2/opt/*.vim
diff --git a/src/arglist.c b/src/arglist.c
index 187e16e..8825c8e 100644
--- a/src/arglist.c
+++ b/src/arglist.c
@@ -184,6 +184,8 @@ alist_set(
/*
* Add file "fname" to argument list "al".
* "fname" must have been allocated and "al" must have been checked for room.
+ *
+ * May trigger Buf* autocommands
*/
void
alist_add(
@@ -196,6 +198,7 @@ alist_add(
if (check_arglist_locked() == FAIL)
return;
arglist_locked = TRUE;
+ curwin->w_locked = TRUE;
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(fname);
@@ -207,6 +210,7 @@ alist_add(
++al->al_ga.ga_len;
arglist_locked = FALSE;
+ curwin->w_locked = FALSE;
}
#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
@@ -365,6 +369,7 @@ alist_add_list(
mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]),
(ARGCOUNT - after) * sizeof(aentry_T));
arglist_locked = TRUE;
+ curwin->w_locked = TRUE;
for (i = 0; i < count; ++i)
{
int flags = BLN_LISTED | (will_edit ? BLN_CURBUF : 0);
@@ -373,6 +378,7 @@ alist_add_list(
ARGLIST[after + i].ae_fnum = buflist_add(files[i], flags);
}
arglist_locked = FALSE;
+ curwin->w_locked = FALSE;
ALIST(curwin)->al_ga.ga_len += count;
if (old_argcount > 0 && curwin->w_arg_idx >= after)
curwin->w_arg_idx += count;
diff --git a/src/auto/configure b/src/auto/configure
index 98b9580..4a99071 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -1575,7 +1575,7 @@ Optional Packages:
--with-python-command=NAME name of the Python 2 command (default: python2 or python)
--with-python-config-dir=PATH Python's config directory (deprecated)
--with-python3-command=NAME name of the Python 3 command (default: python3 or python)
- --with-python3-stable-abi=VERSION stable ABI version to target (e.g. 3.8)
+ --with-python3-stable-abi=VERSION stable ABI version to target (default: 3.8)
--with-python3-config-dir=PATH Python's config directory (deprecated)
--with-tclsh=PATH which tclsh to use (default: tclsh8.0)
--with-ruby-command=RUBY name of the Ruby command (default: ruby)
@@ -7083,14 +7083,21 @@ printf %s "checking Python is 3.0 or better... " >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yep" >&5
printf "%s\n" "yep" >&6; }
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --with-python3-stable-abi argument" >&5
+ python3_stable_abi_default=3.8
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --with-python3-stable-abi argument" >&5
printf %s "checking --with-python3-stable-abi argument... " >&6; }
# Check whether --with-python3-stable-abi was given.
if test ${with_python3_stable_abi+y}
then :
- withval=$with_python3_stable_abi; vi_cv_var_python3_stable_abi="$withval"; { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $vi_cv_var_python3_stable_abi" >&5
+ withval=$with_python3_stable_abi;
+ if test "X$withval" = "Xyes"; then
+ vi_cv_var_python3_stable_abi=$python3_stable_abi_default
+ else
+ vi_cv_var_python3_stable_abi="$withval"
+ fi
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $vi_cv_var_python3_stable_abi" >&5
printf "%s\n" "$vi_cv_var_python3_stable_abi" >&6; }
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
@@ -15876,6 +15883,30 @@ then :
fi
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dgettext" >&5
+printf %s "checking for dgettext... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <libintl.h>
+int
+main (void)
+{
+dgettext("Test", "Test");
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }; printf "%s\n" "#define HAVE_DGETTEXT 1" >>confdefs.h
+
+else $as_nop
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _nl_msg_cat_cntr" >&5
printf %s "checking for _nl_msg_cat_cntr... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
diff --git a/src/autocmd.c b/src/autocmd.c
index 8380f8a..00f41bd 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -120,6 +120,7 @@ static keyvalue_T event_tab[] = {
KEYVALUE_ENTRY(EVENT_CURSORHOLD, "CursorHold"),
KEYVALUE_ENTRY(EVENT_CURSORHOLDI, "CursorHoldI"),
KEYVALUE_ENTRY(EVENT_CURSORMOVED, "CursorMoved"),
+ KEYVALUE_ENTRY(EVENT_CURSORMOVEDC, "CursorMovedC"),
KEYVALUE_ENTRY(EVENT_CURSORMOVEDI, "CursorMovedI"),
KEYVALUE_ENTRY(EVENT_DIFFUPDATED, "DiffUpdated"),
KEYVALUE_ENTRY(EVENT_DIRCHANGED, "DirChanged"),
@@ -154,6 +155,7 @@ static keyvalue_T event_tab[] = {
KEYVALUE_ENTRY(EVENT_INSERTENTER, "InsertEnter"),
KEYVALUE_ENTRY(EVENT_INSERTLEAVE, "InsertLeave"),
KEYVALUE_ENTRY(EVENT_INSERTLEAVEPRE, "InsertLeavePre"),
+ KEYVALUE_ENTRY(EVENT_KEYINPUTPRE, "KeyInputPre"),
KEYVALUE_ENTRY(EVENT_MENUPOPUP, "MenuPopup"),
KEYVALUE_ENTRY(EVENT_MODECHANGED, "ModeChanged"),
KEYVALUE_ENTRY(EVENT_OPTIONSET, "OptionSet"),
@@ -2021,6 +2023,15 @@ has_insertcharpre(void)
}
/*
+ * Return TRUE when there is an KeyInputPre autocommand defined.
+ */
+ int
+has_keyinputpre(void)
+{
+ return (first_autopat[(int)EVENT_KEYINPUTPRE] != NULL);
+}
+
+/*
* Return TRUE when there is an CmdUndefined autocommand defined.
*/
int
@@ -2250,10 +2261,12 @@ apply_autocmds_group(
|| event == EVENT_CMDLINECHANGED
|| event == EVENT_CMDLINEENTER
|| event == EVENT_CMDLINELEAVE
+ || event == EVENT_CURSORMOVEDC
|| event == EVENT_CMDWINENTER
|| event == EVENT_CMDWINLEAVE
|| event == EVENT_CMDUNDEFINED
|| event == EVENT_FUNCUNDEFINED
+ || event == EVENT_KEYINPUTPRE
|| event == EVENT_REMOTEREPLY
|| event == EVENT_SPELLFILEMISSING
|| event == EVENT_QUICKFIXCMDPRE
diff --git a/src/buffer.c b/src/buffer.c
index cbec9b9..34500e4 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -50,6 +50,7 @@ static void free_buffer(buf_T *);
static void free_buffer_stuff(buf_T *buf, int free_options);
static int bt_nofileread(buf_T *buf);
static void no_write_message_buf(buf_T *buf);
+static int do_buffer_ext(int action, int start, int dir, int count, int flags);
#ifdef UNIX
# define dev_T dev_t
@@ -750,10 +751,16 @@ aucmd_abort:
*/
if (wipe_buf)
{
+ tabpage_T *tp;
+ win_T *wp;
+
// Do not wipe out the buffer if it is used in a window.
if (buf->b_nwindows > 0)
return FALSE;
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ mark_forget_file(wp, buf->b_fnum);
+
if (action == DOBUF_WIPE_REUSE)
{
// we can re-use this buffer number, store it
@@ -1100,13 +1107,30 @@ goto_buffer(
{
bufref_T old_curbuf;
int save_sea = swap_exists_action;
+ int skip_help_buf;
+
+ switch (eap->cmdidx)
+ {
+ case CMD_bnext:
+ case CMD_sbnext:
+ case CMD_bNext:
+ case CMD_bprevious:
+ case CMD_sbNext:
+ case CMD_sbprevious:
+ skip_help_buf = TRUE;
+ break;
+ default:
+ skip_help_buf = FALSE;
+ break;
+ }
set_bufref(&old_curbuf, curbuf);
if (swap_exists_action == SEA_NONE)
swap_exists_action = SEA_DIALOG;
- (void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
- start, dir, count, eap->forceit);
+ (void)do_buffer_ext(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO, start, dir, count,
+ (eap->forceit ? DOBUF_FORCEIT : 0) |
+ (skip_help_buf ? DOBUF_SKIPHELP : 0));
if (swap_exists_action == SEA_QUIT && *eap->cmd == 's')
{
#if defined(FEAT_EVAL)
@@ -1337,8 +1361,11 @@ do_buffer_ext(
if (buf == NULL)
buf = lastbuf;
}
- // don't count unlisted buffers
- if (unload || buf->b_p_bl)
+ // Don't count unlisted buffers.
+ // Avoid non-help buffers if the starting point was a non-help buffer and
+ // vice-versa.
+ if (unload || (buf->b_p_bl
+ && ((flags & DOBUF_SKIPHELP) == 0 || buf->b_help == bp->b_help)))
{
--count;
bp = NULL; // use this buffer as new starting point
@@ -1457,7 +1484,7 @@ do_buffer_ext(
// (unless it's the only window). Repeat this so long as we end up in
// a window with this buffer.
while (buf == curbuf
- && !(curwin->w_closing || curwin->w_buffer->b_locked > 0)
+ && !(win_locked(curwin) || curwin->w_buffer->b_locked > 0)
&& (!ONE_WINDOW || first_tabpage->tp_next != NULL))
{
if (win_close(curwin, FALSE) == FAIL)
@@ -5443,7 +5470,7 @@ ex_buffer_all(exarg_T *eap)
: wp->w_width != Columns)
|| (had_tab > 0 && wp != firstwin))
&& !ONE_WINDOW
- && !(wp->w_closing || wp->w_buffer->b_locked > 0)
+ && !(win_locked(wp) || wp->w_buffer->b_locked > 0)
&& !win_unlisted(wp))
{
if (win_close(wp, FALSE) == FAIL)
diff --git a/src/bufwrite.c b/src/bufwrite.c
index c9d9875..23cd884 100644
--- a/src/bufwrite.c
+++ b/src/bufwrite.c
@@ -1350,7 +1350,7 @@ buf_write(
p = copybuf + STRLEN(copybuf);
if (after_pathsep(copybuf, p) && p[-1] == p[-2])
// Ends with '//', use full path
- if ((p = make_percent_swname(copybuf, fname)) != NULL)
+ if ((p = make_percent_swname(copybuf, p, fname)) != NULL)
{
backup = modname(p, backup_ext, FALSE);
vim_free(p);
@@ -1564,7 +1564,7 @@ buf_write(
p = IObuff + STRLEN(IObuff);
if (after_pathsep(IObuff, p) && p[-1] == p[-2])
// path ends with '//', use full path
- if ((p = make_percent_swname(IObuff, fname)) != NULL)
+ if ((p = make_percent_swname(IObuff, p, fname)) != NULL)
{
backup = modname(p, backup_ext, FALSE);
vim_free(p);
diff --git a/src/change.c b/src/change.c
index dacc06f..72d01c5 100644
--- a/src/change.c
+++ b/src/change.c
@@ -1355,17 +1355,17 @@ del_bytes(
mch_memmove(newp + col, oldp + col + count, (size_t)movelen);
if (alloc_newp)
ml_replace(lnum, newp, FALSE);
-#ifdef FEAT_PROP_POPUP
else
{
+#ifdef FEAT_PROP_POPUP
// Also move any following text properties.
if (oldlen + 1 < curbuf->b_ml.ml_line_len)
mch_memmove(newp + newlen + 1, oldp + oldlen + 1,
(size_t)curbuf->b_ml.ml_line_len - oldlen - 1);
+#endif
curbuf->b_ml.ml_line_len -= count;
curbuf->b_ml.ml_line_textlen = 0;
}
-#endif
// mark the buffer as changed and prepare for displaying
inserted_bytes(lnum, col, -count);
diff --git a/src/channel.c b/src/channel.c
index b99b3a9..69bbff2 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -2277,7 +2277,7 @@ channel_parse_json(channel_T *channel, ch_part_T part)
{
int timeout;
#ifdef MSWIN
- timeout = GetTickCount() > chanpart->ch_deadline;
+ timeout = (int)(GetTickCount() - chanpart->ch_deadline) > 0;
#else
{
struct timeval now_tv;
diff --git a/src/charset.c b/src/charset.c
index 9aa402a..19b0895 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -827,20 +827,20 @@ linetabsize_no_outer(win_T *wp, linenr_T lnum)
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);
+ 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);
@@ -1397,17 +1397,17 @@ win_lbr_chartabsize(
else if (max_head_vcol > vcol + head_prev + prev_rem)
head += (max_head_vcol - (vcol + head_prev + prev_rem)
+ width2 - 1) / width2 * head_mid;
-# ifdef FEAT_PROP_POPUP
else if (max_head_vcol < 0)
{
- int off = 0;
+ int off = mb_added;
+# ifdef FEAT_PROP_POPUP
if (*s != NUL
&& ((State & MODE_NORMAL) || cts->cts_start_incl))
off += cts->cts_cur_text_width;
+# endif
if (off >= prev_rem)
head += (1 + (off - prev_rem) / width) * head_mid;
}
-# endif
}
}
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 8d8bf06..c1ed03b 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -46,6 +46,7 @@ cmdline_fuzzy_completion_supported(expand_T *xp)
&& xp->xp_context != EXPAND_COLORS
&& xp->xp_context != EXPAND_COMPILER
&& xp->xp_context != EXPAND_DIRECTORIES
+ && xp->xp_context != EXPAND_DIRS_IN_CDPATH
&& xp->xp_context != EXPAND_FILES
&& xp->xp_context != EXPAND_FILES_IN_PATH
&& xp->xp_context != EXPAND_FILETYPE
@@ -107,7 +108,8 @@ wildescape(
|| xp->xp_context == EXPAND_FILES_IN_PATH
|| xp->xp_context == EXPAND_SHELLCMD
|| xp->xp_context == EXPAND_BUFFERS
- || xp->xp_context == EXPAND_DIRECTORIES)
+ || xp->xp_context == EXPAND_DIRECTORIES
+ || xp->xp_context == EXPAND_DIRS_IN_CDPATH)
{
// Insert a backslash into a file name before a space, \, %, #
// and wildmatch characters, except '~'.
@@ -357,6 +359,7 @@ cmdline_pum_create(
compl_match_array[i].pum_info = NULL;
compl_match_array[i].pum_extra = NULL;
compl_match_array[i].pum_kind = NULL;
+ compl_match_array[i].pum_user_hlattr = -1;
}
// Compute the popup menu starting column
@@ -1404,7 +1407,8 @@ addstar(
if (context != EXPAND_FILES
&& context != EXPAND_FILES_IN_PATH
&& context != EXPAND_SHELLCMD
- && context != EXPAND_DIRECTORIES)
+ && context != EXPAND_DIRECTORIES
+ && context != EXPAND_DIRS_IN_CDPATH)
{
// Matching will be done internally (on something other than files).
// So we convert the file-matching-type wildcards into our kind for
@@ -2138,7 +2142,7 @@ set_context_by_cmdname(
case CMD_lcd:
case CMD_lchdir:
if (xp->xp_context == EXPAND_FILES)
- xp->xp_context = EXPAND_DIRECTORIES;
+ xp->xp_context = EXPAND_DIRS_IN_CDPATH;
break;
case CMD_help:
xp->xp_context = EXPAND_HELP;
@@ -2845,6 +2849,8 @@ expand_files_and_dirs(
flags |= EW_FILE;
else if (xp->xp_context == EXPAND_FILES_IN_PATH)
flags |= (EW_FILE | EW_PATH);
+ else if (xp->xp_context == EXPAND_DIRS_IN_CDPATH)
+ flags = (flags | EW_DIR | EW_CDPATH) & ~EW_FILE;
else
flags = (flags | EW_DIR) & ~EW_FILE;
if (options & WILD_ICASE)
@@ -3098,7 +3104,8 @@ ExpandFromContext(
if (xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_DIRECTORIES
- || xp->xp_context == EXPAND_FILES_IN_PATH)
+ || xp->xp_context == EXPAND_FILES_IN_PATH
+ || xp->xp_context == EXPAND_DIRS_IN_CDPATH)
return expand_files_and_dirs(xp, pat, matches, numMatches, flags,
options);
diff --git a/src/config.h.in b/src/config.h.in
index 8ad9f03..530c082 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -222,7 +222,6 @@
#undef HAVE_UNSETENV
#undef HAVE_USLEEP
#undef HAVE_UTIME
-#undef HAVE_BIND_TEXTDOMAIN_CODESET
#undef HAVE_MBLEN
#undef HAVE_TIMER_CREATE
#undef HAVE_CLOCK_GETTIME
@@ -424,6 +423,12 @@
/* Define if there is a working gettext(). */
#undef HAVE_GETTEXT
+/* Define if there is a working bind_textdomain_codeset(). */
+#undef HAVE_BIND_TEXTDOMAIN_CODESET
+
+/* Define if there is a working dgettext(). */
+#undef HAVE_DGETTEXT
+
/* Define if _nl_msg_cat_cntr is present. */
#undef HAVE_NL_MSG_CAT_CNTR
diff --git a/src/configure.ac b/src/configure.ac
index 946fe52..233e907 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1539,11 +1539,18 @@ if test "$enable_python3interp" = "yes" -o "$enable_python3interp" = "dynamic";
AC_MSG_RESULT(yep)
dnl -- get the stable ABI version if passed in
+ python3_stable_abi_default=3.8
AC_MSG_CHECKING(--with-python3-stable-abi argument)
AC_SUBST(vi_cv_var_python3_stable_abi)
- AC_ARG_WITH(python3-stable-abi, [ --with-python3-stable-abi=VERSION stable ABI version to target (e.g. 3.8)],
- vi_cv_var_python3_stable_abi="$withval"; AC_MSG_RESULT($vi_cv_var_python3_stable_abi),
- AC_MSG_RESULT(no))
+ AC_ARG_WITH(python3-stable-abi, [ --with-python3-stable-abi=VERSION stable ABI version to target (default: 3.8)],
+ [
+ if test "X$withval" = "Xyes"; then
+ vi_cv_var_python3_stable_abi=$python3_stable_abi_default
+ else
+ vi_cv_var_python3_stable_abi="$withval"
+ fi
+ AC_MSG_RESULT($vi_cv_var_python3_stable_abi)],
+ AC_MSG_RESULT(no))
if test "X$vi_cv_var_python3_stable_abi" != "X"; then
AC_CACHE_VAL(vi_cv_var_python3_stable_abi_hex,
[
@@ -4497,6 +4504,12 @@ if test "$enable_nls" = "yes"; then
AC_SUBST(MAKEMO)
dnl this was added in GNU gettext 0.10.36
AC_CHECK_FUNCS(bind_textdomain_codeset)
+ AC_MSG_CHECKING([for dgettext])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [#include <libintl.h>],
+ [dgettext("Test", "Test");])],
+ AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_DGETTEXT),
+ AC_MSG_RESULT([no]))
dnl _nl_msg_cat_cntr is required for GNU gettext
AC_MSG_CHECKING([for _nl_msg_cat_cntr])
AC_LINK_IFELSE([AC_LANG_PROGRAM(
diff --git a/src/dict.c b/src/dict.c
index bf45b0b..d3636f3 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -1222,8 +1222,7 @@ dict_lookup(hashitem_T *hi)
dict_equal(
dict_T *d1,
dict_T *d2,
- int ic, // ignore case for strings
- int recursive) // TRUE when used recursively
+ int ic) // ignore case for strings
{
hashitem_T *hi;
dictitem_T *item2;
@@ -1247,7 +1246,7 @@ dict_equal(
item2 = dict_find(d2, hi->hi_key, -1);
if (item2 == NULL)
return FALSE;
- if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive))
+ if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic))
return FALSE;
--todo;
}
@@ -1275,7 +1274,7 @@ dict_count(dict_T *d, typval_T *needle, int ic)
if (!HASHITEM_EMPTY(hi))
{
--todo;
- if (tv_equal(&HI2DI(hi)->di_tv, needle, ic, FALSE))
+ if (tv_equal(&HI2DI(hi)->di_tv, needle, ic))
++n;
}
}
diff --git a/src/edit.c b/src/edit.c
index e75a1cf..8a37a61 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -2849,7 +2849,6 @@ cursor_down_inner(win_T *wp, long n)
// count each sequence of folded lines as one logical line
while (n--)
{
- // Move to last line of fold, will fail if it's the end-of-file.
if (hasFoldingWin(wp, lnum, NULL, &last, TRUE, NULL))
lnum = last + 1;
else
@@ -2877,8 +2876,11 @@ cursor_down(
{
linenr_T lnum = curwin->w_cursor.lnum;
linenr_T line_count = curwin->w_buffer->b_ml.ml_line_count;
- // This fails if the cursor is already in the last line or would move
- // beyond the last line and '-' is in 'cpoptions'
+ // This fails if the cursor is already in the last (folded) line, or would
+ // move beyond the last line and '-' is in 'cpoptions'.
+#ifdef FEAT_FOLDING
+ hasFoldingWin(curwin, lnum, NULL, &lnum, TRUE, NULL);
+#endif
if (n > 0
&& (lnum >= line_count
|| (lnum + n > line_count
diff --git a/src/errors.h b/src/errors.h
index 4387a29..03b3c08 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -1038,8 +1038,10 @@ EXTERN char e_missing_argument_str[]
INIT(= N_("E417: Missing argument: %s"));
EXTERN char e_illegal_value_str[]
INIT(= N_("E418: Illegal value: %s"));
+#ifdef FEAT_EVAL
EXTERN char e_im_a_teapot[]
INIT(= N_("E418: I'm a teapot"));
+#endif
EXTERN char e_fg_color_unknown[]
INIT(= N_("E419: FG color unknown"));
EXTERN char e_bg_color_unknown[]
@@ -1273,8 +1275,10 @@ EXTERN char e_is_not_file_or_writable_device[]
INIT(= N_("is not a file or writable device"));
EXTERN char e_str_is_not_file_or_writable_device[]
INIT(= N_("E503: \"%s\" is not a file or writable device"));
+#ifdef FEAT_EVAL
EXTERN char e_coffee_currently_not_available[]
INIT(= N_("E503: Coffee is currently not available"));
+#endif
// E504
EXTERN char e_is_read_only_cannot_override_W_in_cpoptions[]
INIT(= N_("is read-only (cannot override: \"W\" in 'cpoptions')"));
@@ -1571,11 +1575,12 @@ EXTERN char e_too_many_signs_defined[]
EXTERN char e_unknown_printer_font_str[]
INIT(= N_("E613: Unknown printer font: %s"));
#endif
-EXTERN char e_class_required[]
- INIT(= N_("E614: Class required"));
+// E614 unused (deleted)
// E615 unused
+#ifdef FEAT_EVAL
EXTERN char e_object_required_for_argument_nr[]
INIT(= N_("E616: Object required for argument %d"));
+#endif
#ifdef FEAT_GUI_GTK
EXTERN char e_cannot_be_changed_in_gtk_GUI[]
INIT(= N_("E617: Cannot be changed in the GTK GUI"));
@@ -3315,8 +3320,10 @@ EXTERN char e_could_not_check_for_pending_sigalrm_str[]
#ifdef FEAT_EVAL
EXTERN char e_substitute_nesting_too_deep[]
INIT(= N_("E1290: substitute nesting too deep"));
+# ifdef MSWIN
EXTERN char e_invalid_argument_nr[]
INIT(= N_("E1291: Invalid argument: %ld"));
+# endif
#endif
EXTERN char e_cmdline_window_already_open[]
INIT(= N_("E1292: Command-line window is already open"));
@@ -3387,16 +3394,13 @@ EXTERN char e_invalid_object_variable_declaration_str[]
INIT(= N_("E1317: Invalid object variable declaration: %s"));
EXTERN char e_not_valid_command_in_class_str[]
INIT(= N_("E1318: Not a valid command in a class: %s"));
-EXTERN char e_using_class_as_number[]
- INIT(= N_("E1319: Using a Class as a Number"));
+// E1319 unused
EXTERN char e_using_object_as_number[]
INIT(= N_("E1320: Using an Object as a Number"));
-EXTERN char e_using_class_as_float[]
- INIT(= N_("E1321: Using a Class as a Float"));
+// E1321 unused
EXTERN char e_using_object_as_float[]
INIT(= N_("E1322: Using an Object as a Float"));
-EXTERN char e_using_class_as_string[]
- INIT(= N_("E1323: Using a Class as a String"));
+// E1323 unused
EXTERN char e_using_object_as_string[]
INIT(= N_("E1324: Using an Object as a String"));
EXTERN char e_method_not_found_on_class_str_str[]
@@ -3547,8 +3551,7 @@ EXTERN char e_type_can_only_be_defined_in_vim9_script[]
INIT(= N_("E1393: Type can only be defined in Vim9 script"));
EXTERN char e_type_name_must_start_with_uppercase_letter_str[]
INIT(= N_("E1394: Type name must start with an uppercase letter: %s"));
-EXTERN char e_cannot_modify_typealias[]
- INIT(= N_("E1395: Type alias \"%s\" cannot be modified"));
+// E1395 unused
EXTERN char e_typealias_already_exists_for_str[]
INIT(= N_("E1396: Type alias \"%s\" already exists"));
EXTERN char e_missing_typealias_name[]
@@ -3557,20 +3560,16 @@ EXTERN char e_missing_typealias_type[]
INIT(= N_("E1398: Missing type alias type"));
EXTERN char e_type_can_only_be_used_in_script[]
INIT(= N_("E1399: Type can only be used in a script"));
-EXTERN char e_using_typealias_as_number[]
- INIT(= N_("E1400: Using type alias \"%s\" as a Number"));
-EXTERN char e_using_typealias_as_float[]
- INIT(= N_("E1401: Using type alias \"%s\" as a Float"));
-EXTERN char e_using_typealias_as_string[]
- INIT(= N_("E1402: Using type alias \"%s\" as a String"));
+// E1400 unused
+// E1401 unused
+// E1402 unused
EXTERN char e_using_typealias_as_value_str[]
INIT(= N_("E1403: Type alias \"%s\" cannot be used as a value"));
EXTERN char e_abstract_cannot_be_used_in_interface[]
INIT(= N_("E1404: Abstract cannot be used in an interface"));
EXTERN char e_using_class_as_value_str[]
INIT(= N_("E1405: Class \"%s\" cannot be used as a value"));
-EXTERN char e_using_class_as_var_val[]
- INIT(= N_("E1406: Cannot use a Class as a variable or value"));
+// E1406 unused
EXTERN char e_using_typealias_as_var_val[]
INIT(= N_("E1407: Cannot use a Typealias as a variable or value"));
EXTERN char e_final_variable_not_supported_in_interface[]
@@ -3625,20 +3624,26 @@ EXTERN char e_fmt_arg_nr_unused_str[]
INIT(= N_("E1501: format argument %d unused in $-style format: %s"));
EXTERN char e_positional_num_field_spec_reused_str_str[]
INIT(= N_("E1502: Positional argument %d used as field width reused as different type: %s/%s"));
+#ifdef FEAT_EVAL
EXTERN char e_positional_nr_out_of_bounds_str[]
INIT(= N_("E1503: Positional argument %d out of bounds: %s"));
+#endif
EXTERN char e_positional_arg_num_type_inconsistent_str_str[]
INIT(= N_("E1504: Positional argument %d type used inconsistently: %s/%s"));
EXTERN char e_invalid_format_specifier_str[]
INIT(= N_("E1505: Invalid format specifier: %s"));
+#ifdef FEAT_XATTR
EXTERN char e_xattr_erange[]
INIT(= N_("E1506: Buffer too small to copy xattr value or key"));
+#endif
EXTERN char e_aptypes_is_null_nr_str[]
INIT(= "E1507: Internal error: ap_types or ap_types[idx] is NULL: %d: %s");
+#ifdef FEAT_XATTR
EXTERN char e_xattr_e2big[]
INIT(= N_("E1508: Size of the extended attribute value is larger than the maximum size allowed"));
EXTERN char e_xattr_other[]
INIT(= N_("E1509: Error occurred when reading or writing extended attribute"));
+#endif
EXTERN char e_val_too_large[]
INIT(= N_("E1510: Value too large: %s"));
EXTERN char e_wrong_number_of_characters_for_field_str[]
diff --git a/src/eval.c b/src/eval.c
index 7848fea..cc289b4 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3259,7 +3259,7 @@ may_call_simple_func(
char_u *p = STRNCMP(arg, "<SNR>", 5) == 0 ? skipdigits(arg + 5) : arg;
if (to_name_end(p, TRUE) == parens)
- r = call_simple_func(arg, (int)(parens - arg), rettv);
+ r = call_simple_func(arg, (size_t)(parens - arg), rettv);
}
return r;
}
@@ -5923,6 +5923,37 @@ func_tv2string(typval_T *tv, char_u **tofree, int echo_style)
}
/*
+ * Return a textual representation of the object method in "tv", a VAR_PARTIAL.
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * When "echo_style" is FALSE, put quotes around the function name as
+ * "function()", otherwise does not put quotes around function name.
+ * May return NULL.
+ */
+ static char_u *
+method_tv2string(typval_T *tv, char_u **tofree, int echo_style)
+{
+ char_u buf[MAX_FUNC_NAME_LEN];
+ partial_T *pt = tv->vval.v_partial;
+
+ size_t len = vim_snprintf((char *)buf, sizeof(buf), "<SNR>%d_%s.%s",
+ pt->pt_func->uf_script_ctx.sc_sid,
+ pt->pt_func->uf_class->class_name,
+ pt->pt_func->uf_name);
+ if (len >= sizeof(buf))
+ {
+ if (echo_style)
+ {
+ *tofree = NULL;
+ return (char_u *)"function()";
+ }
+ else
+ return *tofree = string_quote((char_u*)"", TRUE);
+ }
+
+ return *tofree = echo_style ? vim_strsave(buf) : string_quote(buf, TRUE);
+}
+
+/*
* Return a textual representation of a partial in "tv".
* If the memory is allocated "tofree" is set to it, otherwise NULL.
* "numbuf" is used for a number. May return NULL.
@@ -6088,10 +6119,10 @@ dict_tv2string(
*/
static char_u *
jobchan_tv2string(
- typval_T *tv,
- char_u **tofree,
- char_u *numbuf,
- int composite_val)
+ typval_T *tv UNUSED,
+ char_u **tofree UNUSED,
+ char_u *numbuf UNUSED,
+ int composite_val UNUSED)
{
char_u *r = NULL;
@@ -6139,6 +6170,58 @@ class_tv2string(typval_T *tv, char_u **tofree)
}
/*
+ * Return a textual representation of an Object in "tv".
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * When "copyID" is not zero replace recursive object with "...".
+ * When "restore_copyID" is FALSE, repeated items in the object are
+ * replaced with "...". May return NULL.
+ */
+ static char_u *
+object_tv2string(
+ typval_T *tv,
+ char_u **tofree,
+ int copyID,
+ int restore_copyID,
+ char_u *numbuf,
+ int echo_style,
+ int composite_val)
+{
+ char_u *r = NULL;
+
+ object_T *obj = tv->vval.v_object;
+ if (obj == NULL || obj->obj_class == NULL)
+ {
+ *tofree = NULL;
+ r = (char_u *)"object of [unknown]";
+ }
+ else if (copyID != 0 && obj->obj_copyID == copyID
+ && obj->obj_class->class_obj_member_count != 0)
+ {
+ size_t n = 25 + strlen((char *)obj->obj_class->class_name);
+ r = alloc(n);
+ if (r != NULL)
+ (void)vim_snprintf((char *)r, n, "object of %s {...}",
+ obj->obj_class->class_name);
+ *tofree = r;
+ }
+ else
+ {
+ int old_copyID;
+ if (restore_copyID)
+ old_copyID = obj->obj_copyID;
+
+ obj->obj_copyID = copyID;
+ *tofree = object2string(obj, numbuf, copyID, echo_style,
+ restore_copyID, composite_val);
+ if (restore_copyID)
+ obj->obj_copyID = old_copyID;
+ r = *tofree;
+ }
+
+ return r;
+}
+
+/*
* Return a string with the string representation of a variable.
* If the memory is allocated "tofree" is set to it, otherwise NULL.
* "numbuf" is used for a number.
@@ -6169,7 +6252,7 @@ echo_string_core(
{
// Only give this message once for a recursive call to avoid
// flooding the user with errors. And stop iterating over lists
- // and dicts.
+ // and dicts and objects.
did_echo_string_emsg = TRUE;
emsg(_(e_variable_nested_too_deep_for_displaying));
}
@@ -6189,7 +6272,11 @@ echo_string_core(
break;
case VAR_PARTIAL:
- r = partial_tv2string(tv, tofree, numbuf, copyID);
+ if (tv->vval.v_partial == NULL
+ || tv->vval.v_partial->pt_obj == NULL)
+ r = partial_tv2string(tv, tofree, numbuf, copyID);
+ else
+ r = method_tv2string(tv, tofree, echo_style);
break;
case VAR_BLOB:
@@ -6227,9 +6314,8 @@ echo_string_core(
break;
case VAR_OBJECT:
- *tofree = r = object2string(tv->vval.v_object, numbuf, copyID,
- echo_style, restore_copyID,
- composite_val);
+ r = object_tv2string(tv, tofree, copyID, restore_copyID,
+ numbuf, echo_style, composite_val);
break;
case VAR_FLOAT:
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 9720691..173b544 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -28,6 +28,7 @@ static void f_balloon_show(typval_T *argvars, typval_T *rettv);
static void f_balloon_split(typval_T *argvars, typval_T *rettv);
# endif
#endif
+static void f_bindtextdomain(typval_T *argvars, typval_T *rettv);
static void f_byte2line(typval_T *argvars, typval_T *rettv);
static void f_call(typval_T *argvars, typval_T *rettv);
static void f_changenr(typval_T *argvars, typval_T *rettv);
@@ -81,6 +82,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv);
static void f_hlID(typval_T *argvars, typval_T *rettv);
static void f_hlexists(typval_T *argvars, typval_T *rettv);
static void f_hostname(typval_T *argvars, typval_T *rettv);
+static void f_id(typval_T *argvars, typval_T *rettv);
static void f_index(typval_T *argvars, typval_T *rettv);
static void f_indexof(typval_T *argvars, typval_T *rettv);
static void f_input(typval_T *argvars, typval_T *rettv);
@@ -1133,6 +1135,7 @@ static argcheck_T arg2_number_bool[] = {arg_number, arg_bool};
static argcheck_T arg2_number_dict_any[] = {arg_number, arg_dict_any};
static argcheck_T arg2_number_list[] = {arg_number, arg_list_any};
static argcheck_T arg2_number_string[] = {arg_number, arg_string};
+static argcheck_T arg2_number_buffer[] = {arg_number, arg_buffer};
static argcheck_T arg2_number_string_or_list[] = {arg_number, arg_string_or_list_any};
static argcheck_T arg2_str_or_nr_or_list_dict[] = {arg_str_or_nr_or_list, arg_dict_any};
static argcheck_T arg2_string[] = {arg_string, arg_string};
@@ -1323,7 +1326,6 @@ ret_list_items(int argcount UNUSED,
*decl_type = &t_list_any;
return &t_list_list_any;
}
-
static type_T *
ret_list_string_items(int argcount UNUSED,
type2_T *argtypes UNUSED,
@@ -1333,6 +1335,14 @@ ret_list_string_items(int argcount UNUSED,
return &t_list_list_string;
}
static type_T *
+ret_list_regionpos(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type)
+{
+ *decl_type = &t_list_any;
+ return &t_list_list_list_number;
+}
+ static type_T *
ret_dict_any(int argcount UNUSED,
type2_T *argtypes UNUSED,
type_T **decl_type UNUSED)
@@ -1823,6 +1833,8 @@ static funcentry_T global_functions[] =
NULL
#endif
},
+ {"bindtextdomain", 2, 2, 0, arg2_string,
+ ret_bool, f_bindtextdomain},
{"blob2list", 1, 1, FEARG_1, arg1_blob,
ret_list_number, f_blob2list},
{"browse", 4, 4, 0, arg4_browse,
@@ -1963,11 +1975,11 @@ static funcentry_T global_functions[] =
ret_number, f_diff_hlID},
{"digraph_get", 1, 1, FEARG_1, arg1_string,
ret_string, f_digraph_get},
- {"digraph_getlist",0, 1, FEARG_1, arg1_bool,
+ {"digraph_getlist", 0, 1, FEARG_1, arg1_bool,
ret_list_string_items, f_digraph_getlist},
{"digraph_set", 2, 2, FEARG_1, arg2_string,
ret_bool, f_digraph_set},
- {"digraph_setlist",1, 1, FEARG_1, arg1_list_string,
+ {"digraph_setlist", 1, 1, FEARG_1, arg1_list_string,
ret_bool, f_digraph_setlist},
{"echoraw", 1, 1, FEARG_1, arg1_string,
ret_void, f_echoraw},
@@ -2139,8 +2151,8 @@ static funcentry_T global_functions[] =
ret_dict_any, f_getreginfo},
{"getregion", 2, 3, FEARG_1, arg3_list_list_dict,
ret_list_string, f_getregion},
- {"getregionpos", 2, 3, FEARG_1, arg3_list_list_dict,
- ret_list_string, f_getregionpos},
+ {"getregionpos", 2, 3, FEARG_1, arg3_list_list_dict,
+ ret_list_regionpos, f_getregionpos},
{"getregtype", 0, 1, FEARG_1, arg1_string,
ret_string, f_getregtype},
{"getscriptinfo", 0, 1, 0, arg1_dict_any,
@@ -2153,7 +2165,7 @@ static funcentry_T global_functions[] =
ret_any, f_gettabwinvar},
{"gettagstack", 0, 1, FEARG_1, arg1_number,
ret_dict_any, f_gettagstack},
- {"gettext", 1, 1, FEARG_1, arg1_string,
+ {"gettext", 1, 2, FEARG_1, arg2_string,
ret_string, f_gettext},
{"getwininfo", 0, 1, FEARG_1, arg1_number,
ret_list_dict_any, f_getwininfo},
@@ -2203,6 +2215,8 @@ static funcentry_T global_functions[] =
ret_string, f_hostname},
{"iconv", 3, 3, FEARG_1, arg3_string,
ret_string, f_iconv},
+ {"id", 1, 1, FEARG_1, NULL,
+ ret_string, f_id},
{"indent", 1, 1, FEARG_1, arg1_lnum,
ret_number, f_indent},
{"index", 2, 4, FEARG_1, arg24_index,
@@ -2421,6 +2435,8 @@ static funcentry_T global_functions[] =
ret_void, PROP_FUNC(f_popup_move)},
{"popup_notification", 2, 2, FEARG_1, arg2_str_or_nr_or_list_dict,
ret_number, PROP_FUNC(f_popup_notification)},
+ {"popup_setbuf", 2, 2, FEARG_1, arg2_number_buffer,
+ ret_number_bool, PROP_FUNC(f_popup_setbuf)},
{"popup_setoptions", 2, 2, FEARG_1, arg2_number_dict_any,
ret_void, PROP_FUNC(f_popup_setoptions)},
{"popup_settext", 2, 2, FEARG_1, arg2_number_string_or_list,
@@ -3118,8 +3134,8 @@ internal_func_check_arg_types(
// functions, check the arguments are not types.
if (!(func_allows_type(idx)))
{
- for (int i = 0; i < argcount; ++i)
- if (check_type_is_value(types[i].type_curr) == FAIL)
+ for (int i = 0; i < argcount; ++i)
+ if (check_type_is_value(types[i].type_curr) == FAIL)
return FAIL;
}
@@ -3474,6 +3490,33 @@ get_buf_arg(typval_T *arg)
}
/*
+ * "bindtextdomain(package, path)" function
+ */
+ static void
+f_bindtextdomain(typval_T *argvars, typval_T *rettv)
+{
+ rettv->v_type = VAR_BOOL;
+ rettv->vval.v_number = VVAL_TRUE;
+
+ if (check_for_nonempty_string_arg(argvars, 0) == FAIL
+ || check_for_nonempty_string_arg(argvars, 1) == FAIL)
+ return;
+
+ if (strcmp((const char *)argvars[0].vval.v_string, VIMPACKAGE) == 0)
+ semsg(_(e_invalid_argument_str), tv_get_string(&argvars[0]));
+ else
+ {
+ if (bindtextdomain((const char *)argvars[0].vval.v_string, (const char *)argvars[1].vval.v_string) == NULL)
+ {
+ do_outofmem_msg((long)0);
+ rettv->vval.v_number = VVAL_FALSE;
+ }
+ }
+
+ return;
+}
+
+/*
* "byte2line(byte)" function
*/
static void
@@ -5110,6 +5153,36 @@ f_get(typval_T *argvars, typval_T *rettv)
list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]);
}
}
+ else if (STRCMP(what, "arity") == 0)
+ {
+ int required = 0, optional = 0, varargs = FALSE;
+ char_u *name = partial_name(pt);
+
+ get_func_arity(name, &required, &optional, &varargs);
+
+ rettv->v_type = VAR_DICT;
+ if (rettv_dict_alloc(rettv) == OK)
+ {
+ dict_T *dict = rettv->vval.v_dict;
+
+ // Take into account the arguments of the partial, if any.
+ // Note that it is possible to supply more arguments than the function
+ // accepts.
+ if (pt->pt_argc >= required + optional)
+ required = optional = 0;
+ else if (pt->pt_argc > required)
+ {
+ optional -= pt->pt_argc - required;
+ required = 0;
+ }
+ else
+ required -= pt->pt_argc;
+
+ dict_add_number(dict, "required", required);
+ dict_add_number(dict, "optional", optional);
+ dict_add_bool(dict, "varargs", varargs);
+ }
+ }
else
semsg(_(e_invalid_argument_str), what);
@@ -6030,11 +6103,39 @@ f_gettagstack(typval_T *argvars, typval_T *rettv)
static void
f_gettext(typval_T *argvars, typval_T *rettv)
{
- if (check_for_nonempty_string_arg(argvars, 0) == FAIL)
+#if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
+ char *prev = NULL;
+#endif
+
+ if (check_for_nonempty_string_arg(argvars, 0) == FAIL
+ || check_for_opt_string_arg(argvars, 1) == FAIL)
return;
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave((char_u *)_(argvars[0].vval.v_string));
+
+ if (argvars[1].v_type == VAR_STRING &&
+ argvars[1].vval.v_string != NULL &&
+ *(argvars[1].vval.v_string) != NUL)
+ {
+#if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
+ prev = bind_textdomain_codeset((const char *)argvars[1].vval.v_string, (char *)p_enc);
+#endif
+
+#if defined(HAVE_DGETTEXT)
+ rettv->vval.v_string = vim_strsave((char_u *)dgettext((const char *)argvars[1].vval.v_string, (const char *)argvars[0].vval.v_string));
+#else
+ textdomain((const char *)argvars[1].vval.v_string);
+ rettv->vval.v_string = vim_strsave((char_u *)_(argvars[0].vval.v_string));
+ textdomain(VIMPACKAGE);
+#endif
+
+#if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
+ if (prev != NULL)
+ bind_textdomain_codeset((const char *)argvars[1].vval.v_string, prev);
+#endif
+ }
+ else
+ rettv->vval.v_string = vim_strsave((char_u *)_(argvars[0].vval.v_string));
}
// for VIM_VERSION_ defines
@@ -7435,6 +7536,54 @@ f_hostname(typval_T *argvars UNUSED, typval_T *rettv)
}
/*
+ * "id()" function
+ * Identity. Return address of item as a hex string, %p format.
+ * Currently only valid for object/container types.
+ * Return empty string if not an object.
+ */
+#ifdef VMS // VMS does not have defined uintptr_t
+# if defined(HAVE_NO_LONG_LONG)
+typedef unsigned int uintptr_t;
+# else
+typedef unsigned long long uintptr_t;
+# endif
+#endif // VMS
+
+ static void
+f_id(typval_T *argvars, typval_T *rettv)
+{
+ char numbuf[NUMBUFLEN];
+ char *p = numbuf;
+
+ switch (argvars[0].v_type)
+ {
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_OBJECT:
+ case VAR_JOB:
+ case VAR_CHANNEL:
+ case VAR_BLOB:
+ // Assume pointer value in typval_T vval union at common location.
+ if (argvars[0].vval.v_object != NULL)
+ {
+ // "v" gets the address as an integer
+ uintptr_t v = (uintptr_t)(void *)argvars[0].vval.v_object;
+ // Build a hex string from the item's address; it is in
+ // reverse order. Ignore trailing zeros.
+ for (; p < numbuf + sizeof(uintptr_t) * 2 && v != 0;
+ ++p, v >>= 4)
+ *p = "0123456789abcdef"[v & 0xf];
+ }
+ default:
+ break;
+ }
+ *p = NUL;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_strsave((char_u *)numbuf);
+}
+
+/*
* "index()" function
*/
static void
@@ -7483,7 +7632,7 @@ f_index(typval_T *argvars, typval_T *rettv)
{
tv.v_type = VAR_NUMBER;
tv.vval.v_number = blob_get(b, idx);
- if (tv_equal(&tv, &argvars[1], ic, FALSE))
+ if (tv_equal(&tv, &argvars[1], ic))
{
rettv->vval.v_number = idx;
return;
@@ -7516,7 +7665,7 @@ f_index(typval_T *argvars, typval_T *rettv)
}
for ( ; item != NULL; item = item->li_next, ++idx)
- if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE))
+ if (tv_equal(&item->li_tv, &argvars[1], ic))
{
rettv->vval.v_number = idx;
break;
@@ -9215,69 +9364,47 @@ f_test_srand_seed(typval_T *argvars, typval_T *rettv UNUSED)
static void
init_srand(UINT32_T *x)
{
-#ifndef MSWIN
- static int dev_urandom_state = NOTDONE; // FAIL or OK once tried
-#endif
+ struct {
+ union {
+ UINT32_T number;
+ char_u bytes[sizeof(UINT32_T)];
+ } contents;
+ } buf;
if (srand_seed_for_testing_is_used)
{
*x = srand_seed_for_testing;
return;
}
-#ifndef MSWIN
- if (dev_urandom_state != FAIL)
- {
- int fd = open("/dev/urandom", O_RDONLY);
- struct {
- union {
- UINT32_T number;
- char bytes[sizeof(UINT32_T)];
- } contents;
- } buf;
- // Attempt reading /dev/urandom.
- if (fd == -1)
- dev_urandom_state = FAIL;
- else
- {
- buf.contents.number = 0;
- if (read(fd, buf.contents.bytes, sizeof(UINT32_T))
- != sizeof(UINT32_T))
- dev_urandom_state = FAIL;
- else
- {
- dev_urandom_state = OK;
- *x = buf.contents.number;
- }
- close(fd);
- }
- }
- if (dev_urandom_state != OK)
-#endif
+ if (mch_get_random(buf.contents.bytes, sizeof(buf.contents.bytes)) == OK)
{
- // Reading /dev/urandom doesn't work, fall back to:
- // - randombytes_random()
- // - reltime() or time()
- // - XOR with process ID
+ *x = buf.contents.number;
+ return;
+ }
+
+ // The system's random number generator doesn't work, fall back to:
+ // - randombytes_random()
+ // - reltime() or time()
+ // - XOR with process ID
#if defined(FEAT_SODIUM)
- if (crypt_sodium_init() >= 0)
- *x = crypt_sodium_randombytes_random();
- else
+ if (crypt_sodium_init() >= 0)
+ *x = crypt_sodium_randombytes_random();
+ else
#endif
- {
+ {
#if defined(FEAT_RELTIME)
- proftime_T res;
- profile_start(&res);
+ proftime_T res;
+ profile_start(&res);
# if defined(MSWIN)
- *x = (UINT32_T)res.LowPart;
+ *x = (UINT32_T)res.LowPart;
# else
- *x = (UINT32_T)res.tv_fsec;
+ *x = (UINT32_T)res.tv_fsec;
# endif
#else
- *x = vim_time();
+ *x = vim_time();
#endif
- *x ^= mch_get_pid();
- }
+ *x ^= mch_get_pid();
}
}
diff --git a/src/evalvars.c b/src/evalvars.c
index 6facbeb..f18b516 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -4100,7 +4100,7 @@ set_var_const(
// Modifying a final variable with a List value using the "+="
// operator is allowed. For other types, it is not allowed.
- if (((flags & ASSIGN_FOR_LOOP) == 0
+ if ((((flags & ASSIGN_FOR_LOOP) == 0 || (flags & ASSIGN_DECL) == 0)
&& ((flags & ASSIGN_COMPOUND_OP) == 0
|| !type_inplace_modifiable))
? var_check_permission(di, name) == FAIL
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 8143c24..acddd9c 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -2838,9 +2838,9 @@ do_ecmd(
int did_decrement;
buf_T *was_curbuf = curbuf;
- // Set the w_closing flag to avoid that autocommands close the
+ // Set the w_locked flag to avoid that autocommands close the
// window. And set b_locked for the same reason.
- the_curwin->w_closing = TRUE;
+ the_curwin->w_locked = TRUE;
++buf->b_locked;
if (curbuf == old_curbuf.br_buf)
@@ -2854,7 +2854,7 @@ do_ecmd(
// Autocommands may have closed the window.
if (win_valid(the_curwin))
- the_curwin->w_closing = FALSE;
+ the_curwin->w_locked = FALSE;
--buf->b_locked;
#ifdef FEAT_EVAL
@@ -3360,11 +3360,17 @@ ex_append(exarg_T *eap)
indent = get_indent_lnum(lnum);
}
ex_keep_indent = FALSE;
- if (eap->ea_getline == NULL)
+ if (*eap->arg == '|')
+ {
+ // Get the text after the trailing bar.
+ theline = vim_strsave(eap->arg + 1);
+ *eap->arg = NUL;
+ }
+ else if (eap->ea_getline == NULL)
{
// No getline() function, use the lines that follow. This ends
// when there is no more.
- if (eap->nextcmd == NULL || *eap->nextcmd == NUL)
+ if (eap->nextcmd == NULL)
break;
p = vim_strchr(eap->nextcmd, NL);
if (p == NULL)
@@ -3372,6 +3378,8 @@ ex_append(exarg_T *eap)
theline = vim_strnsave(eap->nextcmd, p - eap->nextcmd);
if (*p != NUL)
++p;
+ else
+ p = NULL;
eap->nextcmd = p;
}
else
@@ -3769,6 +3777,7 @@ ex_substitute(exarg_T *eap)
int endcolumn = FALSE; // cursor in last column when done
pos_T old_cursor = curwin->w_cursor;
int start_nsubs;
+ int keeppatterns = cmdmod.cmod_flags & CMOD_KEEPPATTERNS;
#ifdef FEAT_EVAL
int save_ma = 0;
int save_sandbox = 0;
@@ -3832,11 +3841,11 @@ ex_substitute(exarg_T *eap)
which_pat = RE_LAST; // use last used regexp
delimiter = *cmd++; // remember delimiter character
pat = cmd; // remember start of search pat
- patlen = STRLEN(pat);
cmd = skip_regexp_ex(cmd, delimiter, magic_isset(),
&eap->arg, NULL, NULL);
if (cmd[0] == delimiter) // end delimiter found
*cmd++ = NUL; // replace it with a NUL
+ patlen = STRLEN(pat);
}
/*
@@ -3868,7 +3877,7 @@ ex_substitute(exarg_T *eap)
// out of memory
return;
}
- else
+ else if (!keeppatterns)
{
vim_free(old_sub);
old_sub = vim_strsave(sub);
@@ -3932,7 +3941,7 @@ ex_substitute(exarg_T *eap)
ex_may_print(eap);
}
- if ((cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0)
+ if (!keeppatterns)
save_re_pat(RE_SUBST, pat, patlen, magic_isset());
// put pattern in history
add_to_history(HIST_SEARCH, pat, patlen, TRUE, NUL);
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index ce30b8d..0681153 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -197,7 +197,7 @@ dialog_changed(
// restore to empty when write failed
if (empty_bufname)
{
- VIM_CLEAR(buf->b_fname);
+ buf->b_fname = NULL;
VIM_CLEAR(buf->b_ffname);
VIM_CLEAR(buf->b_sfname);
unchanged(buf, TRUE, FALSE);
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 71bfa93..2a59301 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -19,10 +19,6 @@ 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
@@ -1460,8 +1456,13 @@ handle_did_throw(void)
current_exception->throw_name = NULL;
discard_current_exception(); // uses IObuff if 'verbose'
- suppress_errthrow = TRUE;
- force_abort = TRUE;
+
+ // If "silent!" is active the uncaught exception is not fatal.
+ if (emsg_silent == 0)
+ {
+ suppress_errthrow = TRUE;
+ force_abort = TRUE;
+ }
if (messages != NULL)
{
@@ -2336,12 +2337,7 @@ do_one_cmd(
{
for (p = ea.arg; *p; ++p)
{
- // Remove one backslash before a newline, so that it's possible to
- // pass a newline to the shell and also a newline that is preceded
- // with a backslash. This makes it impossible to end a shell
- // command in a backslash, but that doesn't appear useful.
- // Halving the number of backslashes is incompatible with previous
- // versions.
+ // Remove one backslash before a newline
if (*p == '\\' && p[1] == '\n')
STRMOVE(p, p + 1);
else if (*p == '\n' && !(ea.argt & EX_EXPR_ARG))
@@ -2722,6 +2718,12 @@ ex_errmsg(char *msg, char_u *arg)
}
/*
+ * The "+" string used in place of an empty command in Ex mode.
+ * This string is used in pointer comparison.
+ */
+static char exmode_plus[] = "+";
+
+/*
* Handle a range without a command.
* Returns an error message on failure.
*/
@@ -2730,7 +2732,8 @@ ex_range_without_command(exarg_T *eap)
{
char *errormsg = NULL;
- if ((*eap->cmd == '|' || (exmode_active && eap->line1 != eap->line2))
+ if ((*eap->cmd == '|' ||
+ (exmode_active && eap->cmd != (char_u *)exmode_plus + 1))
#ifdef FEAT_EVAL
&& !in_vim9script()
#endif
@@ -2860,9 +2863,8 @@ parse_command_modifiers(
{
// The automatically inserted Visual area range is skipped, so that
// typing ":cmdmod cmd" in Visual mode works without having to move the
- // range to after the modififiers. The command will be
- // "'<,'>cmdmod cmd", parse "cmdmod cmd" and then put back "'<,'>"
- // before "cmd" below.
+ // range to after the modifiers. The command will be "'<,'>cmdmod cmd",
+ // parse "cmdmod cmd" and then put back "'<,'>" before "cmd" below.
eap->cmd += 5;
cmd_start = eap->cmd;
has_visual_range = TRUE;
@@ -3213,7 +3215,7 @@ parse_command_modifiers(
eap->cmd = orig_cmd;
}
else if (use_plus_cmd)
- eap->cmd = (char_u *)"+";
+ eap->cmd = (char_u *)exmode_plus;
return OK;
}
@@ -4044,16 +4046,6 @@ static cmdmod_info_T cmdmod_info_tab[] = {
{"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).
* Return zero when it's not a modifier.
@@ -4061,36 +4053,20 @@ cmp_cmdmod_info(const void *a, const void *b)
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));
-
- // 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 (i = 0; i < (int)ARRAY_LENGTH(cmdmod_info_tab); ++i)
{
- int i;
-
- for (i = entry->minlen; p[i] != NUL; ++i)
- {
- if (p[i] != entry->name[i])
+ for (j = 0; p[j] != NUL; ++j)
+ if (p[j] != cmdmod_info_tab[i].name[j])
break;
- }
-
- if (!ASCII_ISALPHA(p[i]) && i >= entry->minlen && (p == cmd || entry->has_count))
- return i + (int)(p - cmd);
+ if (!ASCII_ISALPHA(p[j]) && j >= cmdmod_info_tab[i].minlen
+ && (p == cmd || cmdmod_info_tab[i].has_count))
+ return j + (int)(p - cmd);
}
-
return 0;
}
@@ -4104,33 +4080,18 @@ cmd_exists(char_u *name)
{
exarg_T ea;
int full = FALSE;
+ int i;
+ int j;
char_u *p;
- // only lowercase characters can match
- if (ASCII_ISLOWER(*name))
+ // Check command modifiers.
+ for (i = 0; i < (int)ARRAY_LENGTH(cmdmod_info_tab); ++i)
{
- 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);
- }
+ for (j = 0; name[j] != NUL; ++j)
+ if (name[j] != cmdmod_info_tab[i].name[j])
+ break;
+ if (name[j] == NUL && j >= cmdmod_info_tab[i].minlen)
+ return (cmdmod_info_tab[i].name[j] == NUL ? 2 : 1);
}
// Check built-in commands and user defined commands.
@@ -4698,6 +4659,7 @@ get_address(
if (n == MAXLNUM)
{
emsg(_(e_line_number_out_of_range));
+ cmd = NULL;
goto error;
}
}
@@ -4728,6 +4690,7 @@ get_address(
if (lnum >= 0 && n >= LONG_MAX - lnum)
{
emsg(_(e_line_number_out_of_range));
+ cmd = NULL;
goto error;
}
lnum += n;
@@ -5401,7 +5364,11 @@ separate_nextcmd(exarg_T *eap, int keep_backslash)
&& in_vim9script()
&& !(eap->argt & EX_NOTRLCOM)
&& p > eap->cmd && VIM_ISWHITE(p[-1]))
- || *p == '|' || *p == '\n')
+ || (*p == '|'
+ && eap->cmdidx != CMD_append
+ && eap->cmdidx != CMD_change
+ && eap->cmdidx != CMD_insert)
+ || *p == '\n')
{
/*
* We remove the '\' before the '|', unless EX_CTRLV is used
@@ -5981,6 +5948,10 @@ get_command_name(expand_T *xp UNUSED, int idx)
{
if (idx >= (int)CMD_SIZE)
return expand_user_command_name(idx);
+ // the following are no real commands
+ if (STRNCMP(cmdnames[idx].cmd_name, "{", 1) == 0 ||
+ STRNCMP(cmdnames[idx].cmd_name, "}", 1) == 0)
+ return (char_u *)"";
return cmdnames[idx].cmd_name;
}
@@ -7261,7 +7232,7 @@ ex_resize(exarg_T *eap)
ex_find(exarg_T *eap)
{
if (!check_can_set_curbuf_forceit(eap->forceit))
- return;
+ return;
char_u *fname;
int count;
@@ -7353,7 +7324,7 @@ ex_edit(exarg_T *eap)
// All other commands must obey 'winfixbuf' / ! rules
&& (is_other_file(0, ffname) && !check_can_set_curbuf_forceit(eap->forceit))
)
- return;
+ return;
do_exedit(eap, NULL);
}
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 3ae4958..1b3a699 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -1586,6 +1586,7 @@ getcmdline_int(
int res;
int save_msg_scroll = msg_scroll;
int save_State = State; // remember State when called
+ int prev_cmdpos = -1;
int some_key_typed = FALSE; // one of the keys was typed
// mouse drag and release events are ignored, unless they are
// preceded with a mouse down event
@@ -2473,6 +2474,13 @@ getcmdline_int(
* (Sorry for the goto's, I know it is ugly).
*/
cmdline_not_changed:
+ // Trigger CursorMovedC autocommands.
+ if (ccline.cmdpos != prev_cmdpos)
+ {
+ trigger_cmd_autocmd(cmdline_type, EVENT_CURSORMOVEDC);
+ prev_cmdpos = ccline.cmdpos;
+ }
+
#ifdef FEAT_SEARCH_EXTRA
if (!is_state.incsearch_postponed)
continue;
@@ -2484,10 +2492,17 @@ cmdline_changed:
if (is_state.winid != curwin->w_id)
init_incsearch_state(&is_state);
#endif
+ // Trigger CmdlineChanged autocommands.
if (trigger_cmdlinechanged)
- // Trigger CmdlineChanged autocommands.
trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED);
+ // Trigger CursorMovedC autocommands.
+ if (ccline.cmdpos != prev_cmdpos)
+ {
+ trigger_cmd_autocmd(cmdline_type, EVENT_CURSORMOVEDC);
+ prev_cmdpos = ccline.cmdpos;
+ }
+
#ifdef FEAT_SEARCH_EXTRA
if (xpc.xp_context == EXPAND_NOTHING && (KeyTyped || vpeekc() == NUL))
may_do_incsearch_highlighting(firstc, count, &is_state);
@@ -3130,31 +3145,15 @@ redraw:
windgoto(msg_row, msg_col);
pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
- // We are done when a NL is entered, but not when it comes after an
- // odd number of backslashes, that results in a NUL.
- if (line_ga.ga_len > 0 && pend[-1] == '\n')
+ // We are done when a NL is entered, but not when it comes after a
+ // backslash in prompt mode.
+ if (line_ga.ga_len > 0 && pend[-1] == '\n'
+ && (line_ga.ga_len <= 1 || pend[-2] != '\\' || !promptc))
{
- int bcount = 0;
-
- while (line_ga.ga_len - 2 >= bcount && pend[-2 - bcount] == '\\')
- ++bcount;
-
- if (bcount > 0)
- {
- // Halve the number of backslashes: "\NL" -> "NUL", "\\NL" ->
- // "\NL", etc.
- line_ga.ga_len -= (bcount + 1) / 2;
- pend -= (bcount + 1) / 2;
- pend[-1] = '\n';
- }
-
- if ((bcount & 1) == 0)
- {
- --line_ga.ga_len;
- --pend;
- *pend = NUL;
- break;
- }
+ --line_ga.ga_len;
+ --pend;
+ *pend = NUL;
+ break;
}
}
@@ -4176,6 +4175,7 @@ get_cmdline_completion(void)
{
cmdline_info_T *p;
char_u *buffer;
+ int xp_context;
if (cmdline_star > 0)
return NULL;
@@ -4184,15 +4184,21 @@ get_cmdline_completion(void)
if (p == NULL || p->xpc == NULL)
return NULL;
- set_expand_context(p->xpc);
- if (p->xpc->xp_context == EXPAND_UNSUCCESSFUL)
+ xp_context = p->xpc->xp_context;
+ if (xp_context == EXPAND_NOTHING)
+ {
+ set_expand_context(p->xpc);
+ xp_context = p->xpc->xp_context;
+ p->xpc->xp_context = EXPAND_NOTHING;
+ }
+ if (xp_context == EXPAND_UNSUCCESSFUL)
return NULL;
- char_u *cmd_compl = cmdcomplete_type_to_str(p->xpc->xp_context);
+ char_u *cmd_compl = cmdcomplete_type_to_str(xp_context);
if (cmd_compl == NULL)
return NULL;
- if (p->xpc->xp_context == EXPAND_USER_LIST || p->xpc->xp_context == EXPAND_USER_DEFINED)
+ if (xp_context == EXPAND_USER_LIST || xp_context == EXPAND_USER_DEFINED)
{
buffer = alloc(STRLEN(cmd_compl) + STRLEN(p->xpc->xp_arg) + 2);
if (buffer == NULL)
@@ -4308,6 +4314,7 @@ set_cmdline_pos(
new_cmdpos = 0;
else
new_cmdpos = pos;
+
return 0;
}
diff --git a/src/fileio.c b/src/fileio.c
index e7f3332..d27a172 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3912,7 +3912,7 @@ vim_rename(char_u *from, char_u *to)
/*
* Create the new file with same permissions as the original.
- * Return -1 for failure, 0 for success.
+ * Return FAIL for failure, OK for success.
*/
int
vim_copyfile(char_u *from, char_u *to)
@@ -3936,7 +3936,7 @@ vim_copyfile(char_u *from, char_u *to)
ret = mch_lstat((char *)from, &st);
if (ret >= 0 && S_ISLNK(st.st_mode))
{
- ret = FAIL;
+ ret = -1;
len = readlink((char *)from, linkbuf, MAXPATHL);
if (len > 0)
diff --git a/src/filepath.c b/src/filepath.c
index 9f68d7c..d514aaf 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -3645,11 +3645,15 @@ dos_expandpath(
}
else
{
+ stat_T sb;
+
// no more wildcards, check if there is a match
// remove backslashes for the remaining components only
if (*path_end != 0)
backslash_halve(buf + len + 1);
- if (mch_getperm(buf) >= 0) // add existing file
+ // add existing file
+ if ((flags & EW_ALLLINKS) ? mch_lstat((char *)buf, &sb) >= 0
+ : mch_getperm(buf) >= 0)
addfile(gap, buf, flags);
}
}
@@ -3999,6 +4003,8 @@ gen_expand_wildcards(
int add_pat;
int retval = OK;
int did_expand_in_path = FALSE;
+ char_u *path_option = *curbuf->b_p_path == NUL ?
+ p_path : curbuf->b_p_path;
/*
* expand_env() is called to expand things like "~user". If this fails,
@@ -4088,7 +4094,7 @@ gen_expand_wildcards(
*/
if (mch_has_exp_wildcard(p) || (flags & EW_ICASE))
{
- if ((flags & EW_PATH)
+ if ((flags & (EW_PATH | EW_CDPATH))
&& !mch_isFullName(p)
&& !(p[0] == '.'
&& (vim_ispathsep(p[1])
@@ -4122,8 +4128,8 @@ gen_expand_wildcards(
vim_free(t);
}
- if (did_expand_in_path && ga.ga_len > 0 && (flags & EW_PATH))
- uniquefy_paths(&ga, p);
+ if (did_expand_in_path && ga.ga_len > 0 && (flags & (EW_PATH | EW_CDPATH)))
+ uniquefy_paths(&ga, p, path_option);
if (p != pat[i])
vim_free(p);
}
diff --git a/src/findfile.c b/src/findfile.c
index 2636609..4310a50 100644
--- a/src/findfile.c
+++ b/src/findfile.c
@@ -418,6 +418,7 @@ vim_findfile_init(
{
char_u *helper;
void *ptr;
+ size_t len;
helper = walker;
ptr = vim_realloc(search_ctx->ffsc_stopdirs_v,
@@ -428,18 +429,21 @@ vim_findfile_init(
// ignore, keep what we have and continue
break;
walker = vim_strchr(walker, ';');
- if (walker)
+ len = walker ? (size_t)(walker - helper) : STRLEN(helper);
+ // "" means ascent till top of directory tree.
+ if (*helper != NUL && !vim_isAbsName(helper)
+ && len + 1 < MAXPATHL)
{
+ // Make the stop dir an absolute path name.
+ vim_strncpy(ff_expand_buffer, helper, len);
search_ctx->ffsc_stopdirs_v[dircount-1] =
- vim_strnsave(helper, walker - helper);
- walker++;
+ FullName_save(ff_expand_buffer, FALSE);
}
else
- // this might be "", which means ascent till top
- // of directory tree.
search_ctx->ffsc_stopdirs_v[dircount-1] =
- vim_strsave(helper);
-
+ vim_strnsave(helper, len);
+ if (walker)
+ walker++;
dircount++;
} while (walker != NULL);
@@ -1078,11 +1082,13 @@ vim_findfile(void *search_ctx_arg)
&& search_ctx->ffsc_stopdirs_v != NULL && !got_int)
{
ff_stack_T *sptr;
+ // path_end may point to the NUL or the previous path separator
+ int plen = (path_end - search_ctx->ffsc_start_dir)
+ + (*path_end != NUL);
// is the last starting directory in the stop list?
if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
- (int)(path_end - search_ctx->ffsc_start_dir),
- search_ctx->ffsc_stopdirs_v) == TRUE)
+ plen, search_ctx->ffsc_stopdirs_v) == TRUE)
break;
// cut of last dir
@@ -1521,22 +1527,14 @@ ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v)
return TRUE;
for (i = 0; stopdirs_v[i] != NULL; i++)
- {
- if ((int)STRLEN(stopdirs_v[i]) > path_len)
- {
- // match for parent directory. So '/home' also matches
- // '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
- // '/home/r' would also match '/home/rks'
- if (fnamencmp(stopdirs_v[i], path, path_len) == 0
- && vim_ispathsep(stopdirs_v[i][path_len]))
- return TRUE;
- }
- else
- {
- if (fnamecmp(stopdirs_v[i], path) == 0)
- return TRUE;
- }
- }
+ // match for parent directory. So '/home' also matches
+ // '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
+ // '/home/r' would also match '/home/rks'
+ if (fnamencmp(stopdirs_v[i], path, path_len) == 0
+ && ((int)STRLEN(stopdirs_v[i]) <= path_len
+ || vim_ispathsep(stopdirs_v[i][path_len])))
+ return TRUE;
+
return FALSE;
}
@@ -2213,10 +2211,11 @@ is_unique(char_u *maybe_unique, garray_T *gap, int i)
* expanding each into their equivalent path(s).
*/
static void
-expand_path_option(char_u *curdir, garray_T *gap)
+expand_path_option(
+ char_u *curdir,
+ char_u *path_option, // p_path or p_cdpath
+ garray_T *gap)
{
- char_u *path_option = *curbuf->b_p_path == NUL
- ? p_path : curbuf->b_p_path;
char_u *buf;
char_u *p;
int len;
@@ -2331,7 +2330,10 @@ get_path_cutoff(char_u *fname, garray_T *gap)
* that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len".
*/
void
-uniquefy_paths(garray_T *gap, char_u *pattern)
+uniquefy_paths(
+ garray_T *gap,
+ char_u *pattern,
+ char_u *path_option) // p_path or p_cdpath
{
int i;
int len;
@@ -2374,7 +2376,7 @@ uniquefy_paths(garray_T *gap, char_u *pattern)
if ((curdir = alloc(MAXPATHL)) == NULL)
goto theend;
mch_dirname(curdir, MAXPATHL);
- expand_path_option(curdir, &path_ga);
+ expand_path_option(curdir, path_option, &path_ga);
in_curdir = ALLOC_CLEAR_MULT(char_u *, gap->ga_len);
if (in_curdir == NULL)
@@ -2522,13 +2524,17 @@ expand_in_path(
garray_T path_ga;
char_u *paths = NULL;
int glob_flags = 0;
+ char_u *path_option = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
if ((curdir = alloc(MAXPATHL)) == NULL)
return 0;
mch_dirname(curdir, MAXPATHL);
ga_init2(&path_ga, sizeof(char_u *), 1);
- expand_path_option(curdir, &path_ga);
+ if (flags & EW_CDPATH)
+ expand_path_option(curdir, p_cdpath, &path_ga);
+ else
+ expand_path_option(curdir, path_option, &path_ga);
vim_free(curdir);
if (path_ga.ga_len == 0)
return 0;
@@ -2542,7 +2548,7 @@ expand_in_path(
glob_flags |= WILD_ICASE;
if (flags & EW_ADDSLASH)
glob_flags |= WILD_ADD_SLASH;
- globpath(paths, pattern, gap, glob_flags, FALSE);
+ globpath(paths, pattern, gap, glob_flags, !!(flags & EW_CDPATH));
vim_free(paths);
return gap->ga_len;
diff --git a/src/fold.c b/src/fold.c
index 2cd4dcd..3353cc5 100644
--- a/src/fold.c
+++ b/src/fold.c
@@ -1492,6 +1492,9 @@ deleteFoldRecurse(garray_T *gap)
// foldMarkAdjust() {{{2
/*
* Update line numbers of folds for inserted/deleted lines.
+ *
+ * We are adjusting the folds in the range from line1 til line2,
+ * make sure that line2 does not get smaller than line1
*/
void
foldMarkAdjust(
@@ -1505,6 +1508,8 @@ foldMarkAdjust(
// lines, set line2 so that only deleted lines have their folds removed.
if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after)
line2 = line1 - amount_after - 1;
+ if (line2 < line1)
+ line2 = line1;
// If appending a line in Insert mode, it should be included in the fold
// just above the line.
if ((State & MODE_INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
diff --git a/src/getchar.c b/src/getchar.c
index 1c544da..96e180f 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -42,6 +42,11 @@ static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
static int typeahead_char = 0; // typeahead char that's not flushed
+#ifdef FEAT_EVAL
+static char_u typedchars[MAXMAPLEN + 1] = { NUL }; // typed chars before map
+static int typedchars_pos = 0;
+#endif
+
/*
* When block_redo is TRUE the redo buffer will not be changed.
* Used by edit() to repeat insertions.
@@ -96,6 +101,9 @@ static void closescript(void);
static void updatescript(int c);
static int vgetorpeek(int);
static int inchar(char_u *buf, int maxlen, long wait_time);
+#ifdef FEAT_EVAL
+static int do_key_input_pre(int c);
+#endif
/*
* Free and clear a buffer.
@@ -438,9 +446,18 @@ flush_buffers(flush_buffers_T flush_typeahead)
if (flush_typeahead == FLUSH_MINIMAL)
{
- // remove mapped characters at the start only
- typebuf.tb_off += typebuf.tb_maplen;
- typebuf.tb_len -= typebuf.tb_maplen;
+ // remove mapped characters at the start only,
+ // but only when enough space left in typebuf
+ if (typebuf.tb_off + typebuf.tb_maplen >= typebuf.tb_buflen)
+ {
+ typebuf.tb_off = MAXMAPLEN;
+ typebuf.tb_len = 0;
+ }
+ else
+ {
+ typebuf.tb_off += typebuf.tb_maplen;
+ typebuf.tb_len -= typebuf.tb_maplen;
+ }
#if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL)
if (typebuf.tb_len == 0)
typebuf_was_filled = FALSE;
@@ -1706,6 +1723,13 @@ updatescript(int c)
ml_sync_all(c == 0, TRUE);
count = 0;
}
+#ifdef FEAT_EVAL
+ if (typedchars_pos < MAXMAPLEN)
+ {
+ typedchars[typedchars_pos] = c;
+ typedchars_pos++;
+ }
+#endif
}
/*
@@ -1996,8 +2020,45 @@ vgetc(void)
#endif
}
- // a keypad or special function key was not mapped, use it like
- // its ASCII equivalent
+ // For a multi-byte character get all the bytes and return the
+ // converted character.
+ // Note: This will loop until enough bytes are received!
+ if (has_mbyte && (n = MB_BYTE2LEN_CHECK(c)) > 1)
+ {
+ ++no_mapping;
+ buf[0] = c;
+ for (i = 1; i < n; ++i)
+ {
+ buf[i] = vgetorpeek(TRUE);
+ if (buf[i] == K_SPECIAL
+#ifdef FEAT_GUI
+ || (buf[i] == CSI)
+#endif
+ )
+ {
+ // Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER
+ // sequence, which represents a K_SPECIAL (0x80),
+ // or a CSI - KS_EXTRA - KE_CSI sequence, which
+ // represents a CSI (0x9B),
+ // or a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI
+ // too.
+ c = vgetorpeek(TRUE);
+ if (vgetorpeek(TRUE) == KE_CSI && c == KS_EXTRA)
+ buf[i] = CSI;
+ }
+ }
+ --no_mapping;
+ c = (*mb_ptr2char)(buf);
+ }
+
+ if (vgetc_char == 0)
+ {
+ vgetc_mod_mask = mod_mask;
+ vgetc_char = c;
+ }
+
+ // A keypad or special function key was not mapped, use it like
+ // its ASCII equivalent.
switch (c)
{
case K_KPLUS: c = '+'; break;
@@ -2059,43 +2120,6 @@ vgetc(void)
case K_XRIGHT: c = K_RIGHT; break;
}
- // For a multi-byte character get all the bytes and return the
- // converted character.
- // Note: This will loop until enough bytes are received!
- if (has_mbyte && (n = MB_BYTE2LEN_CHECK(c)) > 1)
- {
- ++no_mapping;
- buf[0] = c;
- for (i = 1; i < n; ++i)
- {
- buf[i] = vgetorpeek(TRUE);
- if (buf[i] == K_SPECIAL
-#ifdef FEAT_GUI
- || (buf[i] == CSI)
-#endif
- )
- {
- // Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER
- // sequence, which represents a K_SPECIAL (0x80),
- // or a CSI - KS_EXTRA - KE_CSI sequence, which
- // represents a CSI (0x9B),
- // or a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI
- // too.
- c = vgetorpeek(TRUE);
- if (vgetorpeek(TRUE) == KE_CSI && c == KS_EXTRA)
- buf[i] = CSI;
- }
- }
- --no_mapping;
- c = (*mb_ptr2char)(buf);
- }
-
- if (vgetc_char == 0)
- {
- vgetc_mod_mask = mod_mask;
- vgetc_char = c;
- }
-
break;
}
@@ -2130,6 +2154,13 @@ vgetc(void)
}
#endif
+#ifdef FEAT_EVAL
+ c = do_key_input_pre(c);
+
+ // Clear the next typedchars_pos
+ typedchars_pos = 0;
+#endif
+
// Need to process the character before we know it's safe to do something
// else.
if (c != K_IGNORE)
@@ -2138,6 +2169,78 @@ vgetc(void)
return c;
}
+#ifdef FEAT_EVAL
+/*
+ * Handle the InsertCharPre autocommand.
+ * "c" is the character that was typed.
+ * Return new input character.
+ */
+ static int
+do_key_input_pre(int c)
+{
+ int res = c;
+ char_u buf[MB_MAXBYTES + 1];
+ char_u curr_mode[MODE_MAX_LENGTH];
+ int save_State = State;
+ save_v_event_T save_v_event;
+ dict_T *v_event;
+
+ // Return quickly when there is nothing to do.
+ if (!has_keyinputpre())
+ return res;
+
+ if (IS_SPECIAL(c))
+ {
+ buf[0] = K_SPECIAL;
+ buf[1] = KEY2TERMCAP0(c);
+ buf[2] = KEY2TERMCAP1(c);
+ buf[3] = NUL;
+ }
+ else
+ buf[(*mb_char2bytes)(c, buf)] = NUL;
+
+ typedchars[typedchars_pos] = NUL;
+ vim_unescape_csi(typedchars);
+
+ get_mode(curr_mode);
+
+ // Lock the text to avoid weird things from happening.
+ ++textlock;
+ set_vim_var_string(VV_CHAR, buf, -1); // set v:char
+
+ v_event = get_v_event(&save_v_event);
+ (void)dict_add_bool(v_event, "typed", KeyTyped);
+ (void)dict_add_string(v_event, "typedchar", typedchars);
+
+ if (apply_autocmds(EVENT_KEYINPUTPRE, curr_mode, curr_mode, FALSE, curbuf)
+ && STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0)
+ {
+ // Get the value of v:char. It may be empty or more than one
+ // character. Only use it when changed, otherwise continue with the
+ // original character.
+ char_u *v_char;
+
+ v_char = get_vim_var_str(VV_CHAR);
+
+ // Convert special bytes when it is special string.
+ if (STRLEN(v_char) >= 3 && v_char[0] == K_SPECIAL)
+ res = TERMCAP2KEY(v_char[1], v_char[2]);
+ else if (STRLEN(v_char) > 0)
+ res = PTR2CHAR(v_char);
+ }
+
+ restore_v_event(v_event, &save_v_event);
+
+ set_vim_var_string(VV_CHAR, NULL, -1); // clear v:char
+ --textlock;
+
+ // Restore the State, it may have been changed.
+ State = save_State;
+
+ return res;
+}
+#endif
+
/*
* Like vgetc(), but never return a NUL when called recursively, get a key
* directly from the user (ignoring typeahead).
@@ -2841,8 +2944,11 @@ handle_mapping(
}
}
else
+ {
// No match; may have to check for termcode at next
- // character. If the first character that didn't match is
+ // character.
+
+ // If the first character that didn't match is
// K_SPECIAL then check for a termcode. This isn't perfect
// but should work in most cases.
if (max_mlen < mlen)
@@ -2852,6 +2958,12 @@ handle_mapping(
}
else if (max_mlen == mlen && mp->m_keys[mlen] == K_SPECIAL)
want_termcode = 1;
+
+ // Check termcode for uppercase character to properly
+ // process "ESC[27;2;<ascii code>~" control sequences.
+ if (ASCII_ISUPPER(mp->m_keys[mlen]))
+ want_termcode = 1;
+ }
}
}
@@ -3053,6 +3165,8 @@ handle_mapping(
int save_m_noremap;
int save_m_silent;
char_u *save_m_keys;
+ char_u *save_alt_m_keys;
+ int save_alt_m_keylen;
#else
# define save_m_noremap mp->m_noremap
# define save_m_silent mp->m_silent
@@ -3101,6 +3215,8 @@ handle_mapping(
save_m_noremap = mp->m_noremap;
save_m_silent = mp->m_silent;
save_m_keys = NULL; // only saved when needed
+ save_alt_m_keys = NULL; // only saved when needed
+ save_alt_m_keylen = mp->m_alt != NULL ? mp->m_alt->m_keylen : 0;
/*
* Handle ":map <expr>": evaluate the {rhs} as an expression. Also
@@ -3117,7 +3233,10 @@ handle_mapping(
vgetc_busy = 0;
may_garbage_collect = FALSE;
- save_m_keys = vim_strsave(mp->m_keys);
+ save_m_keys = vim_strnsave(mp->m_keys, (size_t)mp->m_keylen);
+ save_alt_m_keys = mp->m_alt != NULL
+ ? vim_strnsave(mp->m_alt->m_keys,
+ (size_t)save_alt_m_keylen) : NULL;
map_str = eval_map_expr(mp, NUL);
// The mapping may do anything, but we expect it to take care of
@@ -3175,15 +3294,20 @@ handle_mapping(
noremap = save_m_noremap;
else if (
#ifdef FEAT_EVAL
- STRNCMP(map_str, save_m_keys != NULL ? save_m_keys : mp->m_keys,
- (size_t)keylen)
-#else
- STRNCMP(map_str, mp->m_keys, (size_t)keylen)
+ save_m_expr ?
+ (save_m_keys != NULL
+ && STRNCMP(map_str, save_m_keys, (size_t)keylen) == 0)
+ || (save_alt_m_keys != NULL
+ && STRNCMP(map_str, save_alt_m_keys,
+ (size_t)save_alt_m_keylen) == 0) :
#endif
- != 0)
- noremap = REMAP_YES;
- else
+ STRNCMP(map_str, mp->m_keys, (size_t)keylen) == 0
+ || (mp->m_alt != NULL
+ && STRNCMP(map_str, mp->m_alt->m_keys,
+ (size_t)mp->m_alt->m_keylen) == 0))
noremap = REMAP_SKIP;
+ else
+ noremap = REMAP_YES;
i = ins_typebuf(map_str, noremap,
0, TRUE, cmd_silent || save_m_silent);
#ifdef FEAT_EVAL
@@ -3193,6 +3317,7 @@ handle_mapping(
}
#ifdef FEAT_EVAL
vim_free(save_m_keys);
+ vim_free(save_alt_m_keys);
#endif
*keylenp = keylen;
if (i == FAIL)
diff --git a/src/globals.h b/src/globals.h
index fb5c7b3..77ddea8 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -131,8 +131,8 @@ EXTERN int screen_Columns INIT(= 0); // actual size of ScreenLines[]
*/
EXTERN int mod_mask INIT(= 0); // current key modifiers
-// The value of "mod_mask" and the unomdified character before calling
-// merge_modifyOtherKeys().
+// The value of "mod_mask" and the unmodified character in vgetc() after it has
+// called vgetorpeek() enough times.
EXTERN int vgetc_mod_mask INIT(= 0);
EXTERN int vgetc_char INIT(= 0);
@@ -519,31 +519,37 @@ EXTERN int garbage_collect_at_exit INIT(= FALSE);
#define t_list_list_any (static_types[70])
#define t_const_list_list_any (static_types[71])
-#define t_list_list_string (static_types[72])
-#define t_const_list_list_string (static_types[73])
+#define t_list_list_number (static_types[72])
+#define t_const_list_list_number (static_types[73])
-#define t_dict_bool (static_types[74])
-#define t_const_dict_bool (static_types[75])
+#define t_list_list_string (static_types[74])
+#define t_const_list_list_string (static_types[75])
-#define t_dict_number (static_types[76])
-#define t_const_dict_number (static_types[77])
+#define t_list_list_list_number (static_types[76])
+#define t_const_list_list_list_number (static_types[77])
-#define t_dict_string (static_types[78])
-#define t_const_dict_string (static_types[79])
+#define t_dict_bool (static_types[78])
+#define t_const_dict_bool (static_types[79])
-#define t_super (static_types[80])
-#define t_const_super (static_types[81])
+#define t_dict_number (static_types[80])
+#define t_const_dict_number (static_types[81])
-#define t_object (static_types[82])
-#define t_const_object (static_types[83])
+#define t_dict_string (static_types[82])
+#define t_const_dict_string (static_types[83])
-#define t_class (static_types[84])
-#define t_const_class (static_types[85])
+#define t_super (static_types[84])
+#define t_const_super (static_types[85])
-#define t_typealias (static_types[86])
-#define t_const_typealias (static_types[87])
+#define t_object (static_types[86])
+#define t_const_object (static_types[87])
-EXTERN type_T static_types[88]
+#define t_class (static_types[88])
+#define t_const_class (static_types[89])
+
+#define t_typealias (static_types[90])
+#define t_const_typealias (static_types[91])
+
+EXTERN type_T static_types[92]
#ifdef DO_INIT
= {
// 0: t_unknown
@@ -690,35 +696,43 @@ EXTERN type_T static_types[88]
{VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_any, NULL, NULL},
{VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_any, NULL, NULL},
- // 72: t_list_list_string
+ // 74: t_list_list_number
+ {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_number, NULL, NULL},
+ {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_number, NULL, NULL},
+
+ // 74: t_list_list_string
{VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_string, NULL, NULL},
{VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_string, NULL, NULL},
- // 74: t_dict_bool
+ // 76: t_list_list_list_number
+ {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_list_number, NULL, NULL},
+ {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_list_number, NULL, NULL},
+
+ // 78: t_dict_bool
{VAR_DICT, 0, 0, TTFLAG_STATIC, &t_bool, NULL, NULL},
{VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL, NULL},
- // 76: t_dict_number
+ // 80: t_dict_number
{VAR_DICT, 0, 0, TTFLAG_STATIC, &t_number, NULL, NULL},
{VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL, NULL},
- // 78: t_dict_string
+ // 82: t_dict_string
{VAR_DICT, 0, 0, TTFLAG_STATIC, &t_string, NULL, NULL},
{VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL, NULL},
- // 80: t_super (VAR_CLASS with tt_member set to &t_bool
+ // 84: t_super (VAR_CLASS with tt_member set to &t_bool
{VAR_CLASS, 0, 0, TTFLAG_STATIC, &t_bool, NULL, NULL},
{VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL, NULL},
- // 82: t_object
+ // 86: t_object
{VAR_OBJECT, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
{VAR_OBJECT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
- // 84: t_class
+ // 88: 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
+ // 90: t_typealias
{VAR_TYPEALIAS, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
{VAR_TYPEALIAS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
}
diff --git a/src/gui.c b/src/gui.c
index 25662ef..8e7b079 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -460,7 +460,7 @@ gui_init_check(void)
// and in that case we don't want to overwrite ligatures map that has already
// been correctly populated (as that would lead to a cleared ligatures maps).
if (*p_guiligatures == NUL)
- CLEAR_FIELD(gui.ligatures_map);
+ CLEAR_FIELD(gui.ligatures_map);
#endif
#if defined(ALWAYS_USE_GUI) || defined(VIMDLL)
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index 67ee531..6c97d1a 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -797,8 +797,8 @@ draw_event(GtkWidget *widget UNUSED,
# if GTK_CHECK_VERSION(3,10,0)
static gboolean
scale_factor_event(GtkWidget *widget,
- GParamSpec* pspec UNUSED,
- gpointer user_data UNUSED)
+ GParamSpec* pspec UNUSED,
+ gpointer user_data UNUSED)
{
if (gui.surface != NULL)
cairo_surface_destroy(gui.surface);
diff --git a/src/gui_w32.c b/src/gui_w32.c
index f628dd6..78f252a 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -274,13 +274,9 @@ gui_mch_set_rendering_options(char_u *s)
// cproto fails on missing include files
#ifndef PROTO
-
-# ifndef __MINGW32__
-# include <shellapi.h>
-# endif
+# include <shellapi.h>
# include <commctrl.h>
# include <windowsx.h>
-
#endif // PROTO
#ifdef FEAT_MENU
@@ -5526,6 +5522,9 @@ gui_mch_prepare(int *argc, char **argv)
}
#ifdef FEAT_OLE
+# ifdef VIMDLL
+ if (mch_is_gui_executable())
+# endif
{
int bDoRestart = FALSE;
diff --git a/src/help.c b/src/help.c
index a792bf3..1062362 100644
--- a/src/help.c
+++ b/src/help.c
@@ -813,6 +813,8 @@ fix_help_buffer(void)
f1 = fnames[i1];
t1 = gettail(f1);
e1 = vim_strrchr(t1, '.');
+ if (e1 == NULL)
+ continue;
if (fnamecmp(e1, ".txt") != 0
&& fnamecmp(e1, fname + 4) != 0)
{
@@ -828,6 +830,8 @@ fix_help_buffer(void)
continue;
t2 = gettail(f2);
e2 = vim_strrchr(t2, '.');
+ if (e2 == NULL)
+ continue;
if (e1 - f1 != e2 - f2
|| fnamencmp(f1, f2, e1 - f1) != 0)
continue;
diff --git a/src/highlight.c b/src/highlight.c
index a71a100..d3ea2d2 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -3351,8 +3351,8 @@ syn_list_header(
if (msg_col >= endcol) // output at least one space
endcol = msg_col + 1;
- if (Columns <= endcol) // avoid hang for tiny window
- endcol = Columns - 1;
+ if (Columns <= (long)endcol) // avoid hang for tiny window
+ endcol = (int)(Columns - 1);
msg_advance(endcol);
diff --git a/src/if_mzsch.c b/src/if_mzsch.c
index 9a9c487..4a8644c 100644
--- a/src/if_mzsch.c
+++ b/src/if_mzsch.c
@@ -383,7 +383,7 @@ static void (*dll_scheme_set_config_path)(Scheme_Object *p);
# define scheme_null dll_scheme_null
# define scheme_true dll_scheme_true
-// pointers are GetProceAddress'ed as pointers to pointer
+// pointers are GetProcAddress'ed as pointers to pointer
#if !defined(USE_THREAD_LOCAL) && !defined(LINK_EXTENSIONS_BY_TABLE)
# define scheme_current_thread (*dll_scheme_current_thread_ptr)
# endif
@@ -924,7 +924,7 @@ mzscheme_end(void)
#endif
}
-#if HAVE_TLS_SPACE
+#if HAVE_TLS_SPACE && !defined(VIMDLL)
# if defined(_MSC_VER)
static __declspec(thread) void *tls_space;
extern intptr_t _tls_index;
@@ -960,7 +960,24 @@ mzscheme_main(void)
}
#endif
#ifdef HAVE_TLS_SPACE
+# ifdef VIMDLL
+ void **ptls_space;
+ intptr_t tls_index;
+ void (*pget_tls_info)(void ***ptls_space, intptr_t *ptls_index);
+
+ // Get the address of get_tls_info() from (g)vim.exe.
+ pget_tls_info = (void *)GetProcAddress(
+ GetModuleHandle(NULL), "get_tls_info");
+ if (pget_tls_info == NULL)
+ {
+ disabled = TRUE;
+ return vim_main2();
+ }
+ pget_tls_info(&ptls_space, &tls_index);
+ scheme_register_tls_space(ptls_space, tls_index);
+# else
scheme_register_tls_space(&tls_space, _tls_index);
+# endif
#endif
#ifdef TRAMPOLINED_MZVIM_STARTUP
return scheme_main_setup(TRUE, mzscheme_env_main, argc, &argv);
diff --git a/src/if_py_both.h b/src/if_py_both.h
index e0fd3ea..3643f8b 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -358,7 +358,9 @@ static PyObject *py_find_spec;
#else
static PyObject *py_load_module;
#endif
+#if PY_VERSION_HEX < 0x30c00a7
static PyObject *py_find_module;
+#endif
static PyObject *VimError;
@@ -3081,7 +3083,7 @@ ListConcatInPlace(ListObject *self, PyObject *obj)
}
Py_DECREF(lookup_dict);
- Py_INCREF(self);
+ Py_INCREF((PyObject *)self);
return (PyObject *)(self);
}
@@ -4010,7 +4012,7 @@ TabPageNew(tabpage_T *tab)
if (TAB_PYTHON_REF(tab))
{
self = TAB_PYTHON_REF(tab);
- Py_INCREF(self);
+ Py_INCREF((PyObject *)self);
}
else
{
@@ -4204,7 +4206,7 @@ WindowNew(win_T *win, tabpage_T *tab)
if (WIN_PYTHON_REF(win))
{
self = WIN_PYTHON_REF(win);
- Py_INCREF(self);
+ Py_INCREF((PyObject *)self);
}
else
{
@@ -4332,7 +4334,7 @@ WindowAttr(WindowObject *self, char *name)
}
else if (strcmp(name, "tabpage") == 0)
{
- Py_INCREF(self->tabObject);
+ Py_INCREF((PyObject *)self->tabObject);
return (PyObject *)(self->tabObject);
}
else if (strcmp(name, "__members__") == 0)
@@ -4486,7 +4488,7 @@ WinListNew(TabPageObject *tabObject)
self = PyObject_NEW(WinListObject, WinListTypePtr);
self->tabObject = tabObject;
- Py_INCREF(tabObject);
+ Py_INCREF((PyObject *)tabObject);
return (PyObject *)(self);
}
@@ -5381,7 +5383,7 @@ RangeNew(buf_T *buf, PyInt start, PyInt end)
Py_DECREF(self);
return NULL;
}
- Py_INCREF(bufr);
+ Py_INCREF((PyObject *)bufr);
self->buf = bufr;
self->start = start;
@@ -5510,7 +5512,7 @@ BufferNew(buf_T *buf)
if (BUF_PYTHON_REF(buf) != NULL)
{
self = BUF_PYTHON_REF(buf);
- Py_INCREF(self);
+ Py_INCREF((PyObject *)self);
}
else
{
diff --git a/src/if_python3.c b/src/if_python3.c
index c135e7e..ac817bd 100644
--- a/src/if_python3.c
+++ b/src/if_python3.c
@@ -219,6 +219,17 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll
# define PyObject_GetItem py3_PyObject_GetItem
# define PyObject_IsTrue py3_PyObject_IsTrue
# define PyModule_GetDict py3_PyModule_GetDict
+# if defined(USE_LIMITED_API) \
+ && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
+# undef Py_INCREF
+# if Py_LIMITED_API+0 >= 0x030a00A7
+# define _Py_IncRef py3__Py_IncRef
+# define Py_INCREF _Py_IncRef
+# else
+# define Py_IncRef py3_Py_IncRef
+# define Py_INCREF Py_IncRef
+# endif
+# endif
# ifdef USE_LIMITED_API
# define Py_CompileString py3_Py_CompileString
# define PyEval_EvalCode py3_PyEval_EvalCode
@@ -232,7 +243,11 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll
# define PyObject_HasAttrString py3_PyObject_HasAttrString
# define PyObject_SetAttrString py3_PyObject_SetAttrString
# define PyObject_CallFunctionObjArgs py3_PyObject_CallFunctionObjArgs
-# define _PyObject_CallFunction_SizeT py3__PyObject_CallFunction_SizeT
+# if PY_VERSION_HEX >= 0x030d0000
+# define PyObject_CallFunction py3_PyObject_CallFunction
+# else
+# define _PyObject_CallFunction_SizeT py3__PyObject_CallFunction_SizeT
+# endif
# define PyObject_Call py3_PyObject_Call
# define PyEval_GetLocals py3_PyEval_GetLocals
# define PyEval_GetGlobals py3_PyEval_GetGlobals
@@ -387,6 +402,15 @@ static void (*py3_Py_Finalize)(void);
static void (*py3_PyErr_SetString)(PyObject *, const char *);
static void (*py3_PyErr_SetObject)(PyObject *, PyObject *);
static int (*py3_PyErr_ExceptionMatches)(PyObject *);
+# if defined(USE_LIMITED_API) \
+ && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
+# if Py_LIMITED_API+0 >= 0x030a00A7
+# define _Py_IncRef py3__Py_IncRef
+static void (*py3__Py_IncRef)(PyObject *);
+# else
+static void (*py3_Py_IncRef)(PyObject *);
+# endif
+# endif
# ifdef USE_LIMITED_API
static PyObject* (*py3_Py_CompileString)(const char *, const char *, int);
static PyObject* (*py3_PyEval_EvalCode)(PyObject *co, PyObject *globals, PyObject *locals);
@@ -398,7 +422,11 @@ static PyObject* (*py3_PyObject_GetAttrString)(PyObject *, const char *);
static int (*py3_PyObject_HasAttrString)(PyObject *, const char *);
static int (*py3_PyObject_SetAttrString)(PyObject *, const char *, PyObject *);
static PyObject* (*py3_PyObject_CallFunctionObjArgs)(PyObject *, ...);
+# if PY_VERSION_HEX >= 0x030d0000
+static PyObject* (*py3_PyObject_CallFunction)(PyObject *, char *, ...);
+# else
static PyObject* (*py3__PyObject_CallFunction_SizeT)(PyObject *, char *, ...);
+# endif
static PyObject* (*py3_PyObject_Call)(PyObject *, PyObject *, PyObject *);
static PyObject* (*py3_PyEval_GetGlobals)(void);
static PyObject* (*py3_PyEval_GetLocals)(void);
@@ -590,6 +618,14 @@ static struct
{"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString},
{"PyErr_SetObject", (PYTHON_PROC*)&py3_PyErr_SetObject},
{"PyErr_ExceptionMatches", (PYTHON_PROC*)&py3_PyErr_ExceptionMatches},
+# if defined(USE_LIMITED_API) \
+ && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
+# if Py_LIMITED_API+0 >= 0x030a00A7
+ {"_Py_IncRef", (PYTHON_PROC*)&py3__Py_IncRef},
+# else
+ {"Py_IncRef", (PYTHON_PROC*)&py3_Py_IncRef},
+# endif
+# endif
# ifdef USE_LIMITED_API
{"Py_CompileString", (PYTHON_PROC*)&py3_Py_CompileString},
{"PyEval_EvalCode", (PYTHON_PROC*)&PyEval_EvalCode},
@@ -601,7 +637,11 @@ static struct
{"PyObject_HasAttrString", (PYTHON_PROC*)&py3_PyObject_HasAttrString},
{"PyObject_SetAttrString", (PYTHON_PROC*)&py3_PyObject_SetAttrString},
{"PyObject_CallFunctionObjArgs", (PYTHON_PROC*)&py3_PyObject_CallFunctionObjArgs},
+# if PY_VERSION_HEX >= 0x030d0000
+ {"PyObject_CallFunction", (PYTHON_PROC*)&py3_PyObject_CallFunction},
+# else
{"_PyObject_CallFunction_SizeT", (PYTHON_PROC*)&py3__PyObject_CallFunction_SizeT},
+# endif
{"PyObject_Call", (PYTHON_PROC*)&py3_PyObject_Call},
{"PyEval_GetGlobals", (PYTHON_PROC*)&py3_PyEval_GetGlobals},
{"PyEval_GetLocals", (PYTHON_PROC*)&py3_PyEval_GetLocals},
@@ -762,6 +802,20 @@ py3__Py_XDECREF(PyObject *op)
# define Py_XDECREF(op) py3__Py_XDECREF(_PyObject_CAST(op))
# endif
+# if defined(USE_LIMITED_API) \
+ && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
+ static inline void
+py3__Py_XINCREF(PyObject *op)
+{
+ if (op != NULL)
+ {
+ Py_INCREF(op);
+ }
+}
+# undef Py_XINCREF
+# define Py_XINCREF(op) py3__Py_XINCREF(_PyObject_CAST(op))
+# endif
+
# if PY_VERSION_HEX >= 0x030900b0
static inline int
py3_PyType_HasFeature(PyTypeObject *type, unsigned long feature)
@@ -1067,7 +1121,7 @@ static int python_end_called = FALSE;
#ifdef USE_LIMITED_API
# define DESTRUCTOR_FINISH(self) \
- ((freefunc)PyType_GetSlot(Py_TYPE(self), Py_tp_free))((PyObject*)self)
+ ((freefunc)PyType_GetSlot(Py_TYPE((PyObject*)self), Py_tp_free))((PyObject*)self)
#else
# define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self)
#endif
diff --git a/src/indent.c b/src/indent.c
index 777db24..0d6fadb 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -996,7 +996,7 @@ get_breakindent_win(
# else
if (wp->w_briopt_vcol == 0)
prev_indent = get_indent_str(line,
- (int)wp->w_buffer->b_p_ts, no_ts);
+ (int)wp->w_buffer->b_p_ts, no_ts);
# endif
prev_tick = CHANGEDTICK(wp->w_buffer);
prev_listopt = wp->w_briopt_list;
diff --git a/src/insexpand.c b/src/insexpand.c
index c673df9..af818d4 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -58,7 +58,7 @@ static char *ctrl_x_msgs[] =
N_(" Command-line completion (^V^N^P)"),
N_(" User defined completion (^U^N^P)"),
N_(" Omni completion (^O^N^P)"),
- N_(" Spelling suggestion (s^N^P)"),
+ N_(" Spelling suggestion (^S^N^P)"),
N_(" Keyword Local completion (^N^P)"),
NULL, // CTRL_X_EVAL doesn't use msg.
N_(" Command-line completion (^V^N^P)"),
@@ -114,6 +114,8 @@ struct compl_S
int cp_flags; // CP_ values
int cp_number; // sequence number
int cp_score; // fuzzy match score
+ int cp_user_hlattr; // highlight attribute to combine with
+ int cp_user_kind_hlattr; // highlight attribute for kind
};
// values for cp_flags
@@ -203,7 +205,9 @@ static int compl_opt_suppress_empty = FALSE;
static int compl_selected_item = -1;
-static int ins_compl_add(char_u *str, int len, char_u *fname, char_u **cptext, typval_T *user_data, int cdir, int flags, int adup);
+static int *compl_fuzzy_scores;
+
+static int ins_compl_add(char_u *str, int len, char_u *fname, char_u **cptext, typval_T *user_data, int cdir, int flags, int adup, int user_hlattr, int user_kind_hlattr);
static void ins_compl_longest_match(compl_T *match);
static void ins_compl_del_pum(void);
static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir);
@@ -743,7 +747,7 @@ ins_compl_add_infercase(
if (icase)
flags |= CP_ICASE;
- res = ins_compl_add(str, len, fname, NULL, NULL, dir, flags, FALSE);
+ res = ins_compl_add(str, len, fname, NULL, NULL, dir, flags, FALSE, -1, -1);
vim_free(tofree);
return res;
}
@@ -776,7 +780,9 @@ ins_compl_add(
typval_T *user_data UNUSED, // "user_data" entry or NULL
int cdir,
int flags_arg,
- int adup) // accept duplicate match
+ int adup, // accept duplicate match
+ int user_hlattr,
+ int user_kind_hlattr)
{
compl_T *match;
int dir = (cdir == 0 ? compl_direction : cdir);
@@ -840,6 +846,8 @@ ins_compl_add(
else
match->cp_fname = NULL;
match->cp_flags = flags;
+ match->cp_user_hlattr = user_hlattr;
+ match->cp_user_kind_hlattr = user_kind_hlattr;
if (cptext != NULL)
{
@@ -992,7 +1000,7 @@ ins_compl_add_matches(
for (i = 0; i < num_matches && add_r != FAIL; i++)
if ((add_r = ins_compl_add(matches[i], -1, NULL, NULL, NULL, dir,
- CP_FAST | (icase ? CP_ICASE : 0), FALSE)) == OK)
+ CP_FAST | (icase ? CP_ICASE : 0), FALSE, -1, -1)) == OK)
// if dir was BACKWARD then honor it just once
dir = FORWARD;
FreeWild(num_matches, matches);
@@ -1306,7 +1314,13 @@ ins_compl_build_pum(void)
{
did_find_shown_match = TRUE;
max_fuzzy_score = compl->cp_score;
- compl_shown_match = compl;
+ if (!compl_no_select)
+ compl_shown_match = compl;
+ }
+
+ if (!shown_match_ok && compl == compl_shown_match && !compl_no_select)
+ {
+ cur = i;
shown_match_ok = TRUE;
}
@@ -1318,8 +1332,6 @@ ins_compl_build_pum(void)
&& (max_fuzzy_score > 0
|| (compl_leader == NULL || lead_len == 0)))
{
- shown_match_ok = TRUE;
- cur = 0;
if (match_at_original_text(compl_shown_match))
compl_shown_match = shown_compl;
}
@@ -1333,6 +1345,8 @@ ins_compl_build_pum(void)
compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND];
compl_match_array[i].pum_info = compl->cp_text[CPT_INFO];
compl_match_array[i].pum_score = compl->cp_score;
+ compl_match_array[i].pum_user_hlattr = compl->cp_user_hlattr;
+ compl_match_array[i].pum_user_kind_hlattr = compl->cp_user_kind_hlattr;
if (compl->cp_text[CPT_MENU] != NULL)
compl_match_array[i++].pum_extra =
compl->cp_text[CPT_MENU];
@@ -1367,6 +1381,7 @@ ins_compl_build_pum(void)
// sort by the largest score of fuzzy match
qsort(compl_match_array, (size_t)compl_match_arraysize,
sizeof(pumitem_T), ins_compl_fuzzy_cmp);
+ shown_match_ok = TRUE;
}
if (!shown_match_ok) // no displayed match at all
@@ -2833,6 +2848,14 @@ theend:
#endif // FEAT_COMPL_FUNC
#if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) || defined(PROTO)
+
+ static inline int
+get_user_highlight_attr(char_u *hlname)
+{
+ if (hlname != NULL && *hlname != NUL)
+ return syn_name2attr(hlname);
+ return -1;
+}
/*
* Add a match to the list of matches from a typeval_T.
* If the given string is already in the list of completions, then return
@@ -2850,6 +2873,10 @@ ins_compl_add_tv(typval_T *tv, int dir, int fast)
char_u *(cptext[CPT_COUNT]);
typval_T user_data;
int status;
+ char_u *user_hlname;
+ char_u *user_kind_hlname;
+ int user_hlattr = -1;
+ int user_kind_hlattr = -1;
user_data.v_type = VAR_UNKNOWN;
if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL)
@@ -2859,6 +2886,13 @@ ins_compl_add_tv(typval_T *tv, int dir, int fast)
cptext[CPT_MENU] = dict_get_string(tv->vval.v_dict, "menu", FALSE);
cptext[CPT_KIND] = dict_get_string(tv->vval.v_dict, "kind", FALSE);
cptext[CPT_INFO] = dict_get_string(tv->vval.v_dict, "info", FALSE);
+
+ user_hlname = dict_get_string(tv->vval.v_dict, "hl_group", FALSE);
+ user_hlattr = get_user_highlight_attr(user_hlname);
+
+ user_kind_hlname = dict_get_string(tv->vval.v_dict, "kind_hlgroup", FALSE);
+ user_kind_hlattr = get_user_highlight_attr(user_kind_hlname);
+
dict_get_tv(tv->vval.v_dict, "user_data", &user_data);
if (dict_get_string(tv->vval.v_dict, "icase", FALSE) != NULL
&& dict_get_number(tv->vval.v_dict, "icase"))
@@ -2881,7 +2915,8 @@ ins_compl_add_tv(typval_T *tv, int dir, int fast)
clear_tv(&user_data);
return FAIL;
}
- status = ins_compl_add(word, -1, NULL, cptext, &user_data, dir, flags, dup);
+ status = ins_compl_add(word, -1, NULL, cptext,
+ &user_data, dir, flags, dup, user_hlattr, user_kind_hlattr);
if (status != OK)
clear_tv(&user_data);
return status;
@@ -2968,7 +3003,7 @@ set_completion(colnr_T startcol, list_T *list)
flags |= CP_ICASE;
if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
-1, NULL, NULL, NULL, 0,
- flags | CP_FAST, FALSE) != OK)
+ flags | CP_FAST, FALSE, -1, -1) != OK)
return;
ctrl_x_mode = CTRL_X_EVAL;
@@ -3318,7 +3353,8 @@ typedef struct
process_next_cpt_value(
ins_compl_next_state_T *st,
int *compl_type_arg,
- pos_T *start_match_pos)
+ pos_T *start_match_pos,
+ int in_fuzzy)
{
int compl_type = -1;
int status = INS_COMPL_CPT_OK;
@@ -3334,7 +3370,7 @@ process_next_cpt_value(
st->first_match_pos = *start_match_pos;
// Move the cursor back one character so that ^N can match the
// word immediately after the cursor.
- if (ctrl_x_mode_normal() && dec(&st->first_match_pos) < 0)
+ if (ctrl_x_mode_normal() && (!in_fuzzy && dec(&st->first_match_pos) < 0))
{
// Move the cursor to after the last character in the
// buffer, so that word at start of buffer is found
@@ -3502,6 +3538,18 @@ get_next_tag_completion(void)
}
/*
+ * Compare function for qsort
+ */
+static int compare_scores(const void *a, const void *b)
+{
+ int idx_a = *(const int *)a;
+ int idx_b = *(const int *)b;
+ int score_a = compl_fuzzy_scores[idx_a];
+ int score_b = compl_fuzzy_scores[idx_b];
+ return (score_a > score_b) ? -1 : (score_a < score_b) ? 1 : 0;
+}
+
+/*
* Get the next set of filename matching "compl_pattern".
*/
static void
@@ -3509,6 +3557,77 @@ get_next_filename_completion(void)
{
char_u **matches;
int num_matches;
+ char_u *ptr;
+ garray_T fuzzy_indices;
+ int i;
+ int score;
+ char_u *leader = ins_compl_leader();
+ size_t leader_len = STRLEN(leader);
+ int in_fuzzy = ((get_cot_flags() & COT_FUZZY) != 0 && leader_len > 0);
+ char_u **sorted_matches;
+ int *fuzzy_indices_data;
+ char_u *last_sep = NULL;
+ size_t path_with_wildcard_len;
+ char_u *path_with_wildcard;
+
+#ifdef BACKSLASH_IN_FILENAME
+ char pathsep = (curbuf->b_p_csl[0] == 's') ?
+ '/' : (curbuf->b_p_csl[0] == 'b') ? '\\' : PATHSEP;
+#else
+ char pathsep = PATHSEP;
+#endif
+
+ if (in_fuzzy)
+ {
+#ifdef BACKSLASH_IN_FILENAME
+ if (curbuf->b_p_csl[0] == 's')
+ {
+ for (i = 0; i < leader_len; i++)
+ {
+ if (leader[i] == '\\')
+ leader[i] = '/';
+ }
+ }
+ else if (curbuf->b_p_csl[0] == 'b')
+ {
+ for (i = 0; i < leader_len; i++)
+ {
+ if (leader[i] == '/')
+ leader[i] = '\\';
+ }
+ }
+#endif
+ last_sep = vim_strrchr(leader, pathsep);
+ if (last_sep == NULL)
+ {
+ // No path separator or separator is the last character,
+ // fuzzy match the whole leader
+ vim_free(compl_pattern);
+ compl_pattern = vim_strsave((char_u *)"*");
+ compl_patternlen = STRLEN(compl_pattern);
+ }
+ else if (*(last_sep + 1) == '\0')
+ in_fuzzy = FALSE;
+ else
+ {
+ // Split leader into path and file parts
+ int path_len = last_sep - leader + 1;
+ path_with_wildcard_len = path_len + 2;
+ path_with_wildcard = alloc(path_with_wildcard_len);
+ if (path_with_wildcard != NULL)
+ {
+ vim_strncpy(path_with_wildcard, leader, path_len);
+ vim_strcat(path_with_wildcard, (char_u *)"*", path_with_wildcard_len);
+ vim_free(compl_pattern);
+ compl_pattern = path_with_wildcard;
+ compl_patternlen = STRLEN(compl_pattern);
+
+ // Move leader to the file part
+ leader = last_sep + 1;
+ leader_len = STRLEN(leader);
+ }
+ }
+ }
if (expand_wildcards(1, &compl_pattern, &num_matches, &matches,
EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) != OK)
@@ -3519,12 +3638,9 @@ get_next_filename_completion(void)
#ifdef BACKSLASH_IN_FILENAME
if (curbuf->b_p_csl[0] != NUL)
{
- int i;
-
for (i = 0; i < num_matches; ++i)
{
- char_u *ptr = matches[i];
-
+ ptr = matches[i];
while (*ptr != NUL)
{
if (curbuf->b_p_csl[0] == 's' && *ptr == '\\')
@@ -3536,7 +3652,53 @@ get_next_filename_completion(void)
}
}
#endif
- ins_compl_add_matches(num_matches, matches, p_fic || p_wic);
+
+ if (in_fuzzy)
+ {
+ ga_init2(&fuzzy_indices, sizeof(int), 10);
+ compl_fuzzy_scores = (int *)alloc(sizeof(int) * num_matches);
+
+ for (i = 0; i < num_matches; i++)
+ {
+ ptr = matches[i];
+ score = fuzzy_match_str(ptr, leader);
+ if (score > 0)
+ {
+ if (ga_grow(&fuzzy_indices, 1) == OK)
+ {
+ ((int *)fuzzy_indices.ga_data)[fuzzy_indices.ga_len] = i;
+ compl_fuzzy_scores[i] = score;
+ fuzzy_indices.ga_len++;
+ }
+ }
+ }
+
+ // prevent qsort from deref NULL pointer
+ if (fuzzy_indices.ga_len > 0)
+ {
+ fuzzy_indices_data = (int *)fuzzy_indices.ga_data;
+ qsort(fuzzy_indices_data, fuzzy_indices.ga_len, sizeof(int), compare_scores);
+
+ sorted_matches = (char_u **)alloc(sizeof(char_u *) * fuzzy_indices.ga_len);
+ for (i = 0; i < fuzzy_indices.ga_len; ++i)
+ sorted_matches[i] = vim_strsave(matches[fuzzy_indices_data[i]]);
+
+ FreeWild(num_matches, matches);
+ matches = sorted_matches;
+ num_matches = fuzzy_indices.ga_len;
+ }
+ else if (leader_len > 0)
+ {
+ FreeWild(num_matches, matches);
+ num_matches = 0;
+ }
+
+ vim_free(compl_fuzzy_scores);
+ ga_clear(&fuzzy_indices);
+ }
+
+ if (num_matches > 0)
+ ins_compl_add_matches(num_matches, matches, p_fic || p_wic);
}
/*
@@ -3683,8 +3845,10 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos)
int save_p_scs;
int save_p_ws;
int looped_around = FALSE;
- char_u *ptr;
- int len;
+ char_u *ptr = NULL;
+ int len = 0;
+ int in_fuzzy = (get_cot_flags() & COT_FUZZY) != 0 && compl_length > 0;
+ char_u *leader = ins_compl_leader();
// If 'infercase' is set, don't use 'smartcase' here
save_p_scs = p_scs;
@@ -3698,7 +3862,7 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos)
save_p_ws = p_ws;
if (st->ins_buf != curbuf)
p_ws = FALSE;
- else if (*st->e_cpt == '.')
+ else if (*st->e_cpt == '.' && !in_fuzzy)
p_ws = TRUE;
looped_around = FALSE;
for (;;)
@@ -3709,9 +3873,13 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos)
// ctrl_x_mode_line_or_eval() || word-wise search that
// has added a word that was at the beginning of the line
- if (ctrl_x_mode_line_or_eval() || (compl_cont_status & CONT_SOL))
+ if ((ctrl_x_mode_whole_line() && !in_fuzzy) || ctrl_x_mode_eval() || (compl_cont_status & CONT_SOL))
found_new_match = search_for_exact_line(st->ins_buf,
st->cur_match_pos, compl_direction, compl_pattern);
+ else if (in_fuzzy)
+ found_new_match = search_for_fuzzy_match(st->ins_buf,
+ st->cur_match_pos, leader, compl_direction,
+ start_pos, &len, &ptr, ctrl_x_mode_whole_line());
else
found_new_match = searchit(NULL, st->ins_buf, st->cur_match_pos,
NULL, compl_direction, compl_pattern, compl_patternlen,
@@ -3760,8 +3928,9 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos)
&& start_pos->col == st->cur_match_pos->col)
continue;
- ptr = ins_compl_get_next_word_or_line(st->ins_buf, st->cur_match_pos,
- &len, &cont_s_ipos);
+ if (!in_fuzzy)
+ ptr = ins_compl_get_next_word_or_line(st->ins_buf, st->cur_match_pos,
+ &len, &cont_s_ipos);
if (ptr == NULL)
continue;
@@ -3860,6 +4029,7 @@ ins_compl_get_exp(pos_T *ini)
int i;
int found_new_match;
int type = ctrl_x_mode;
+ int in_fuzzy = (get_cot_flags() & COT_FUZZY) != 0;
if (!compl_started)
{
@@ -3886,7 +4056,7 @@ ins_compl_get_exp(pos_T *ini)
compl_old_match = compl_curr_match; // remember the last current match
st.cur_match_pos = (compl_dir_forward())
- ? &st.last_match_pos : &st.first_match_pos;
+ ? &st.last_match_pos : &st.first_match_pos;
// For ^N/^P loop over all the flags/windows/buffers in 'complete'.
for (;;)
@@ -3900,7 +4070,7 @@ ins_compl_get_exp(pos_T *ini)
if ((ctrl_x_mode_normal() || ctrl_x_mode_line_or_eval())
&& (!compl_started || st.found_all))
{
- int status = process_next_cpt_value(&st, &type, ini);
+ int status = process_next_cpt_value(&st, &type, ini, in_fuzzy);
if (status == INS_COMPL_CPT_END)
break;
@@ -4100,10 +4270,10 @@ find_comp_when_fuzzy(void)
int is_backward = compl_shows_dir_backward();
compl_T *comp = NULL;
- if (compl_match_array == NULL ||
- (is_forward && compl_selected_item == compl_match_arraysize - 1)
+ if ((is_forward && compl_selected_item == compl_match_arraysize - 1)
|| (is_backward && compl_selected_item == 0))
- return compl_first_match;
+ return compl_first_match != compl_shown_match ? compl_first_match :
+ (compl_first_match->cp_prev ? compl_first_match->cp_prev : NULL);
if (is_forward)
target_idx = compl_selected_item + 1;
@@ -4621,7 +4791,6 @@ get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col)
}
compl_patternlen = STRLEN(compl_pattern);
-
return OK;
}
@@ -5066,7 +5235,7 @@ ins_compl_start(void)
if (p_ic)
flags |= CP_ICASE;
if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
- -1, NULL, NULL, NULL, 0, flags, FALSE) != OK)
+ -1, NULL, NULL, NULL, 0, flags, FALSE, -1, -1) != OK)
{
VIM_CLEAR(compl_pattern);
compl_patternlen = 0;
diff --git a/src/list.c b/src/list.c
index 9479b4b..36ce494 100644
--- a/src/list.c
+++ b/src/list.c
@@ -365,8 +365,7 @@ list_len(list_T *l)
list_equal(
list_T *l1,
list_T *l2,
- int ic, // ignore case for strings
- int recursive) // TRUE when used recursively
+ int ic) // ignore case for strings
{
listitem_T *item1, *item2;
@@ -386,7 +385,7 @@ list_equal(
for (item1 = l1->lv_first, item2 = l2->lv_first;
item1 != NULL && item2 != NULL;
item1 = item1->li_next, item2 = item2->li_next)
- if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive))
+ if (!tv_equal(&item1->li_tv, &item2->li_tv, ic))
return FALSE;
return item1 == NULL && item2 == NULL;
}
@@ -2727,7 +2726,7 @@ list_count(list_T *l, typval_T *needle, long idx, int ic)
}
for ( ; li != NULL; li = li->li_next)
- if (tv_equal(&li->li_tv, needle, ic, FALSE))
+ if (tv_equal(&li->li_tv, needle, ic))
++n;
return n;
diff --git a/src/macros.h b/src/macros.h
index 190778e..38983ac 100644
--- a/src/macros.h
+++ b/src/macros.h
@@ -194,7 +194,11 @@
#ifdef HAVE_LSTAT
# define mch_lstat(n, p) lstat((n), (p))
#else
-# define mch_lstat(n, p) mch_stat((n), (p))
+# ifdef MSWIN
+# define mch_lstat(n, p) vim_lstat((n), (p))
+# else
+# define mch_lstat(n, p) mch_stat((n), (p))
+# endif
#endif
#ifdef VMS
diff --git a/src/map.c b/src/map.c
index c416c0a..91ab6e3 100644
--- a/src/map.c
+++ b/src/map.c
@@ -85,6 +85,8 @@ map_free(mapblock_T **mpp)
mp = *mpp;
vim_free(mp->m_keys);
+ if (mp->m_alt != NULL)
+ mp->m_alt->m_alt = NULL;
vim_free(mp->m_str);
vim_free(mp->m_orig_str);
*mpp = mp->m_next;
@@ -213,7 +215,7 @@ theend:
--map_locked;
}
- static int
+ static mapblock_T *
map_add(
mapblock_T **map_table,
mapblock_T **abbr_table,
@@ -236,7 +238,7 @@ map_add(
mapblock_T *mp = ALLOC_CLEAR_ONE(mapblock_T);
if (mp == NULL)
- return FAIL;
+ return NULL;
// If CTRL-C has been mapped, don't always use it for Interrupting.
if (*keys == Ctrl_C)
@@ -256,7 +258,7 @@ map_add(
vim_free(mp->m_str);
vim_free(mp->m_orig_str);
vim_free(mp);
- return FAIL;
+ return NULL;
}
mp->m_keylen = (int)STRLEN(mp->m_keys);
mp->m_noremap = noremap;
@@ -292,7 +294,7 @@ map_add(
mp->m_next = map_table[n];
map_table[n] = mp;
}
- return OK;
+ return mp;
}
/*
@@ -444,6 +446,7 @@ do_map(
{
char_u *keys;
mapblock_T *mp, **mpp;
+ mapblock_T *mp_result[2] = {NULL, NULL};
char_u *rhs;
char_u *p;
int n;
@@ -844,6 +847,8 @@ do_map(
retval = 4; // no mem
goto theend;
}
+ if (mp->m_alt != NULL)
+ mp->m_alt = mp->m_alt->m_alt = NULL;
vim_free(mp->m_str);
mp->m_str = newstr;
vim_free(mp->m_orig_str);
@@ -858,6 +863,7 @@ do_map(
mp->m_script_ctx = current_sctx;
mp->m_script_ctx.sc_lnum += SOURCING_LNUM;
#endif
+ mp_result[keyround - 1] = mp;
did_it = TRUE;
}
}
@@ -921,18 +927,25 @@ do_map(
continue; // have added the new entry already
// Get here when adding a new entry to the maphash[] list or abbrlist.
- if (map_add(map_table, abbr_table, keys, rhs, orig_rhs,
- noremap, nowait, silent, mode, abbrev,
+ mp_result[keyround - 1] = map_add(map_table, abbr_table, keys,
+ rhs, orig_rhs, noremap, nowait, silent, mode, abbrev,
#ifdef FEAT_EVAL
expr, /* sid */ 0, /* scriptversion */ 0, /* lnum */ 0,
#endif
- keyround1_simplified) == FAIL)
+ keyround1_simplified);
+ if (mp_result[keyround - 1] == NULL)
{
retval = 4; // no mem
goto theend;
}
}
+ if (mp_result[0] != NULL && mp_result[1] != NULL)
+ {
+ mp_result[0]->m_alt = mp_result[1];
+ mp_result[1]->m_alt = mp_result[0];
+ }
+
theend:
vim_free(keys_buf);
vim_free(alt_keys_buf);
@@ -2710,6 +2723,7 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
int nowait;
char_u *arg;
int dict_only;
+ mapblock_T *mp_result[2] = {NULL, NULL};
// If first arg is a dict, then that's the only arg permitted.
dict_only = argvars[0].v_type == VAR_DICT;
@@ -2806,12 +2820,20 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
do_map(MAPTYPE_UNMAP, arg, mode, is_abbr);
vim_free(arg);
- (void)map_add(map_table, abbr_table, lhsraw, rhs, orig_rhs, noremap,
- nowait, silent, mode, is_abbr, expr, sid, scriptversion, lnum, 0);
+ mp_result[0] = map_add(map_table, abbr_table, lhsraw, rhs, orig_rhs,
+ noremap, nowait, silent, mode, is_abbr, expr, sid,
+ scriptversion, lnum, 0);
if (lhsrawalt != NULL)
- (void)map_add(map_table, abbr_table, lhsrawalt, rhs, orig_rhs, noremap,
- nowait, silent, mode, is_abbr, expr, sid, scriptversion,
- lnum, 1);
+ mp_result[1] = map_add(map_table, abbr_table, lhsrawalt, rhs, orig_rhs,
+ noremap, nowait, silent, mode, is_abbr, expr, sid,
+ scriptversion, lnum, 1);
+
+ if (mp_result[0] != NULL && mp_result[1] != NULL)
+ {
+ mp_result[0]->m_alt = mp_result[1];
+ mp_result[1]->m_alt = mp_result[0];
+ }
+
vim_free(arg_buf);
}
#endif
diff --git a/src/mark.c b/src/mark.c
index 22e3c62..9f6a9cc 100644
--- a/src/mark.c
+++ b/src/mark.c
@@ -130,6 +130,38 @@ setmark_pos(int c, pos_T *pos, int fnum)
}
/*
+ * Delete every entry referring to file 'fnum' from both the jumplist and the
+ * tag stack.
+ */
+ void
+mark_forget_file(win_T *wp, int fnum)
+{
+ int i;
+
+ for (i = wp->w_jumplistlen - 1; i >= 0; --i)
+ if (wp->w_jumplist[i].fmark.fnum == fnum)
+ {
+ vim_free(wp->w_jumplist[i].fname);
+ if (wp->w_jumplistidx > i)
+ --wp->w_jumplistidx;
+ --wp->w_jumplistlen;
+ mch_memmove(&wp->w_jumplist[i], &wp->w_jumplist[i + 1],
+ (wp->w_jumplistlen - i) * sizeof(wp->w_jumplist[i]));
+ }
+
+ for (i = wp->w_tagstacklen - 1; i >= 0; --i)
+ if (wp->w_tagstack[i].fmark.fnum == fnum)
+ {
+ tagstack_clear_entry(&wp->w_tagstack[i]);
+ if (wp->w_tagstackidx > i)
+ --wp->w_tagstackidx;
+ --wp->w_tagstacklen;
+ mch_memmove(&wp->w_tagstack[i], &wp->w_tagstack[i + 1],
+ (wp->w_tagstacklen - i) * sizeof(wp->w_tagstack[i]));
+ }
+}
+
+/*
* Set the previous context mark to the current position and add it to the
* jump list.
*/
diff --git a/src/mbyte.c b/src/mbyte.c
index 07446ca..d8c47ac 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -102,7 +102,7 @@
# define WINBYTE BYTE
#endif
-#if (defined(MSWIN) || defined(WIN32UNIX)) && !defined(__MINGW32__)
+#if defined(MSWIN) || defined(WIN32UNIX)
# include <winnls.h>
#endif
@@ -3801,6 +3801,15 @@ utf_strnicmp(
* two characters otherwise.
*/
int
+mb_strnicmp2(char_u *s1, char_u *s2, size_t n1, size_t n2)
+{
+ if (n1 == n2 || !enc_utf8)
+ return mb_strnicmp(s1, s2, n1);
+ else
+ return utf_strnicmp(s1, s2, n1, n2);
+}
+
+ int
mb_strnicmp(char_u *s1, char_u *s2, size_t nn)
{
int i, l;
diff --git a/src/memline.c b/src/memline.c
index 6c63fad..b93eb0a 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -1975,7 +1975,7 @@ recover_names(
if (after_pathsep(dir_name, p) && len > 1 && p[-1] == p[-2])
{
// Ends with '//', Use Full path for swap name
- tail = make_percent_swname(dir_name, fname_res);
+ tail = make_percent_swname(dir_name, p, fname_res);
}
else
#endif
@@ -2143,7 +2143,7 @@ recover_names(
* removed.
*/
char_u *
-make_percent_swname(char_u *dir, char_u *name)
+make_percent_swname(char_u *dir, char_u *dir_end, char_u *name)
{
char_u *d = NULL, *s, *f;
@@ -2159,7 +2159,7 @@ make_percent_swname(char_u *dir, char_u *name)
if (vim_ispathsep(*d))
*d = '%';
- dir[STRLEN(dir) - 1] = NUL; // remove one trailing slash
+ dir_end[-1] = NUL; // remove one trailing slash
d = concat_fnames(dir, s, TRUE);
vim_free(s);
}
@@ -2710,7 +2710,7 @@ ml_get_buf_len(buf_T *buf, linenr_T lnum)
char_u *line;
if (*(line = ml_get_buf(buf, lnum, FALSE)) == NUL)
- return 0;
+ return 0;
if (buf->b_ml.ml_line_textlen <= 0)
buf->b_ml.ml_line_textlen = (int)STRLEN(line) + 1;
@@ -4676,7 +4676,7 @@ makeswapname(
if (after_pathsep(dir_name, s) && len > 1 && s[-1] == s[-2])
{ // Ends with '//', Use Full path
r = NULL;
- if ((s = make_percent_swname(dir_name, fname_res)) != NULL)
+ if ((s = make_percent_swname(dir_name, s, fname_res)) != NULL)
{
r = modname(s, (char_u *)".swp", FALSE);
vim_free(s);
diff --git a/src/misc1.c b/src/misc1.c
index 8348488..0898efb 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -678,17 +678,6 @@ get_mode(char_u *buf)
buf[i++] = 't';
}
#endif
- else if (VIsual_active)
- {
- if (VIsual_select)
- buf[i++] = VIsual_mode + 's' - 'v';
- else
- {
- buf[i++] = VIsual_mode;
- if (restart_VIsual_select)
- buf[i++] = 's';
- }
- }
else if (State == MODE_HITRETURN || State == MODE_ASKMORE
|| State == MODE_SETWSIZE
|| State == MODE_CONFIRM)
@@ -731,6 +720,17 @@ get_mode(char_u *buf)
if ((State & MODE_CMDLINE) && cmdline_overstrike())
buf[i++] = 'r';
}
+ else if (VIsual_active)
+ {
+ if (VIsual_select)
+ buf[i++] = VIsual_mode + 's' - 'v';
+ else
+ {
+ buf[i++] = VIsual_mode;
+ if (restart_VIsual_select)
+ buf[i++] = 's';
+ }
+ }
else
{
buf[i++] = 'n';
diff --git a/src/misc2.c b/src/misc2.c
index c07ed80..b5044fb 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -72,7 +72,7 @@ coladvance_force(colnr_T wcol)
* Get the screen position of character col with a coladd in the cursor line.
*/
int
-getviscol2(colnr_T col, colnr_T coladd UNUSED)
+getviscol2(colnr_T col, colnr_T coladd)
{
colnr_T x;
pos_T pos;
diff --git a/src/move.c b/src/move.c
index 71654dd..f2780e5 100644
--- a/src/move.c
+++ b/src/move.c
@@ -3281,10 +3281,13 @@ pagescroll(int dir, long count, int half)
MAX(1, p_window - 2) : get_scroll_overlap(dir));
nochange = scroll_with_sms(dir, count, &count);
- // Place cursor at top or bottom of window.
- validate_botline();
- curwin->w_cursor.lnum = (dir == FORWARD ? curwin->w_topline
+ if (!nochange)
+ {
+ // Place cursor at top or bottom of window.
+ validate_botline();
+ curwin->w_cursor.lnum = (dir == FORWARD ? curwin->w_topline
: curwin->w_botline - 1);
+ }
}
if (get_scrolloff_value() > 0)
diff --git a/src/netbeans.c b/src/netbeans.c
index 3b68869..781caa8 100644
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -1689,8 +1689,10 @@ nb_do_cmd(
if (streq((char *)args, "T") && buf->bufp != curbuf)
{
exarg_T exarg;
+ CLEAR_FIELD(exarg);
exarg.cmd = (char_u *)"goto";
exarg.forceit = FALSE;
+ exarg.cmdidx = CMD_USER;
dosetvisible = TRUE;
goto_buffer(&exarg, DOBUF_FIRST, FORWARD, buf->bufp->b_fnum);
do_update = 1;
diff --git a/src/normal.c b/src/normal.c
index b55d941..a929dd8 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -4462,7 +4462,7 @@ nv_brackets(cmdarg_T *cap)
SAFE_islower(cap->nchar) ? ACTION_SHOW : ACTION_GOTO,
cap->cmdchar == ']' ? curwin->w_cursor.lnum + 1 : (linenr_T)1,
(linenr_T)MAXLNUM,
- FALSE);
+ FALSE);
vim_free(ptr);
curwin->w_set_curswant = TRUE;
}
@@ -6598,8 +6598,12 @@ nv_wordcmd(cmdarg_T *cap)
// "ce" will change until the end of the next word, but "cw"
// will change only one character! This is done by setting
// flag.
- cap->oap->inclusive = TRUE;
- word_end = TRUE;
+ // This can be configured using :set cpo-z
+ if (vim_strchr(p_cpo, CPO_WORD) != NULL)
+ {
+ cap->oap->inclusive = TRUE;
+ word_end = TRUE;
+ }
flag = TRUE;
}
}
diff --git a/src/ops.c b/src/ops.c
index eb75c34..eb8f64c 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -240,8 +240,8 @@ shift_line(
if (round) // round off indent
{
- i = count / sw_val; // number of 'shiftwidth' rounded down
- j = count % sw_val; // extra spaces
+ i = trim_to_int(count) / sw_val; // number of 'shiftwidth' rounded down
+ j = trim_to_int(count) % sw_val; // extra spaces
if (j && left) // first remove extra spaces
--amount;
if (left)
@@ -676,6 +676,7 @@ op_delete(oparg_T *oap)
&& !oap->block_mode
&& oap->line_count > 1
&& oap->motion_force == NUL
+ && (vim_strchr(p_cpo, CPO_WORD) != NULL)
&& oap->op_type == OP_DELETE)
{
ptr = ml_get(oap->end.lnum) + oap->end.col;
@@ -2673,6 +2674,8 @@ do_addsub(
int do_bin;
int do_alpha;
int do_unsigned;
+ int do_blank;
+ int blank_unsigned = FALSE; // blank: treat as unsigned?
int firstdigit;
int subtract;
int negative = FALSE;
@@ -2690,6 +2693,7 @@ do_addsub(
do_bin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin"
do_alpha = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha"
do_unsigned = (vim_strchr(curbuf->b_p_nf, 'u') != NULL); // "Unsigned"
+ do_blank = (vim_strchr(curbuf->b_p_nf, 'k') != NULL); // "blanK"
if (virtual_active())
{
@@ -2813,8 +2817,13 @@ do_addsub(
&& (!has_mbyte || !(*mb_head_off)(ptr, ptr + col - 1))
&& !do_unsigned)
{
- negative = TRUE;
- was_positive = FALSE;
+ if (do_blank && col >= 2 && !VIM_ISWHITE(ptr[col - 2]))
+ blank_unsigned = TRUE;
+ else
+ {
+ negative = TRUE;
+ was_positive = FALSE;
+ }
}
}
@@ -2875,10 +2884,16 @@ do_addsub(
&& !visual
&& !do_unsigned)
{
- // negative number
- --col;
- negative = TRUE;
+ if (do_blank && col >= 2 && !VIM_ISWHITE(ptr[col - 2]))
+ blank_unsigned = TRUE;
+ else
+ {
+ // negative number
+ --col;
+ negative = TRUE;
+ }
}
+
// get the number value (unsigned)
if (visual && VIsual_mode != 'V')
maxlen = (curbuf->b_visual.vi_curswant == MAXCOL
@@ -2938,7 +2953,7 @@ do_addsub(
negative = FALSE;
}
- if (do_unsigned && negative)
+ if ((do_unsigned || blank_unsigned) && negative)
{
if (subtract)
// sticking at zero.
diff --git a/src/option.h b/src/option.h
index 91d8d95..fba2672 100644
--- a/src/option.h
+++ b/src/option.h
@@ -212,6 +212,7 @@ typedef enum {
#define CPO_REPLCNT 'X' // "R" with a count only deletes chars once
#define CPO_YANK 'y'
#define CPO_KEEPRO 'Z' // don't reset 'readonly' on ":w!"
+#define CPO_WORD 'z' // do not special-case word motions cw and dw
#define CPO_DOLLAR '$'
#define CPO_FILTER '!'
#define CPO_MATCH '%'
@@ -231,9 +232,9 @@ typedef enum {
#define CPO_SCOLON ';' // using "," and ";" will skip over char if
// cursor would not move
// default values for Vim, Vi and POSIX
-#define CPO_VIM "aABceFs"
-#define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;"
-#define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\\.;"
+#define CPO_VIM "aABceFsz"
+#define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>;"
+#define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>#{|&/\\.;"
// characters for p_ww option:
#define WW_ALL "bshl<>[]~"
@@ -520,13 +521,13 @@ EXTERN unsigned cot_flags; // flags from 'completeopt'
#define COT_ANY_MENU 0x003 // combination of menu flags
#define COT_LONGEST 0x004 // FALSE: insert full match,
// TRUE: insert longest prefix
-#define COT_PREVIEW 0x008
-#define COT_POPUP 0x010
-#define COT_POPUPHIDDEN 0x020
-#define COT_ANY_PREVIEW 0x038 // combination of preview flags
-#define COT_NOINSERT 0x040 // FALSE: select & insert, TRUE: noinsert
-#define COT_NOSELECT 0x080 // FALSE: select & insert, TRUE: noselect
-#define COT_FUZZY 0x100 // TRUE: fuzzy match enabled
+#define COT_PREVIEW 0x008
+#define COT_POPUP 0x010
+#define COT_POPUPHIDDEN 0x020
+#define COT_ANY_PREVIEW 0x038 // combination of preview flags
+#define COT_NOINSERT 0x040 // FALSE: select & insert, TRUE: noinsert
+#define COT_NOSELECT 0x080 // FALSE: select & insert, TRUE: noselect
+#define COT_FUZZY 0x100 // TRUE: fuzzy match enabled
#ifdef BACKSLASH_IN_FILENAME
EXTERN char_u *p_csl; // 'completeslash'
#endif
@@ -955,7 +956,6 @@ EXTERN int p_sol; // 'startofline'
EXTERN char_u *p_su; // 'suffixes'
EXTERN char_u *p_sws; // 'swapsync'
EXTERN char_u *p_swb; // 'switchbuf'
-EXTERN char_u *p_spk; // 'splitkeep'
EXTERN unsigned swb_flags;
// Keep in sync with p_swb_values in optionstr.c
#define SWB_USEOPEN 0x001
@@ -964,9 +964,14 @@ EXTERN unsigned swb_flags;
#define SWB_NEWTAB 0x008
#define SWB_VSPLIT 0x010
#define SWB_USELAST 0x020
+EXTERN char_u *p_spk; // 'splitkeep'
#ifdef FEAT_SYN_HL
EXTERN char_u *p_syn; // 'syntax'
#endif
+EXTERN char_u *p_tcl; // 'tabclose'
+EXTERN unsigned tcl_flags; // flags from 'tabclose'
+#define TCL_LEFT 0x001
+#define TCL_USELAST 0x002
EXTERN long p_ts; // 'tabstop'
EXTERN int p_tbs; // 'tagbsearch'
EXTERN char_u *p_tc; // 'tagcase'
diff --git a/src/optiondefs.h b/src/optiondefs.h
index 617f3ce..8982ac6 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -621,13 +621,12 @@ static struct vimoption options[] =
{"columns", "co", P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR,
(char_u *)&Columns, PV_NONE, NULL, NULL,
{(char_u *)80L, (char_u *)0L} SCTX_INIT},
- {"comments", "com", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA
- |P_NODUP|P_CURSWANT,
+ {"comments", "com", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP,
(char_u *)&p_com, PV_COM, did_set_comments, NULL,
{(char_u *)"s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-",
(char_u *)0L}
SCTX_INIT},
- {"commentstring", "cms", P_STRING|P_ALLOCED|P_VI_DEF|P_CURSWANT,
+ {"commentstring", "cms", P_STRING|P_ALLOCED|P_VI_DEF,
#ifdef FEAT_FOLDING
(char_u *)&p_cms, PV_CMS, did_set_commentstring, NULL,
{(char_u *)"/* %s */", (char_u *)0L}
@@ -801,7 +800,7 @@ static struct vimoption options[] =
{"debug", NULL, P_STRING|P_VI_DEF,
(char_u *)&p_debug, PV_NONE, did_set_debug, expand_set_debug,
{(char_u *)"", (char_u *)0L} SCTX_INIT},
- {"define", "def", P_STRING|P_ALLOCED|P_VI_DEF|P_CURSWANT,
+ {"define", "def", P_STRING|P_ALLOCED|P_VI_DEF,
#ifdef FEAT_FIND_ID
(char_u *)&p_def, PV_DEF, NULL, NULL,
{(char_u *)"^\\s*#\\s*define", (char_u *)0L}
@@ -2462,6 +2461,9 @@ static struct vimoption options[] =
{(char_u *)0L, (char_u *)0L}
#endif
SCTX_INIT},
+ {"tabclose", "tcl", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
+ (char_u *)&p_tcl, PV_NONE, did_set_tabclose, expand_set_tabclose,
+ {(char_u *)"", (char_u *)0L} SCTX_INIT},
{"tabline", "tal", P_STRING|P_VI_DEF|P_RALL|P_MLE,
#ifdef FEAT_STL_OPT
(char_u *)&p_tal, PV_NONE, did_set_tabline, NULL,
@@ -2852,13 +2854,13 @@ static struct vimoption options[] =
{"window", "wi", P_NUM|P_VI_DEF,
(char_u *)&p_window, PV_NONE, did_set_window, NULL,
{(char_u *)0L, (char_u *)0L} SCTX_INIT},
- {"winfixbuf", "wfb", P_BOOL|P_VI_DEF|P_RWIN,
+ {"winfixbuf", "wfb", P_BOOL|P_VI_DEF,
(char_u *)VAR_WIN, PV_WFB, NULL, NULL,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"winfixheight", "wfh", P_BOOL|P_VI_DEF|P_RSTAT,
(char_u *)VAR_WIN, PV_WFH, NULL, NULL,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
- {"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT,
+ {"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT,
(char_u *)VAR_WIN, PV_WFW, NULL, NULL,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"winheight", "wh", P_NUM|P_VI_DEF,
@@ -2868,7 +2870,7 @@ static struct vimoption options[] =
{"winminheight", "wmh", P_NUM|P_VI_DEF,
(char_u *)&p_wmh, PV_NONE, did_set_winminheight, NULL,
{(char_u *)1L, (char_u *)0L} SCTX_INIT},
- {"winminwidth", "wmw", P_NUM|P_VI_DEF,
+ {"winminwidth", "wmw", P_NUM|P_VI_DEF,
(char_u *)&p_wmw, PV_NONE, did_set_winminwidth, NULL,
{(char_u *)1L, (char_u *)0L} SCTX_INIT},
{"winptydll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
diff --git a/src/optionstr.c b/src/optionstr.c
index d722981..b6249a2 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -33,7 +33,7 @@ static char *(p_briopt_values[]) = {"shift:", "min:", "sbr", "list:", "column:",
static char *(p_dip_values[]) = {"filler", "context:", "iblank", "icase", "iwhite", "iwhiteall", "iwhiteeol", "horizontal", "vertical", "closeoff", "hiddenoff", "foldcolumn:", "followwrap", "internal", "indent-heuristic", "algorithm:", NULL};
static char *(p_dip_algorithm_values[]) = {"myers", "minimal", "patience", "histogram", NULL};
#endif
-static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", NULL};
+static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", "blank", NULL};
static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
#ifdef FEAT_CLIPBOARD
// Note: Keep this in sync with did_set_clipboard()
@@ -81,6 +81,8 @@ static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize",
static char *(p_swb_values[]) = {"useopen", "usetab", "split", "newtab", "vsplit", "uselast", NULL};
static char *(p_spk_values[]) = {"cursor", "screen", "topline", NULL};
static char *(p_tc_values[]) = {"followic", "ignore", "match", "followscs", "smart", NULL};
+// Keep in sync with TCL_ flags in option.h
+static char *(p_tcl_values[]) = {"left", "uselast", NULL};
#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN)
static char *(p_toolbar_values[]) = {"text", "icons", "tooltips", "horiz", NULL};
#endif
@@ -166,6 +168,7 @@ didset_string_options(void)
(void)opt_strings_flags(p_tbis, p_tbis_values, &tbis_flags, FALSE);
#endif
(void)opt_strings_flags(p_swb, p_swb_values, &swb_flags, TRUE);
+ (void)opt_strings_flags(p_tcl, p_tcl_values, &tcl_flags, TRUE);
}
#if defined(FEAT_EVAL) || defined(PROTO)
@@ -3669,6 +3672,26 @@ expand_set_switchbuf(optexpand_T *args, int *numMatches, char_u ***matches)
matches);
}
+/*
+ * The 'tabclose' option is changed.
+ */
+ char *
+did_set_tabclose(optset_T *args UNUSED)
+{
+ return did_set_opt_flags(p_tcl, p_tcl_values, &tcl_flags, TRUE);
+}
+
+ int
+expand_set_tabclose(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_tcl_values,
+ ARRAY_LENGTH(p_tcl_values) - 1,
+ numMatches,
+ matches);
+}
+
#if defined(FEAT_STL_OPT) || defined(PROTO)
/*
* The 'tabline' option is changed.
diff --git a/src/os_mswin.c b/src/os_mswin.c
index 512fa40..95e3cbc 100644
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -18,20 +18,12 @@
#include <sys/types.h>
#include <signal.h>
#include <limits.h>
+
+// cproto fails on missing include files
#ifndef PROTO
# include <process.h>
-#endif
-
-#undef chdir
-#ifdef __GNUC__
-# ifndef __MINGW32__
-# include <dirent.h>
-# endif
-#else
# include <direct.h>
-#endif
-#ifndef PROTO
# if !defined(FEAT_GUI_MSWIN)
# include <shellapi.h>
# endif
@@ -41,37 +33,8 @@
# include <winspool.h>
# include <commdlg.h>
# endif
-
#endif // PROTO
-#ifdef __MINGW32__
-# ifndef FROM_LEFT_1ST_BUTTON_PRESSED
-# define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001
-# endif
-# ifndef RIGHTMOST_BUTTON_PRESSED
-# define RIGHTMOST_BUTTON_PRESSED 0x0002
-# endif
-# ifndef FROM_LEFT_2ND_BUTTON_PRESSED
-# define FROM_LEFT_2ND_BUTTON_PRESSED 0x0004
-# endif
-# ifndef FROM_LEFT_3RD_BUTTON_PRESSED
-# define FROM_LEFT_3RD_BUTTON_PRESSED 0x0008
-# endif
-# ifndef FROM_LEFT_4TH_BUTTON_PRESSED
-# define FROM_LEFT_4TH_BUTTON_PRESSED 0x0010
-# endif
-
-/*
- * EventFlags
- */
-# ifndef MOUSE_MOVED
-# define MOUSE_MOVED 0x0001
-# endif
-# ifndef DOUBLE_CLICK
-# define DOUBLE_CLICK 0x0002
-# endif
-#endif
-
/*
* When generating prototypes for Win32 on Unix, these lines make the syntax
* errors disappear. They do not need to be correct.
@@ -144,37 +107,6 @@ static HWND s_hwnd = 0; // console window handle, set by GetConsoleHwnd()
int WSInitialized = FALSE; // WinSock is initialized
#endif
-// Don't generate prototypes here, because some systems do have these
-// functions.
-#if defined(__GNUC__) && !defined(PROTO)
-# ifndef __MINGW32__
-int _stricoll(char *a, char *b)
-{
- // the ANSI-ish correct way is to use strxfrm():
- char a_buff[512], b_buff[512]; // file names, so this is enough on Win32
- strxfrm(a_buff, a, 512);
- strxfrm(b_buff, b, 512);
- return strcoll(a_buff, b_buff);
-}
-
-char * _fullpath(char *buf, char *fname, int len)
-{
- LPTSTR toss;
-
- return (char *)GetFullPathName(fname, len, buf, &toss);
-}
-# endif
-
-# if !defined(__MINGW32__) || (__GNUC__ < 4)
-int _chdrive(int drive)
-{
- char temp [3] = "-:";
- temp[0] = drive + 'A' - 1;
- return !SetCurrentDirectory(temp);
-}
-# endif
-#endif
-
#ifndef PROTO
/*
@@ -430,16 +362,6 @@ slash_adjust(char_u *p)
}
}
-// Use 64-bit stat functions.
-#undef stat
-#undef _stat
-#undef _wstat
-#undef _fstat
-#define stat _stat64
-#define _stat _stat64
-#define _wstat _wstat64
-#define _fstat _fstat64
-
static int
read_reparse_point(const WCHAR *name, char_u *buf, DWORD *buf_len)
{
@@ -461,58 +383,6 @@ read_reparse_point(const WCHAR *name, char_u *buf, DWORD *buf_len)
return ok ? OK : FAIL;
}
- static int
-wstat_symlink_aware(const WCHAR *name, stat_T *stp)
-{
-#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__)
- // Work around for VC12 or earlier (and MinGW). _wstat() can't handle
- // symlinks properly.
- // VC9 or earlier: _wstat() doesn't support a symlink at all. It retrieves
- // status of a symlink itself.
- // VC10: _wstat() supports a symlink to a normal file, but it doesn't
- // support a symlink to a directory (always returns an error).
- // VC11 and VC12: _wstat() doesn't return an error for a symlink to a
- // directory, but it doesn't set S_IFDIR flag.
- // MinGW: Same as VC9.
- int n;
- BOOL is_symlink = FALSE;
- HANDLE hFind, h;
- DWORD attr = 0;
- WIN32_FIND_DATAW findDataW;
-
- hFind = FindFirstFileW(name, &findDataW);
- if (hFind != INVALID_HANDLE_VALUE)
- {
- attr = findDataW.dwFileAttributes;
- if ((attr & FILE_ATTRIBUTE_REPARSE_POINT)
- && (findDataW.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
- is_symlink = TRUE;
- FindClose(hFind);
- }
- if (is_symlink)
- {
- h = CreateFileW(name, FILE_READ_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING,
- (attr & FILE_ATTRIBUTE_DIRECTORY)
- ? FILE_FLAG_BACKUP_SEMANTICS : 0,
- NULL);
- if (h != INVALID_HANDLE_VALUE)
- {
- int fd;
-
- fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
- n = _fstat(fd, (struct _stat *)stp);
- if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY))
- stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR;
- _close(fd);
- return n;
- }
- }
-#endif
- return _wstat(name, (struct _stat *)stp);
-}
-
char_u *
resolve_appexeclink(char_u *fname)
{
@@ -568,11 +438,76 @@ resolve_appexeclink(char_u *fname)
return utf16_to_enc(p, NULL);
}
+// Use 64-bit stat functions.
+#undef stat
+#undef _stat
+#undef _wstat
+#undef _fstat
+#define stat _stat64
+#define _stat _stat64
+#define _wstat _wstat64
+#define _fstat _fstat64
+
+/*
+ * Implements lstat() and stat() that can handle symlinks properly.
+ */
+ static int
+mswin_stat_impl(const WCHAR *name, stat_T *stp, const int resolve)
+{
+ int n;
+ int fd;
+ BOOL is_symlink = FALSE;
+ HANDLE hFind, h;
+ DWORD attr = 0;
+ DWORD flag = 0;
+ WIN32_FIND_DATAW findDataW;
+
+#ifdef _UCRT
+ if (resolve)
+ // Universal CRT can handle symlinks properly.
+ return _wstat(name, stp);
+#endif
+
+ hFind = FindFirstFileW(name, &findDataW);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ attr = findDataW.dwFileAttributes;
+ if ((attr & FILE_ATTRIBUTE_REPARSE_POINT)
+ && (findDataW.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
+ is_symlink = TRUE;
+ FindClose(hFind);
+ }
+
+ // Use the plain old stat() whenever it's possible.
+ if (!is_symlink)
+ return _wstat(name, stp);
+
+ if (!resolve && is_symlink)
+ flag = FILE_FLAG_OPEN_REPARSE_POINT;
+ if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ flag |= FILE_FLAG_BACKUP_SEMANTICS;
+
+ h = CreateFileW(name, FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, flag,
+ NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return -1;
+
+ fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
+ n = _fstat(fd, (struct _stat *)stp);
+ if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY))
+ stp->st_mode = (stp->st_mode & ~S_IFMT) | S_IFDIR;
+ _close(fd);
+
+ return n;
+}
+
/*
* stat() can't handle a trailing '/' or '\', remove it first.
+ * When 'resolve' is true behave as lstat() wrt symlinks.
*/
- int
-vim_stat(const char *name, stat_T *stp)
+ static int
+stat_impl(const char *name, stat_T *stp, const int resolve)
{
// WinNT and later can use _MAX_PATH wide characters for a pathname, which
// means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is
@@ -607,11 +542,23 @@ vim_stat(const char *name, stat_T *stp)
if (wp == NULL)
return -1;
- n = wstat_symlink_aware(wp, stp);
+ n = mswin_stat_impl(wp, stp, resolve);
vim_free(wp);
return n;
}
+ int
+vim_lstat(const char *name, stat_T *stp)
+{
+ return stat_impl(name, stp, FALSE);
+}
+
+ int
+vim_stat(const char *name, stat_T *stp)
+{
+ return stat_impl(name, stp, TRUE);
+}
+
#if (defined(FEAT_GUI_MSWIN) && !defined(VIMDLL)) || defined(PROTO)
void
mch_settmode(tmode_T tmode UNUSED)
@@ -883,6 +830,40 @@ mch_icon_load(HANDLE *iconp)
0, mch_icon_load_cb, iconp);
}
+/*
+ * Fill the buffer 'buf' with 'len' random bytes.
+ * Returns FAIL if the OS PRNG is not available or something went wrong.
+ */
+ int
+mch_get_random(char_u *buf, int len)
+{
+ static int initialized = NOTDONE;
+ static HINSTANCE hInstLib;
+ static BOOL (WINAPI *pProcessPrng)(PUCHAR, ULONG);
+
+ if (initialized == NOTDONE)
+ {
+ hInstLib = vimLoadLib("bcryptprimitives.dll");
+ if (hInstLib != NULL)
+ pProcessPrng = (void *)GetProcAddress(hInstLib, "ProcessPrng");
+ if (hInstLib == NULL || pProcessPrng == NULL)
+ {
+ FreeLibrary(hInstLib);
+ initialized = FAIL;
+ }
+ else
+ initialized = OK;
+ }
+
+ if (initialized == FAIL)
+ return FAIL;
+
+ // According to the documentation this call cannot fail.
+ pProcessPrng(buf, len);
+
+ return OK;
+}
+
int
mch_libcall(
char_u *libname,
@@ -2940,7 +2921,7 @@ expand_font_enumproc(
// Filter only on ANSI. Otherwise will see a lot of random fonts that we
// usually don't want.
if (lf->lfCharSet != ANSI_CHARSET)
- return 1;
+ return 1;
int (*add_match)(char_u *) = (int (*)(char_u *))lparam;
@@ -2974,7 +2955,7 @@ gui_mch_expand_font(optexpand_T *args, void *param UNUSED, int (*add_match)(char
// Always fill in with the current font size as first option for
// convenience. We simply round to the closest integer for simplicity.
- int font_height = (int)round(
+ int font_height = (int)round(
pixels_to_points(-current_font_height, TRUE, (long_i)NULL));
vim_snprintf(buf, ARRAY_LENGTH(buf), "h%d", font_height);
add_match((char_u *)buf);
diff --git a/src/os_unix.c b/src/os_unix.c
index d155142..e77a4b2 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -2699,6 +2699,9 @@ mch_FullName(
if ((force || !mch_isFullName(fname))
&& ((p = vim_strrchr(fname, '/')) == NULL || p != fname))
{
+ if (p == NULL && STRCMP(fname, "..") == 0)
+ // Handle ".." without path separators.
+ p = fname + 2;
/*
* If the file name has a path, change to that directory for a moment,
* and then get the directory (and get back to where we were).
@@ -2707,7 +2710,7 @@ mch_FullName(
if (p != NULL)
{
if (STRCMP(p, "/..") == 0)
- // for "/path/dir/.." include the "/.."
+ // For "/path/dir/.." include the "/..".
p += 3;
#ifdef HAVE_FCHDIR
@@ -7498,9 +7501,9 @@ gpm_open(void)
{
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.
+ // 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
@@ -7722,6 +7725,37 @@ sig_sysmouse SIGDEFARG(sigarg)
}
#endif // FEAT_SYSMOUSE
+/*
+ * Fill the buffer 'buf' with 'len' random bytes.
+ * Returns FAIL if the OS PRNG is not available or something went wrong.
+ */
+ int
+mch_get_random(char_u *buf, int len)
+{
+ static int dev_urandom_state = NOTDONE;
+
+ if (dev_urandom_state == FAIL)
+ return FAIL;
+
+ int fd = open("/dev/urandom", O_RDONLY);
+
+ // Attempt reading /dev/urandom.
+ if (fd == -1)
+ dev_urandom_state = FAIL;
+ else if (read(fd, buf, len) == len)
+ {
+ dev_urandom_state = OK;
+ close(fd);
+ }
+ else
+ {
+ dev_urandom_state = FAIL;
+ close(fd);
+ }
+
+ return dev_urandom_state;
+}
+
#if defined(FEAT_LIBCALL) || defined(PROTO)
typedef char_u * (*STRPROCSTR)(char_u *);
typedef char_u * (*INTPROCSTR)(int);
diff --git a/src/os_w32dll.c b/src/os_w32dll.c
index e7ba99b..651f96c 100644
--- a/src/os_w32dll.c
+++ b/src/os_w32dll.c
@@ -7,7 +7,7 @@
* See README.txt for an overview of the Vim source code.
*/
/*
- * Windows GUI: main program (DLL) entry point:
+ * Windows GUI/Console: main program (DLL) entry point:
*
* Ron Aaron <ronaharon@yahoo.com> wrote this and the DLL support code.
* Adapted by Ken Takata.
diff --git a/src/os_w32exe.c b/src/os_w32exe.c
index c4f0294..7aa4ead 100644
--- a/src/os_w32exe.c
+++ b/src/os_w32exe.c
@@ -8,10 +8,10 @@
* See README.txt for an overview of the Vim source code.
*/
/*
- * Windows GUI: main program (EXE) entry point:
+ * Windows GUI/Console: main program (EXE) entry point:
*
- * Ron Aaron <ronaharon@yahoo.com> wrote this and the (now deleted) DLL support
- * code.
+ * Ron Aaron <ronaharon@yahoo.com> wrote this and the DLL support code.
+ * Adapted by Ken Takata.
*/
#include "vim.h"
@@ -20,32 +20,74 @@
__declspec(dllimport)
#endif
int VimMain(int argc, char **argv);
-#ifndef VIMDLL
+
+#ifdef VIMDLL
+# define SaveInst(hInst) // Do nothing
+#else
void SaveInst(HINSTANCE hInst);
#endif
-#ifndef PROTO
-# ifdef FEAT_GUI
+#ifdef FEAT_GUI
int WINAPI
wWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInst UNUSED,
LPWSTR lpszCmdLine UNUSED,
int nCmdShow UNUSED)
-# else
+{
+ SaveInst(hInstance);
+ return VimMain(0, NULL);
+}
+#else
int
wmain(int argc UNUSED, wchar_t **argv UNUSED)
-# endif
{
-# ifndef VIMDLL
-# ifdef FEAT_GUI
- SaveInst(hInstance);
-# else
SaveInst(GetModuleHandleW(NULL));
-# endif
-# endif
+ return VimMain(0, NULL);
+}
+#endif
+
+#ifdef USE_OWNSTARTUP
+// Use our own entry point and don't use the default CRT startup code to
+// reduce the size of (g)vim.exe. This works only when VIMDLL is defined.
+//
+// For MSVC, the /GS- compiler option is needed to avoid the undefined symbol
+// error. (It disables the security check. However, it affects only this
+// function and doesn't have any effect on Vim itself.)
+// For MinGW, the -nostdlib compiler option and the --entry linker option are
+// needed.
+# ifdef FEAT_GUI
+ void WINAPI
+wWinMainCRTStartup(void)
+{
VimMain(0, NULL);
+}
+# else
+ void
+wmainCRTStartup(void)
+{
+ VimMain(0, NULL);
+}
+# endif
+#endif // USE_OWNSTARTUP
+
+
+#if defined(VIMDLL) && defined(FEAT_MZSCHEME)
- return 0;
+# if defined(_MSC_VER)
+static __declspec(thread) void *tls_space;
+extern intptr_t _tls_index;
+# elif defined(__MINGW32__)
+static __thread void *tls_space;
+extern intptr_t _tls_index;
+# endif
+
+// Get TLS information that is needed for if_mzsch.
+ __declspec(dllexport) void
+get_tls_info(void ***ptls_space, intptr_t *ptls_index)
+{
+ *ptls_space = &tls_space;
+ *ptls_index = _tls_index;
+ return;
}
#endif
diff --git a/src/os_win32.c b/src/os_win32.c
index 9947150..6384ac8 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -34,52 +34,14 @@
#ifndef PROTO
# include <process.h>
# include <winternl.h>
-#endif
-
-#undef chdir
-#ifdef __GNUC__
-# ifndef __MINGW32__
-# include <dirent.h>
-# endif
-#else
# include <direct.h>
-#endif
-#ifndef PROTO
# if !defined(FEAT_GUI_MSWIN)
# include <shellapi.h>
# endif
-#endif
-
-#ifdef FEAT_JOB_CHANNEL
-# include <tlhelp32.h>
-#endif
-#ifdef __MINGW32__
-# ifndef FROM_LEFT_1ST_BUTTON_PRESSED
-# define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001
-# endif
-# ifndef RIGHTMOST_BUTTON_PRESSED
-# define RIGHTMOST_BUTTON_PRESSED 0x0002
-# endif
-# ifndef FROM_LEFT_2ND_BUTTON_PRESSED
-# define FROM_LEFT_2ND_BUTTON_PRESSED 0x0004
-# endif
-# ifndef FROM_LEFT_3RD_BUTTON_PRESSED
-# define FROM_LEFT_3RD_BUTTON_PRESSED 0x0008
-# endif
-# ifndef FROM_LEFT_4TH_BUTTON_PRESSED
-# define FROM_LEFT_4TH_BUTTON_PRESSED 0x0010
-# endif
-
-/*
- * EventFlags
- */
-# ifndef MOUSE_MOVED
-# define MOUSE_MOVED 0x0001
-# endif
-# ifndef DOUBLE_CLICK
-# define DOUBLE_CLICK 0x0002
+# ifdef FEAT_JOB_CHANNEL
+# include <tlhelp32.h>
# endif
#endif
@@ -1302,6 +1264,13 @@ decode_key_event(
}
}
}
+ else if (pker->wVirtualKeyCode == VK_INSERT
+ && (nModifs & SHIFT) != 0
+ && (nModifs & ~SHIFT) == 0)
+ {
+ *pmodifiers = 0;
+ *pch2 = VirtKeyMap[i].chShift;
+ }
else
{
*pch2 = VirtKeyMap[i].chAlone;
@@ -2762,12 +2731,6 @@ theend:
#endif // FEAT_GUI_MSWIN
}
-#ifndef PROTO
-# ifndef __MINGW32__
-# include <shellapi.h> // required for FindExecutable()
-# endif
-#endif
-
/*
* Return TRUE if "name" is an executable file, FALSE if not or it doesn't exist.
* When returning TRUE and "path" is not NULL save the path and set "*path" to
@@ -3598,6 +3561,10 @@ mch_exit_c(int r)
vtp_exit();
stoptermcap();
+ // Switch back to main screen buffer.
+ if (use_alternate_screen_buffer)
+ vtp_printf("\033[?1049l");
+
if (g_fWindInitCalled)
settmode(TMODE_COOK);
@@ -5529,11 +5496,7 @@ mch_call_shell(
* CTRL-C, Ctrl-Break or illegal instruction might otherwise kill us.
*/
mch_signal(SIGINT, SIG_IGN);
-#if defined(__GNUC__) && !defined(__MINGW32__)
- mch_signal(SIGKILL, SIG_IGN);
-#else
mch_signal(SIGBREAK, SIG_IGN);
-#endif
mch_signal(SIGILL, SIG_IGN);
mch_signal(SIGFPE, SIG_IGN);
mch_signal(SIGSEGV, SIG_IGN);
@@ -5768,11 +5731,7 @@ mch_call_shell(
resettitle();
mch_signal(SIGINT, SIG_DFL);
-#if defined(__GNUC__) && !defined(__MINGW32__)
- mch_signal(SIGKILL, SIG_DFL);
-#else
mch_signal(SIGBREAK, SIG_DFL);
-#endif
mch_signal(SIGILL, SIG_DFL);
mch_signal(SIGFPE, SIG_DFL);
mch_signal(SIGSEGV, SIG_DFL);
@@ -6379,10 +6338,6 @@ termcap_mode_end(void)
RestoreConsoleBuffer(cb, p_rs);
restore_console_color_rgb();
- // Switch back to main screen buffer.
- if (exiting && use_alternate_screen_buffer)
- vtp_printf("\033[?1049l");
-
if (!USE_WT && (p_rs || exiting))
{
/*
diff --git a/src/po/Make_cyg.mak b/src/po/Make_cyg.mak
index 705858d..c04837e 100644
--- a/src/po/Make_cyg.mak
+++ b/src/po/Make_cyg.mak
@@ -16,7 +16,7 @@ endif
include Make_all.mak
PACKAGE = vim
-VIM = ../vim
+VIMPROG = ../vim
# Uncomment one of the lines below or modify it to put the path to your
# gettext binaries
@@ -64,18 +64,18 @@ PO_INPUTLIST = \
vim.desktop.in
first_time: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST)
- $(VIM) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST)
$(XGETTEXT) --default-domain=$(LANGUAGE) \
--add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST)
- $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST)
$(RM) *.js
$(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST)
- $(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
$(XGETTEXT) --default-domain=$(PACKAGE) \
--add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST)
$(MV) $(PACKAGE).po $(PACKAGE).pot
- $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
$(RM) *.js
# Don't add a dependency here, we only want to update the .po files manually
diff --git a/src/po/Make_ming.mak b/src/po/Make_ming.mak
index 42dab84..21d2d20 100644
--- a/src/po/Make_ming.mak
+++ b/src/po/Make_ming.mak
@@ -23,9 +23,9 @@ include Make_all.mak
PACKAGE = vim
ifeq (sh.exe, $(SHELL))
-VIM = ..\vim
+VIMPROG = ..\vim
else
-VIM = ../vim
+VIMPROG = ../vim
endif
# Uncomment one of the lines below or modify it to put the path to your
@@ -77,18 +77,18 @@ PO_INPUTLIST = \
vim.desktop.in
first_time: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST)
- $(VIM) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST)
$(XGETTEXT) --default-domain=$(LANGUAGE) \
--add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST)
- $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST)
$(RM) *.js
$(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST)
- $(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
$(XGETTEXT) --default-domain=$(PACKAGE) \
--add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST)
$(MV) $(PACKAGE).po $(PACKAGE).pot
- $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
$(RM) *.js
# Don't add a dependency here, we only want to update the .po files manually
diff --git a/src/po/Make_mvc.mak b/src/po/Make_mvc.mak
index a9a69fd..f567d88 100644
--- a/src/po/Make_mvc.mak
+++ b/src/po/Make_mvc.mak
@@ -40,7 +40,9 @@ VIMRUNTIME = ..\..\runtime
PACKAGE = vim
# Correct the following line for the where executeable file vim is
# installed. Please do not put the path in quotes.
-VIM = ..\vim.exe
+!IFNDEF VIMPROG
+VIMPROG = ..\vim.exe
+!ENDIF
# Correct the following line for the directory where gettext et al is
# installed. Please do not put the path in quotes.
@@ -102,7 +104,7 @@ originals : $(MOFILES)
converted: $(MOCONVERTED)
.po.ck:
- "$(VIM)" -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" -S check.vim \
+ "$(VIMPROG)" -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" -S check.vim \
-c "if error == 0 | q | else | num 2 | cq | endif" $<
$(TOUCH_TARGET)
@@ -122,9 +124,7 @@ nb.po: no.po
ja.sjis.po: ja.po
@$(MAKE) -nologo -f Make_mvc.mak sjiscorr
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t CP932 $? | .\sjiscorr.exe > $@
-!ELSEIF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f UTF-8 -t CP932 $? | .\sjiscorr.exe > $@
!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
@@ -146,23 +146,19 @@ sjiscorr: sjiscorr.c
# Convert ja.po to create ja.euc-jp.po.
ja.euc-jp.po: ja.po
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t EUC-JP -o $@ $?
-!ELSE
-! IF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f UTF-8 -t EUC-JP $? > $@
-! ELSE
+!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
[System.IO.File]::ReadAllText(\"$?\", \
[System.Text.Encoding]::GetEncoding(65001)), \
[System.Text.Encoding]::GetEncoding(20932))
-! ENDIF
+!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(20932)) -replace \
'charset=utf-8', 'charset=EUC-JP'; \
[System.IO.File]::WriteAllText(\"$@\", $$out, \
[System.Text.Encoding]::GetEncoding(20932))
-!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(20932)) -replace \
'# Original translations', \
@@ -173,23 +169,19 @@ ja.euc-jp.po: ja.po
# Convert cs.po to create cs.cp1250.po.
cs.cp1250.po: cs.po
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t CP1250 -o $@ $?
-!ELSE
-! IF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f ISO-8859-2 -t CP1250 $? > $@
-! ELSE
+!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
[System.IO.File]::ReadAllText(\"$?\", \
[System.Text.Encoding]::GetEncoding(28592)), \
[System.Text.Encoding]::GetEncoding(1250))
-! ENDIF
+!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(1250)) -replace \
'charset=iso-8859-2', 'charset=CP1250'; \
[System.IO.File]::WriteAllText(\"$@\", $$out, \
[System.Text.Encoding]::GetEncoding(1250))
-!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(1250)) -replace \
'# Original translations', \
@@ -200,23 +192,19 @@ cs.cp1250.po: cs.po
# Convert pl.po to create pl.cp1250.po.
pl.cp1250.po: pl.po
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t CP1250 -o $@ $?
-!ELSE
-! IF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f ISO-8859-2 -t CP1250 $? > $@
-! ELSE
+!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
[System.IO.File]::ReadAllText(\"$?\", \
[System.Text.Encoding]::GetEncoding(28592)), \
[System.Text.Encoding]::GetEncoding(1250))
-! ENDIF
+!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(1250)) -replace \
'charset=iso-8859-2', 'charset=CP1250'; \
[System.IO.File]::WriteAllText(\"$@\", $$out, \
[System.Text.Encoding]::GetEncoding(1250))
-!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(1250)) -replace \
'# Original translations', \
@@ -227,20 +215,16 @@ pl.cp1250.po: pl.po
# Convert pl.po to create pl.UTF-8.po.
pl.UTF-8.po: pl.po
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t UTF-8 -o $@ $?
-!ELSE
-! IF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f ISO-8859-2 -t UTF-8 $? > $@
-! ELSE
+!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
[System.IO.File]::ReadAllText(\"$?\", \
[System.Text.Encoding]::GetEncoding(28592)))
-! ENDIF
+!ENDIF
$(PS) $(PSFLAGS) (Get-Content -Raw -Encoding UTF8 $@ \
^| % {$$_-replace 'charset=iso-8859-2', 'charset=UTF-8'}) \
^| 1>nul New-Item -Force -Path . -ItemType file -Name $@
-!ENDIF
$(PS) $(PSFLAGS) (Get-Content -Raw -Encoding UTF8 $@ \
^| % {$$_-replace '# Original translations', \
'# Generated from $?, DO NOT EDIT'}) \
@@ -249,23 +233,19 @@ pl.UTF-8.po: pl.po
# Convert sk.po to create sk.cp1250.po.
sk.cp1250.po: sk.po
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t CP1250 -o $@ $?
-!ELSE
-! IF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f ISO-8859-2 -t CP1250 $? > $@
-! ELSE
+!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
[System.IO.File]::ReadAllText(\"$?\", \
[System.Text.Encoding]::GetEncoding(28592)), \
[System.Text.Encoding]::GetEncoding(1250))
-! ENDIF
+!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(1250)) -replace \
'charset=iso-8859-2', 'charset=CP1250'; \
[System.IO.File]::WriteAllText(\"$@\", $$out, \
[System.Text.Encoding]::GetEncoding(1250))
-!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(1250)) -replace \
'# Original translations', \
@@ -276,24 +256,20 @@ sk.cp1250.po: sk.po
# Convert zh_CN.UTF-8.po to create zh_CN.po.
zh_CN.po: zh_CN.UTF-8.po
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t GB2312 -o $@ $?
-!ELSE
-! IF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f UTF-8 -t GB2312 $? > $@
-! ELSE
+!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
[System.IO.File]::ReadAllText(\"$?\", \
[System.Text.Encoding]::GetEncoding(65001)), \
[System.Text.Encoding]::GetEncoding(936))
-! ENDIF
+!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(936)) -replace \
'charset=UTF-8', 'charset=GB2312'; \
[System.IO.File]::WriteAllText(\"$@\", $$out, \
[System.Text.Encoding]::GetEncoding(936))
-!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(936)) -replace \
'# Original translations', \
@@ -326,24 +302,19 @@ zh_CN.cp936.po: zh_CN.UTF-8.po
# Convert zh_TW.UTF-8.po to create zh_TW.po.
zh_TW.po: zh_TW.UTF-8.po
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t BIG5 -o $@ $?
-!ELSE
-! IF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f UTF-8 -t BIG5 $? > $@
-! ELSE
+!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
[System.IO.File]::ReadAllText(\"$?\", \
[System.Text.Encoding]::GetEncoding(65001)), \
[System.Text.Encoding]::GetEncoding(950))
-
-! ENDIF
+!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(950)) -replace \
'charset=UTF-8', 'charset=BIG5'; \
[System.IO.File]::WriteAllText(\"$@\", $$out, \
[System.Text.Encoding]::GetEncoding(950))
-!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(950)) -replace \
'# Original translations', \
@@ -371,9 +342,7 @@ zh_TW.po: zh_TW.UTF-8.po
#zh_TW.po: zh_TW.UTF-8.po
# @$(MAKE) -nologo -f Make_mvc.mak big5corr
# -$(RM) $@
-#!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
-# "$(GETTEXT_PATH)\msgconv.exe" -t BIG5 $? | .\big5corr.exe > $@
-#!ELSEIF DEFINED (ICONV)
+#!IF DEFINED (ICONV)
# $(ICONV) -f UTF-8 -t BIG5 $? | .\big5corr.exe > $@
#!ELSE
# $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
@@ -396,24 +365,20 @@ zh_TW.po: zh_TW.UTF-8.po
# Convert ko.UTF-8.po to create ko.po.
ko.po: ko.UTF-8.po
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t EUC-KR -o $@ $?
-!ELSE
-! IF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f UTF-8 -t EUC-KR $? > $@
-! ELSE
+!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
[System.IO.File]::ReadAllText(\"$?\", \
[System.Text.Encoding]::GetEncoding(65001)), \
[System.Text.Encoding]::GetEncoding(51949))
-! ENDIF
+!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(51949)) -replace \
'charset=UTF-8', 'charset=EUC-KR'; \
[System.IO.File]::WriteAllText(\"$@\", $$out, \
[System.Text.Encoding]::GetEncoding(51949))
-!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(51949)) -replace \
'# Original translations', \
@@ -424,24 +389,19 @@ ko.po: ko.UTF-8.po
# Convert ru.po to create ru.cp1251.po.
ru.cp1251.po: ru.po
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t CP1251 -o $@ $?
-!ELSE
-! IF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f UTF-8 -t CP1251 $? > $@
-! ELSE
+!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
[System.IO.File]::ReadAllText(\"$?\", \
[System.Text.Encoding]::GetEncoding(65001)), \
[System.Text.Encoding]::GetEncoding(1251))
-
-! ENDIF
+!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(1251)) -replace \
'charset=UTF-8', 'charset=CP1251'; \
[System.IO.File]::WriteAllText(\"$@\", $$out, \
[System.Text.Encoding]::GetEncoding(1251))
-!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(1251)) -replace \
'# Original translations', \
@@ -452,24 +412,19 @@ ru.cp1251.po: ru.po
# Convert uk.po to create uk.cp1251.po.
uk.cp1251.po: uk.po
-$(RM) $@
-!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
- "$(GETTEXT_PATH)\msgconv.exe" -t CP1251 -o $@ $?
-!ELSE
-! IF DEFINED (ICONV)
+!IF DEFINED (ICONV)
$(ICONV) -f UTF-8 -t CP1251 $? > $@
-! ELSE
+!ELSE
$(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \
[System.IO.File]::ReadAllText(\"$?\", \
[System.Text.Encoding]::GetEncoding(65001)), \
[System.Text.Encoding]::GetEncoding(1251))
-
-! ENDIF
+!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(1251)) -replace \
'charset=UTF-8', 'charset=CP1251'; \
[System.IO.File]::WriteAllText(\"$@\", $$out, \
[System.Text.Encoding]::GetEncoding(1251))
-!ENDIF
$(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \
[System.Text.Encoding]::GetEncoding(1251)) -replace \
'# Original translations', \
@@ -496,27 +451,28 @@ files: $(PO_INPUTLIST)
$(LS) $(LSFLAGS) $(PO_INPUTLIST) > .\files
first_time: files
- "$(VIM)" -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).po \
+ "$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).po \
$(PO_VIM_INPUTLIST)
+ @ copy /b .\files+.\vim_to_js .\allfiles
set OLD_PO_FILE_INPUT=yes
set OLD_PO_FILE_OUTPUT=yes
$(XGETTEXT) --default-domain=$(LANGUAGE) --add-comments $(XGETTEXT_KEYWORDS) \
- --files-from=.\files $(PO_VIM_JSLIST)
- "$(VIM)" -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).po \
+ --files-from=.\allfiles
+ "$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).po \
$(PO_VIM_INPUTLIST)
- $(RM) *.js
+ $(RM) *.js .\vim_to_js
$(PACKAGE).pot: files
- "$(VIM)" -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \
+ "$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \
$(PO_VIM_INPUTLIST)
+ @ copy /b .\files+.\vim_to_js .\allfiles
set OLD_PO_FILE_INPUT=yes
set OLD_PO_FILE_OUTPUT=yes
- $(XGETTEXT) --default-domain=$(PACKAGE) --add-comments $(XGETTEXT_KEYWORDS) \
- --files-from=.\files $(PO_VIM_JSLIST)
- $(MV) $(PACKAGE).po $(PACKAGE).pot
- "$(VIM)" -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \
+ $(XGETTEXT) --default-domain=$(PACKAGE) --output=$(PACKAGE).pot \
+ --add-comments $(XGETTEXT_KEYWORDS) --files-from=.\allfiles
+ "$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \
$(PO_VIM_INPUTLIST)
- $(RM) *.js
+ $(RM) *.js .\vim_to_js
# Only original translations with default encoding should be updated.
# The files that are converted to a different encoding clearly state "DO NOT EDIT".
@@ -541,16 +497,39 @@ install-all: all
"$(VIMRUNTIME)\lang\%%l\LC_MESSAGES\$(PACKAGE).mo"
cleanup-po: $(LANGUAGE).po
- "$(VIM)" -u NONE -e -X -S cleanup.vim -c wq $(LANGUAGE).po
+ "$(VIMPROG)" -u NONE -e -X -S cleanup.vim -c wq $(LANGUAGE).po
cleanup-po-all: $(POFILES)
- !"$(VIM)" -u NONE -e -X -S cleanup.vim -c wq $**
+ !"$(VIMPROG)" -u NONE -e -X -S cleanup.vim -c wq $**
+
+#######
+# For translations of plug-ins
+#######
+
+# Preparing the POT file of the plug-in package
+POT_PLUGPACKAGE_PATH = $(MAKEDIR)
+$(PLUGPACKAGE).pot : $(PO_PLUG_INPUTLIST)
+ "$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim \
+ $(PLUGPACKAGE).pot $**
+ $(XGETTEXT) --from-code=UTF-8 --default-domain=$(PLUGPACKAGE) \
+ --package-name=$(PLUGPACKAGE) \
+ --output-dir="$(POT_PLUGPACKAGE_PATH)" \
+ --output=$(PLUGPACKAGE).pot --files-from=.\vim_to_js
+ "$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim \
+ "$(POT_PLUGPACKAGE_PATH)\$(PLUGPACKAGE).pot" $**
+ $(RM) *.js .\vim_to_js
+
+# Converting the PO file of the plug-in package to the binary format of the MO file
+MO_PLUGPACKAGE_PATH = $(MAKEDIR)
+$(PLUGPACKAGE).mo : $(PO_PLUGPACKAGE)
+ $(MSGFMT) -o $(MO_PLUGPACKAGE_PATH)\$@ $?
+
clean: checkclean
$(RM) *.mo
$(RM) *.pot
$(RM) *.orig
- $(RM) files
+ $(RM) files allfiles
$(RM) sjiscorr.obj sjiscorr.exe
# $(RM) big5corr.obj big5corr.exe
diff --git a/src/po/Makefile b/src/po/Makefile
index cc4008f..95259a6 100644
--- a/src/po/Makefile
+++ b/src/po/Makefile
@@ -11,7 +11,7 @@ include Make_all.mak
PACKAGE = vim
SHELL = /bin/sh
-VIM = ../vim
+VIMPROG = ../vim
# MacOS sed is locale aware, set $LANG to avoid problems.
SED = LANG=C sed
@@ -40,8 +40,8 @@ converted: $(MOCONVERTED)
$(MSGFMTCMD) -o $@ $<
.po.ck:
- $(VIM) -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" -S check.vim \
- -c "if error == 0 | q | else | num 2 | cq | endif" $<
+ $(VIMPROG) -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" \
+ -S check.vim -c "if error == 0 | q | else | num 2 | cq | endif" $< >/dev/null
touch $@
check: $(CHECKFILES)
@@ -107,55 +107,55 @@ nb.po: no.po
ja.sjis.po: ja.po
@$(MAKE) sjiscorr
rm -f $@
- iconv -f UTF-8 -t CP932 $< | ./sjiscorr > $@
+ iconv -f UTF-8 -t CP932 $? | ./sjiscorr > $@
sjiscorr: sjiscorr.c
$(CC) -o sjiscorr sjiscorr.c
ja.euc-jp.po: ja.po
- iconv -f UTF-8 -t EUC-JP $< | \
+ iconv -f UTF-8 -t EUC-JP $? | \
$(SED) -e 's/charset=[uU][tT][fF]-8/charset=EUC-JP/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
# Convert cs.po to create cs.cp1250.po.
cs.cp1250.po: cs.po
rm -f $@
- iconv -f ISO-8859-2 -t CP1250 $< | \
+ iconv -f ISO-8859-2 -t CP1250 $? | \
$(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=CP1250/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
# Convert pl.po to create pl.cp1250.po.
pl.cp1250.po: pl.po
rm -f $@
- iconv -f ISO-8859-2 -t CP1250 $< | \
+ iconv -f ISO-8859-2 -t CP1250 $? | \
$(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=CP1250/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
# Convert pl.po to create pl.UTF-8.po.
pl.UTF-8.po: pl.po
rm -f $@
- iconv -f ISO-8859-2 -t UTF-8 $< | \
+ iconv -f ISO-8859-2 -t UTF-8 $? | \
$(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=UTF-8/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
# Convert sk.po to create sk.cp1250.po.
sk.cp1250.po: sk.po
rm -f $@
- iconv -f ISO-8859-2 -t CP1250 $< | \
+ iconv -f ISO-8859-2 -t CP1250 $? | \
$(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=CP1250/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
# Convert zh_CN.UTF-8.po to create zh_CN.po.
zh_CN.po: zh_CN.UTF-8.po
rm -f $@
- iconv -f UTF-8 -t GB2312 $< | \
+ iconv -f UTF-8 -t GB2312 $? | \
$(SED) -e 's/charset=[uU][tT][fF]-8/charset=GB2312/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
# Convert zh_CN.UTF-8.po to create zh_CN.cp936.po.
@@ -163,17 +163,17 @@ zh_CN.po: zh_CN.UTF-8.po
# This used to convert from zh_CN.po, but that results in a conversion error.
zh_CN.cp936.po: zh_CN.UTF-8.po
rm -f $@
- iconv -f UTF-8 -t CP936 $< | \
+ iconv -f UTF-8 -t CP936 $? | \
$(SED) -e 's/charset=[uU][tT][fF]-8/charset=GBK/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
# Convert zh_TW.UTF-8.po to create zh_TW.po.
zh_TW.po: zh_TW.UTF-8.po
rm -f $@
- iconv -f UTF-8 -t BIG5 $< | \
+ iconv -f UTF-8 -t BIG5 $? | \
$(SED) -e 's/charset=[uU][tT][fF]-8/charset=BIG5/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
@@ -197,7 +197,7 @@ zh_TW.po: zh_TW.UTF-8.po
#zh_TW.po: zh_TW.UTF-8.po
# @$(MAKE) big5corr
# rm -f $@
-# iconv -f UTF-8 -t BIG5 $< | ./big5corr > $@
+# iconv -f UTF-8 -t BIG5 $? | ./big5corr > $@
# 06.11.23, added by Restorer
@@ -209,25 +209,25 @@ zh_TW.po: zh_TW.UTF-8.po
# Convert ko.UTF-8.po to create ko.po.
ko.po: ko.UTF-8.po
rm -f $@
- iconv -f UTF-8 -t EUC-KR $< | \
+ iconv -f UTF-8 -t EUC-KR $? | \
$(SED) -e 's/charset=[uU][tT][fF]-8/charset=EUC-KR/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
# Convert ru.po to create ru.cp1251.po.
ru.cp1251.po: ru.po
rm -f $@
- iconv -f UTF-8 -t CP1251 $< | \
+ iconv -f UTF-8 -t CP1251 $? | \
$(SED) -e 's/charset=[uU][tT][fF]-8/charset=CP1251/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
# Convert uk.po to create uk.cp1251.po.
uk.cp1251.po: uk.po
rm -f $@
- iconv -f UTF-8 -t CP1251 $< | \
+ iconv -f UTF-8 -t CP1251 $? | \
$(SED) -e 's/charset=[uU][tT][fF]-8/charset=CP1251/' \
- -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \
+ -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \
> $@
prefixcheck:
@@ -241,6 +241,7 @@ prefixcheck:
clean: checkclean
rm -f core core.* *.old.po *.mo *.pot sjiscorr
rm -f LINGUAS vim.desktop gvim.desktop tmp_*desktop
+ rm -f ./allfiles
# rm -f big5corr
distclean: clean
@@ -261,21 +262,25 @@ PO_INPUTLIST = \
$(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST)
# Convert the Vim scripts to (what looks like) Javascript.
- $(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \
+ $(PO_VIM_INPUTLIST)
+ @ echo ${PO_INPUTLIST} | tr ' ' '\n' > ./allfiles
+ @ cat ./vim_to_js >> ./allfiles
# Create vim.pot.
- $(XGETTEXT) --default-domain=$(PACKAGE) --add-comments \
- $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST)
- mv -f $(PACKAGE).po $(PACKAGE).pot
+ $(XGETTEXT) --default-domain=$(PACKAGE) --output=$(PACKAGE).pot \
+ --add-comments $(XGETTEXT_KEYWORDS) --files-from=./allfiles
# Fix Vim scripts names, so that "gf" works.
- $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \
+ $(PO_VIM_INPUTLIST)
# Delete the temporary files.
- rm *.js
+ rm -f *.js ./vim_to_js
vim.desktop: vim.desktop.in $(POFILES)
echo $(LANGUAGES) | tr " " "\n" |$(SED) -e '/\./d' | sort > LINGUAS
$(MSGFMT) --desktop -d . --template vim.desktop.in -o tmp_vim.desktop
rm -f LINGUAS
- if command -v desktop-file-validate; then desktop-file-validate tmp_vim.desktop; fi
+ if command -v desktop-file-validate; \
+ then desktop-file-validate tmp_vim.desktop; fi
mv tmp_vim.desktop vim.desktop
# The dependency on vim.desktop is only to avoid the two targets are build at
@@ -284,7 +289,8 @@ gvim.desktop: gvim.desktop.in $(POFILES) vim.desktop
echo $(LANGUAGES) | tr " " "\n" |$(SED) -e '/\./d' | sort > LINGUAS
$(MSGFMT) --desktop -d . --template gvim.desktop.in -o tmp_gvim.desktop
rm -f LINGUAS
- if command -v desktop-file-validate; then desktop-file-validate tmp_gvim.desktop; fi
+ if command -v desktop-file-validate; \
+ then desktop-file-validate tmp_gvim.desktop; fi
mv tmp_gvim.desktop gvim.desktop
# Only original translations with default encoding should be updated.
@@ -301,3 +307,28 @@ $(LANGUAGES):
else \
echo "msgmerge for $@.po failed!"; mv $@.po.old $@.po; \
fi
+
+
+#######
+# For translations of plug-ins
+#######
+
+# Preparing the POT file of the plug-in package
+POT_PLUGPACKAGE_PATH = $(PWD)
+$(PLUGPACKAGE).pot: $(PO_PLUG_INPUTLIST)
+ $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim \
+ $(PLUGPACKAGE).pot $?
+ $(XGETTEXT) --from-code=UTF-8 --default-domain=$(PLUGPACKAGE) \
+ --package-name=$(PLUGPACKAGE) \
+ --output-dir=$(POT_PLUGPACKAGE_PATH) \
+ --output=$(PLUGPACKAGE).pot --files-from=./vim_to_js
+ $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim \
+ $(POT_PLUGPACKAGE_PATH)/$(PLUGPACKAGE).pot $?
+ rm -f *.js ./vim_to_js
+
+# Converting the PO file of the plug-in package to the binary format of the MO
+MO_PLUGPACKAGE_PATH = $(PWD)
+$(PLUGPACKAGE).mo: $(PO_PLUGPACKAGE)
+ $(MSGFMTCMD) -o $(MO_PLUGPACKAGE_PATH)/$@ $?
+
+# vim: set noet sw=8 ts=8 sts=0 wm=0 tw=0 ft=make:
diff --git a/src/po/README.txt b/src/po/README.txt
index 50aff6a..801f5e5 100644
--- a/src/po/README.txt
+++ b/src/po/README.txt
@@ -160,3 +160,20 @@ convert ja.po to EUC-JP (supposed as your system encoding):
"Content-Type: text/plain; charset=EUC-JP\n"
There are examples in the Makefile for the conversions already supported.
+
+
+TRANSLATION OF VIM THE EDITOR PLUG-INS
+
+Vim supports displaying plugin messages for various native languages.
+Translation is available both for plugins that are supplied as part of the Vim
+editor (e.g. "optwin.vim") and for third-party plugin packages.
+
+To translate the plugins supplied with the Vim editor, you must specify a
+gettext() function call for the strings you want to translate.
+The translation of these strings will be retrieved by gettext() from the MO
+file "vim.mo".
+
+For third-party plugins, it is necessary to specify a one-time call to the
+bindtextdomain() function in scripts containing translation strings and for
+all message strings to add a {package} argument to the gettext() function. For
+more information, see ":help package-translation".
diff --git a/src/po/README_mvc.txt b/src/po/README_mvc.txt
index ae9fa2b..e5fd85e 100644
--- a/src/po/README_mvc.txt
+++ b/src/po/README_mvc.txt
@@ -137,4 +137,22 @@ command:
nmake.exe -f Make_mvc.mak clean
+
+TRANSLATION OF VIM THE EDITOR PLUG-INS
+
+Vim supports displaying plugin messages for various native languages.
+Translation is available both for plugins that are supplied as part of the Vim
+editor (e.g. "optwin.vim") and for third-party plugin packages.
+
+To translate the plugins supplied with the Vim editor, you must specify a
+gettext() function call for the strings you want to translate.
+The translation of these strings will be retrieved by gettext() from the MO
+file "vim.mo".
+
+For third-party plugins, it is necessary to specify a one-time call to the
+bindtextdomain() function in scripts containing translation strings and for
+all message strings to add a {package} argument to the gettext() function. For
+more information, see ":help package-translation".
+
+
vim:tw=78:
diff --git a/src/po/ca.po b/src/po/ca.po
index caf02a9..052caad 100644
--- a/src/po/ca.po
+++ b/src/po/ca.po
@@ -1326,8 +1326,8 @@ msgstr " Compleció definida per l'usuari (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni-compleció (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Suggeriment d'ortografia (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Suggeriment d'ortografia (^S^N^P)"
# i C-x C-p
msgid " Keyword Local completion (^N^P)"
diff --git a/src/po/cleanup.vim b/src/po/cleanup.vim
index 1af188a..5e1b967 100644
--- a/src/po/cleanup.vim
+++ b/src/po/cleanup.vim
@@ -9,24 +9,24 @@ let s:was_diff = &diff
setl nodiff
" untranslated message preceded by c-format or comment
-silent g/^#, c-format\n#/.d
-silent g/^#\..*\n#/.d
+silent g/^#, c-format\n#/.d _
+silent g/^#\..*\n#/.d _
" c-format comments have no effect, the check.vim scripts checks it.
" But they might still be useful?
-" silent g/^#, c-format$/d
+" silent g/^#, c-format$/d _
-silent g/^#[:~] /d
+silent g/^#[:~] /d _
silent g/^#, fuzzy\(, .*\)\=\nmsgid ""\@!/.+1,/^$/-1s/^/#\~ /
silent g/^msgstr"/s//msgstr "/
silent g/^msgid"/s//msgid "/
silent g/^msgstr ""\(\n"\)\@!/?^msgid?,.s/^/#\~ /
" Comments only useful for the translator
-silent g/^#\. /d
+silent g/^#\./d _
" clean up empty lines
-silent g/^\n\n\n/.d
+silent g/^\n\n\n/.d _
silent! %s/\n\+\%$//
if s:was_diff
diff --git a/src/po/cs.cp1250.po b/src/po/cs.cp1250.po
index bed2595..24209c9 100644
--- a/src/po/cs.cp1250.po
+++ b/src/po/cs.cp1250.po
@@ -13,7 +13,7 @@ msgstr ""
"Last-Translator: Jiøí Pavlovský <jpavlovsky@mbox.vol.cz>\n"
"Language-Team: Czech <cs@li.org>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=cp1250\n"
+"Content-Type: text/plain; charset=CP1250\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "E82: Cannot allocate any buffer, exiting..."
diff --git a/src/po/da.po b/src/po/da.po
index 80cc6fe..4cb212a 100644
--- a/src/po/da.po
+++ b/src/po/da.po
@@ -412,8 +412,8 @@ msgstr " Fuldførelse af brugerdefineret (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Fuldførelse af omni (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Staveforslag (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Staveforslag (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Fuldførelse af nøgleord local (^N^P)"
diff --git a/src/po/de.po b/src/po/de.po
index f0f00d7..99a62db 100644
--- a/src/po/de.po
+++ b/src/po/de.po
@@ -1376,8 +1376,8 @@ msgstr " Benutzerdefinierte Vervollständigung (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni-Vervollständigung (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Vorschlag der Rechtschreibprüfung (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Vorschlag der Rechtschreibprüfung (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Lokale Stichwort-Vervollständigung(^N^P)"
diff --git a/src/po/eo.po b/src/po/eo.po
index a9aaefa..3f86652 100644
--- a/src/po/eo.po
+++ b/src/po/eo.po
@@ -2616,8 +2616,8 @@ msgstr " Kompletigo difinita de uzanto (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Kompletigo Omni (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Sugesto de literumo (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Sugesto de literumo (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Kompletigo loka de Ålosilvorto (^N/^P)"
diff --git a/src/po/es.po b/src/po/es.po
index f4a02fa..8b072d8 100644
--- a/src/po/es.po
+++ b/src/po/es.po
@@ -1351,8 +1351,8 @@ msgstr " Completar definido por usuario (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Completar con método Omni (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Sugerencia de ortografía (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Sugerencia de ortografía (^S^N^P)"
# Scroll has its own msgs, in its place there is the msg for local
# * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL) -- Acevedo
diff --git a/src/po/fi.po b/src/po/fi.po
index d2fd336..9dc24d3 100644
--- a/src/po/fi.po
+++ b/src/po/fi.po
@@ -1325,8 +1325,8 @@ msgstr " Käyttäjän määrittelemä täydennys (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omnitäydennys (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Oikaisulukuehdotus (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Oikaisulukuehdotus (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Avainsanan paikallinen täydennys (^N^P)"
diff --git a/src/po/fixfilenames.vim b/src/po/fixfilenames.vim
index 04bc079..2344b3b 100644
--- a/src/po/fixfilenames.vim
+++ b/src/po/fixfilenames.vim
@@ -3,9 +3,11 @@
set shortmess+=A
-for name in argv()[1:]
- let jsname = fnamemodify(name, ":t:r") .. ".js"
- exe "%s+" .. jsname .. "+" .. substitute(name, '\\', '/', 'g') .. "+"
+let s:namenum = 0
+for s:name in argv()[1:]
+ let s:jsname = fnamemodify(s:name, ":t:r") .. s:namenum .. ".js"
+ exe "%s+" .. s:jsname .. "+" .. substitute(s:name, '\\', '/', 'g') .. "+ge"
+ let s:namenum +=1
endfor
write
diff --git a/src/po/fr.po b/src/po/fr.po
index 27f11eb..3a55f8d 100644
--- a/src/po/fr.po
+++ b/src/po/fr.po
@@ -2738,8 +2738,8 @@ msgstr " Complètement défini par l'utilisateur (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Complètement selon le type de fichier (Omni) (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Suggestion d'orthographe (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Suggestion d'orthographe (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Complètement local de mot-clé (^N/^P)"
diff --git a/src/po/ga.po b/src/po/ga.po
index e81ef69..cd1a029 100644
--- a/src/po/ga.po
+++ b/src/po/ga.po
@@ -1401,8 +1401,8 @@ msgstr " Comhlánú saincheaptha (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Comhlánú Omni (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Moladh litrithe (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Moladh litrithe (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Comhlánú logánta lorgfhocal (^N^P)"
diff --git a/src/po/hu.po b/src/po/hu.po
index 0a11847..221cf33 100644
--- a/src/po/hu.po
+++ b/src/po/hu.po
@@ -264,8 +264,8 @@ msgstr " Felhasználó által definiált kiegészítés (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni kiegészítés (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Helyesírási javaslat (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Helyesírási javaslat (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Kulcsszó helyi kiegészítés (^N^P)"
diff --git a/src/po/it.po b/src/po/it.po
index fde1c23..78c2130 100644
--- a/src/po/it.po
+++ b/src/po/it.po
@@ -14,8 +14,8 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-05-28 09:50+0200\n"
-"PO-Revision-Date: 2024-03-06 15:00+0100\n"
+"POT-Creation-Date: 2024-08-11 10:10+0200\n"
+"PO-Revision-Date: 2024-08-11 10:36+0100\n"
"Last-Translator: Antonio Colombo <azc100@gmail.com>\n"
"Language-Team: Italian\n"
"Language: it\n"
@@ -583,16 +583,16 @@ msgid "Greetings, Vim user!"
msgstr "Salve, utente Vim!"
msgid "Already only one tab page"
-msgstr "C'è già un'unica pagina di linguette"
+msgstr "C'è già un'unica pagina di schede"
msgid "Edit File in new tab page"
-msgstr "Apri il File in una nuova pagina di linguette"
+msgstr "Apri il File in una nuova pagina di schede"
msgid "Edit File in new window"
msgstr "Apri il File in una nuova finestra"
msgid "Tab page %d"
-msgstr "Pagina di linguette %d"
+msgstr "Pagina di schede %d"
msgid "No swap file"
msgstr "Non posso creare un file di swap"
@@ -895,13 +895,13 @@ msgid "Vim: Received \"die\" request from session manager\n"
msgstr "Vim: Ricevuta richiesta \"die\" dal Session Manager\n"
msgid "Close tab"
-msgstr "Chiudi linguetta"
+msgstr "Chiudi scheda"
msgid "New tab"
-msgstr "Nuova linguetta"
+msgstr "Nuova scheda"
msgid "Open Tab..."
-msgstr "Apri linguetta..."
+msgstr "Apri scheda..."
msgid "Vim: Main window unexpectedly destroyed\n"
msgstr "Vim: Finestra principale distrutta inaspettatamente\n"
@@ -946,7 +946,7 @@ msgid "&Undo"
msgstr "&U Disfa"
msgid "Open tab..."
-msgstr "Apri linguetta..."
+msgstr "Apri scheda..."
msgid "Find string"
msgstr "Trova stringa"
@@ -1287,8 +1287,8 @@ msgstr " Completamento definito dall'utente (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Completamento globale (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Suggerimento ortografico (s^N^P)"
+msgid " Spelling suggestion (^s^N^P)"
+msgstr " Suggerimento ortografico (^s^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Completamento Parola Locale (^N^P)"
@@ -1604,7 +1604,7 @@ msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\t\tNon caricare script plugin"
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-o[N]\t\tApri N pagine di linguette (predefinito: una per ogni file)"
+msgstr "-o[N]\t\tApri N pagine di schede (predefinito: una per ogni file)"
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\t\tApri N finestre (predefinito: una per ogni file)"
@@ -1667,7 +1667,7 @@ msgid ""
"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
msgstr ""
"--remote-tab[-wait][-silent] <file> Come --remote, ma apre una pagina di "
-"linguette per file"
+"schede per file"
msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
msgstr "--remote-send <tasti>\tInvia <tasti> a un server Vim ed esci"
@@ -5538,9 +5538,6 @@ msgstr "E612: Troppi 'sign' definiti"
msgid "E613: Unknown printer font: %s"
msgstr "E613: Carattere di stampa sconosciuto: %s"
-msgid "E614: Class required"
-msgstr "E614: Classe richiesta"
-
msgid "E616: Object required for argument %d"
msgstr "E616: Object richiesto per argomento %d"
@@ -6045,7 +6042,7 @@ msgid "E783: Duplicate char in MAP entry"
msgstr "E783: Carattere duplicato nell'elemento MAP"
msgid "E784: Cannot close last tab page"
-msgstr "E784: Non posso chiudere l'ultima pagina di linguette"
+msgstr "E784: Non posso chiudere l'ultima pagina di schede"
msgid "E785: complete() can only be used in Insert mode"
msgstr "E785: complete() può essere usata solo in modalità inserimento"
@@ -6747,7 +6744,7 @@ msgid "E996: Cannot lock a register"
msgstr "E996: Non posso bloccare un registro"
msgid "E997: Tabpage not found: %d"
-msgstr "E997: Pagina-di-linguette non trovata: %d"
+msgstr "E997: Pagina-di-schede non trovata: %d"
msgid "E998: Reduce of an empty %s with no initial value"
msgstr ""
@@ -7715,7 +7712,7 @@ msgstr "E1307: Argomento %d: Tenta di modificare la costante %s"
msgid "E1308: Cannot resize a window in another tab page"
msgstr ""
-"E1308: Non posso ridimensionare una finestra in un'altra pagine di linguette"
+"E1308: Non posso ridimensionare una finestra in un'altra pagine di schede"
msgid "E1309: Cannot change mappings while listing"
msgstr "E1309: Non posso modificare mappature mentre le sto elencando"
@@ -7749,21 +7746,12 @@ msgstr "E1317: Dichiarazione di variabile Object non valida: %s"
msgid "E1318: Not a valid command in a class: %s"
msgstr "E1318: Comando non valido in una Classe: %s"
-msgid "E1319: Using a Class as a Number"
-msgstr "E1319: Uso di una Classe come un Numero"
-
msgid "E1320: Using an Object as a Number"
msgstr "E1320: Uso di un Object come un Numero"
-msgid "E1321: Using a Class as a Float"
-msgstr "E1321: Uso di una Classe come un Numero-a-virgola-mobile"
-
msgid "E1322: Using an Object as a Float"
msgstr "E1322: Uso di un Object come un Numero-a-virgola-mobile"
-msgid "E1323: Using a Class as a String"
-msgstr "E1323: Uso di una Classe come una Stringa"
-
msgid "E1324: Using an Object as a String"
msgstr "E1324: Uso di un Object come una Stringa"
@@ -7794,8 +7782,8 @@ msgstr ""
msgid "E1332: public variable name cannot start with underscore: %s"
msgstr ""
-"E1332: Il nome di un elemento public non può iniziare con il trattino "
-"basso: %s"
+"E1332: Il nome di un elemento public non può iniziare con il trattino basso: "
+"%s"
msgid "E1333: Cannot access protected variable \"%s\" in class \"%s\""
msgstr ""
@@ -8004,9 +7992,6 @@ msgstr "E1393: Il Tipo può essere definito solo negli script Vim9"
msgid "E1394: Type name must start with an uppercase letter: %s"
msgstr "E1394: Il nome di un Tipo deve iniziare con una lettera maiuscola: %s"
-msgid "E1395: Type alias \"%s\" cannot be modified"
-msgstr "E1395: Il Tipo alias \"%s\" non può essere modificato"
-
msgid "E1396: Type alias \"%s\" already exists"
msgstr "E1396: Il Tipo alias \"%s\" esiste già"
@@ -8019,15 +8004,6 @@ msgstr "E1398: Manca il tipo del Tipo alias"
msgid "E1399: Type can only be used in a script"
msgstr "E1399: \"Tipo\" si può usare solo in uno script"
-msgid "E1400: Using type alias \"%s\" as a Number"
-msgstr "E1400: Uso del Tipo alias \"%s\" come un Numero"
-
-msgid "E1401: Using type alias \"%s\" as a Float"
-msgstr "E1401: Uso del Tipo alias \"%s\" come un Numero-a-virgola-mobile"
-
-msgid "E1402: Using type alias \"%s\" as a String"
-msgstr "E1402: Uso del Tipo alias \"%s\" come una Stringa"
-
msgid "E1403: Type alias \"%s\" cannot be used as a value"
msgstr "E1403: Impossibile usare il Tipo alias \"%s\" come valore"
@@ -8037,9 +8013,6 @@ msgstr "E1404: Impossibile usare \"Abstract\" in un'Interfaccia"
msgid "E1405: Class \"%s\" cannot be used as a value"
msgstr "E1405: Impossibile usare Classe \"%s\" come valore"
-msgid "E1406: Cannot use a Class as a variable or value"
-msgstr "E1406: Impossibile usare una Classe come variabile o valore"
-
msgid "E1407: Cannot use a Typealias as a variable or value"
msgstr "E1407: Impossibile usare un Tipo alias come variabile o valore"
@@ -8158,8 +8131,8 @@ msgid "E1512: Wrong character width for field \"%s\""
msgstr "E1512: Larghezza carattere errata per campo \"%s\""
msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled"
-msgstr "E1513: Non riesco a passare a un altro buffer. Opzione "
-"'winfixbuf' attiva"
+msgstr ""
+"E1513: Non riesco a passare a un altro buffer. Opzione 'winfixbuf' attiva"
#. type of cmdline window or 0
#. result of cmdline window or 0
@@ -8362,10 +8335,10 @@ msgid "unable to unset option %s which does not have global value"
msgstr "impossibile rimuovere l'opzione %s che non ha un valore globale"
msgid "attempt to refer to deleted tab page"
-msgstr "tentativo di riferimento a pagina di linguette cancellata"
+msgstr "tentativo di riferimento a pagina di schede cancellata"
msgid "no such tab page"
-msgstr "pagina di linguette inesistente"
+msgstr "pagina di schede inesistente"
msgid "attempt to refer to deleted window"
msgstr "tentativo di riferimento a una finestra cancellata"
@@ -8399,7 +8372,7 @@ msgstr "atteso Object vim.Window, ottenuto %s"
msgid "failed to find window in the current tab page"
msgstr ""
-"non è stato possibile trovare la finestra nella pagina di linguette corrente"
+"non è stato possibile trovare la finestra nella pagina di schede corrente"
msgid "did not switch to the specified window"
msgstr "passaggio alla finestra specificata non effettuato"
@@ -8408,7 +8381,7 @@ msgid "expected vim.TabPage object, but got %s"
msgstr "atteso Object vim.TabPage, ottenuto %s"
msgid "did not switch to the specified tab page"
-msgstr "passaggio alla pagina di linguette specificata non effettuato"
+msgstr "passaggio alla pagina di schede specificata non effettuato"
msgid "failed to run the code"
msgstr "esecuzione del codice non riuscita"
@@ -8988,24 +8961,28 @@ msgid "name of the winpty dynamic library"
msgstr "nome della libreria dinamica winpty"
msgid "multiple tab pages"
-msgstr "più di una pagina di linguette"
+msgstr "più di una pagina di schede"
msgid "0, 1 or 2; when to use a tab pages line"
-msgstr "0, 1 o 2; utilizzo della riga che descrive pagine di linguette"
+msgstr "0, 1 o 2; utilizzo della riga che descrive pagine di schede"
+
+msgid "behaviour when closing tab pages: left, uselast or empty"
+msgstr ""
+"comportamento alla chiusura di pagine di schede: left, uselast o empty"
msgid "maximum number of tab pages to open for -p and \"tab all\""
msgstr ""
-"massimo numero di pagine di linguette da aprire\n"
+"massimo numero di pagine di schede da aprire\n"
"per -p e \"tab all\""
msgid "custom tab pages line"
-msgstr "personalizzazione riga che descrive le pagine di linguette"
+msgstr "personalizzazione riga che descrive le pagine di schede"
msgid "custom tab page label for the GUI"
-msgstr "personalizzazione etichetta per le pagine di linguette nella GUI"
+msgstr "personalizzazione etichetta per le pagine di schede nella GUI"
msgid "custom tab page tooltip for the GUI"
-msgstr "personalizzazione suggerimento per le pagine di linguette nella GUI"
+msgstr "personalizzazione suggerimento per le pagine di schede nella GUI"
msgid "terminal"
msgstr "terminale"
diff --git a/src/po/ja.euc-jp.po b/src/po/ja.euc-jp.po
index 362be9e..ced4cd9 100644
--- a/src/po/ja.euc-jp.po
+++ b/src/po/ja.euc-jp.po
@@ -3,7 +3,7 @@
# Do ":help uganda" in Vim to read copying and usage conditions.
# Do ":help credits" in Vim to see a list of people who contributed.
#
-# Copyright (C) 2001-2023 MURAOKA Taro <koron.kaoriya@gmail.com>,
+# Copyright (C) 2001-2024 MURAOKA Taro <koron.kaoriya@gmail.com>,
# vim-jp <http://vim-jp.org/>
#
# THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
@@ -12,10 +12,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Vim 9.0\n"
+"Project-Id-Version: Vim 9.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-12-18 16:41+0900\n"
-"PO-Revision-Date: 2023-12-19 12:45+0900\n"
+"POT-Creation-Date: 2024-07-23 10:59+0900\n"
+"PO-Revision-Date: 2024-08-15 12:54+0900\n"
"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
"Language-Team: Japanese <https://github.com/vim-jp/lang-ja>\n"
"Language: ja\n"
@@ -175,6 +175,9 @@ msgstr " (file %d of %d)"
msgid " (file (%d) of %d)"
msgstr " (file (%d) of %d)"
+msgid "[Command Line]"
+msgstr "[¥³¥Þ¥ó¥É¥é¥¤¥ó]"
+
msgid "[Prompt]"
msgstr "[¥×¥í¥ó¥×¥È]"
@@ -439,10 +442,6 @@ msgstr "ÊÒ²¾Ì¾"
msgid "Bopomofo"
msgstr "Ãí²»»úÊì"
-msgid "Not enough memory to set references, garbage collection aborted!"
-msgstr ""
-"¥¬¡¼¥Ù¥Ã¥¸¥³¥ì¥¯¥·¥ç¥ó¤òÃæ»ß¤·¤Þ¤·¤¿! »²¾È¤òºîÀ®¤¹¤ë¤Î¤Ë¥á¥â¥ê¤¬ÉÔ­¤·¤Þ¤·¤¿"
-
msgid ""
"\n"
"\tLast set from "
@@ -688,9 +687,6 @@ msgstr "¥¨¥é¡¼"
msgid "Interrupt"
msgstr "³ä¹þ¤ß"
-msgid "[Command Line]"
-msgstr "[¥³¥Þ¥ó¥É¥é¥¤¥ó]"
-
msgid "is a directory"
msgstr "¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹"
@@ -854,6 +850,10 @@ msgid "+-%s%3ld line: "
msgid_plural "+-%s%3ld lines: "
msgstr[0] "+-%s%3ld ¹Ô: "
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr ""
+"¥¬¡¼¥Ù¥Ã¥¸¥³¥ì¥¯¥·¥ç¥ó¤òÃæ»ß¤·¤Þ¤·¤¿! »²¾È¤òºîÀ®¤¹¤ë¤Î¤Ë¥á¥â¥ê¤¬ÉÔ­¤·¤Þ¤·¤¿"
+
msgid "No match at cursor, finding next"
msgstr "¥«¡¼¥½¥ë¤Î°ÌÃ֤˥ޥåÁ¤Ï¤¢¤ê¤Þ¤»¤ó¡¢¼¡¤ò¸¡º÷¤·¤Æ¤¤¤Þ¤¹"
@@ -1337,8 +1337,8 @@ msgstr " ¥æ¡¼¥¶¡¼ÄêµÁÊä´° (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " ¥ª¥à¥ËÊä´° (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Ä֤꽤Àµ¸õÊä (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Ä֤꽤Àµ¸õÊä (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " ¶É½ê¥­¡¼¥ï¡¼¥ÉÊä´° (^N^P)"
@@ -1416,6 +1416,9 @@ msgstr "mapnew() ¤Î°ú¿ô"
msgid "filter() argument"
msgstr "filter() ¤Î°ú¿ô"
+msgid "foreach() argument"
+msgstr "foreach() ¤Î°ú¿ô"
+
msgid "extendnew() argument"
msgstr "extendnew() ¤Î°ú¿ô"
@@ -2454,6 +2457,9 @@ msgstr "%s ¤Ø (%s ¾å¤Î)"
msgid "Printing '%s'"
msgstr "°õºþ¤·¤Æ¤¤¤Þ¤¹: '%s'"
+#~ msgid "DefaultFontNameForWindows"
+#~ msgstr ""
+
#, c-format
msgid "Opening the X display took %ld msec"
msgstr "X¥µ¡¼¥Ð¡¼¤Ø¤ÎÀܳ¤Ë %ld ¥ß¥êÉ䫤«¤ê¤Þ¤·¤¿"
@@ -3394,8 +3400,8 @@ msgid "%s returning %s"
msgstr "%s ¤¬ %s ¤òÊÖ¤·¤Þ¤·¤¿"
#, c-format
-msgid "Function %s does not need compiling"
-msgstr "´Ø¿ô %s ¤Ï¥³¥ó¥Ñ¥¤¥ë¤ÎɬÍפ¬¤¢¤ê¤Þ¤»¤ó"
+msgid "Function %s%s%s does not need compiling"
+msgstr "´Ø¿ô %s%s%s ¤Ï¥³¥ó¥Ñ¥¤¥ë¤ÎɬÍפ¬¤¢¤ê¤Þ¤»¤ó"
#, c-format
msgid "%s (%s, compiled %s)"
@@ -3554,6 +3560,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: \""
@@ -4158,6 +4167,10 @@ msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :source ¤Ç¼è¹þ¤à¥Õ¥¡¥¤¥ë°Ê³°¤Ç¤Ï :loadkeymap ¤ò»È¤¨¤Þ¤»¤ó"
#, c-format
+msgid "E106: Unsupported diff output format: %s"
+msgstr "E106: ¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤diff½ÐÎÏ¥Õ¥©¡¼¥Þ¥Ã¥È¤Ç¤¹: %s"
+
+#, c-format
msgid "E107: Missing parentheses: %s"
msgstr "E107: ¥«¥Ã¥³ '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
@@ -4486,8 +4499,8 @@ msgstr "E196: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¹ç»ú¤Ï¤¢¤ê¤Þ¤»¤ó"
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: ¸À¸ì¤ò \"%s\" ¤ËÀßÄê¤Ç¤­¤Þ¤»¤ó"
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: ¥¢¥¯¥Æ¥£¥Ö¤Ê¥¦¥£¥ó¥É¥¦¤«¥Ð¥Ã¥Õ¥¡¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿"
+msgid "E199: Active window or buffer changed or deleted"
+msgstr "E199: ¥¢¥¯¥Æ¥£¥Ö¤Ê¥¦¥£¥ó¥É¥¦¤«¥Ð¥Ã¥Õ¥¡¤¬Êѹ¹¤Þ¤¿¤Ïºï½ü¤µ¤ì¤Þ¤·¤¿"
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: *ReadPre ¼«Æ°¥³¥Þ¥ó¥É ¤¬¥Õ¥¡¥¤¥ë¤òÆɹþÉԲĤˤ·¤Þ¤·¤¿"
@@ -5857,9 +5870,6 @@ msgstr "E612: sign¤ÎÄêµÁ¤¬Â¿²á¤®¤Þ¤¹"
msgid "E613: Unknown printer font: %s"
msgstr "E613: ̤ÃΤΥץê¥ó¥¿¥ª¥×¥·¥ç¥ó¤Ç¤¹: %s"
-msgid "E614: Class required"
-msgstr "E614: ¥¯¥é¥¹¤¬É¬ÍפǤ¹"
-
#, c-format
msgid "E616: Object required for argument %d"
msgstr "E616: °ú¿ô %d ¤Ë¤Ï¥ª¥Ö¥¸¥§¥¯¥È¤¬É¬ÍפǤ¹"
@@ -6696,7 +6706,7 @@ msgid "E862: Cannot use g: here"
msgstr "E862: ¤³¤³¤Ç¤Ï g: ¤Ï»È¤¨¤Þ¤»¤ó"
msgid "E863: Not allowed for a terminal in a popup window"
-msgstr "E863: üËö¤Ï¥Ý¥Ã¥×¥¢¥Ã¥×¥¦¥£¥ó¥É¥¦¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
+msgstr "E863: ¥Ý¥Ã¥×¥¢¥Ã¥×¥¦¥£¥ó¥É¥¦Æâ¤ÎüËö¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
#, no-c-format
msgid ""
@@ -6753,6 +6763,10 @@ msgstr ""
msgid "E876: (NFA regexp) Not enough space to store the whole NFA"
msgstr "E876: (NFA Àµµ¬É½¸½) NFAÁ´ÂΤòÊݸ¤¹¤ë¤Ë¤Ï¶õ¤­¥¹¥Ú¡¼¥¹¤¬Â­¤ê¤Þ¤»¤ó"
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %d"
+msgstr "E877: (NFA Àµµ¬É½¸½) ̵¸ú¤Êʸ»ú¥¯¥é¥¹¤Ç¤¹: %d"
+
msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!"
msgstr ""
"E878: (NFA Àµµ¬É½¸½) ¸½ºß²£ÃÇÃæ¤Î¥Ö¥é¥ó¥Á¤Ë½½Ê¬¤Ê¥á¥â¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó!"
@@ -8319,21 +8333,12 @@ msgstr "E1317: ÉÔÀµ¤Ê¥ª¥Ö¥¸¥§¥¯¥ÈÊÑ¿ô¤ÎÀë¸À¤Ç¤¹: %s"
msgid "E1318: Not a valid command in a class: %s"
msgstr "E1318: ¥¯¥é¥¹Æâ¤Ç¤Ï»È¤¨¤Ê¤¤¥³¥Þ¥ó¥É¤Ç¤¹: %s"
-msgid "E1319: Using a Class as a Number"
-msgstr "E1319: ¥¯¥é¥¹¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-
msgid "E1320: Using an Object as a Number"
msgstr "E1320: ¥ª¥Ö¥¸¥§¥¯¥È¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-msgid "E1321: Using a Class as a Float"
-msgstr "E1321: ¥¯¥é¥¹¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-
msgid "E1322: Using an Object as a Float"
msgstr "E1322: ¥ª¥Ö¥¸¥§¥¯¥È¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-msgid "E1323: Using a Class as a String"
-msgstr "E1323: ¥¯¥é¥¹¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-
msgid "E1324: Using an Object as a String"
msgstr "E1324: ¥ª¥Ö¥¸¥§¥¯¥È¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
@@ -8362,14 +8367,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\" ¤¬É¬Í×"
"¤Ç¤¹"
#, c-format
-msgid "E1332: Public variable name cannot start with underscore: %s"
+msgid "E1332: public variable name cannot start with underscore: %s"
msgstr "E1332: ¥Ñ¥Ö¥ê¥Ã¥¯ÊÑ¿ô̾¤Ï¥¢¥ó¥À¡¼¥¹¥³¥¢¤Ç»Ï¤á¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó: %s"
#, c-format
@@ -8575,10 +8580,10 @@ msgstr ""
"E1386: ¥ª¥Ö¥¸¥§¥¯¥È¥á¥½¥Ã¥É \"%s\" ¤Ï¥¯¥é¥¹ \"%s\" ¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò»È¤¦¤³¤È¤Î"
"¤ß¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤¹"
-msgid "E1387: Public variable not supported in an interface"
+msgid "E1387: public variable not supported in an interface"
msgstr "E1387: ¥¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹Æâ¤Ç¥Ñ¥Ö¥ê¥Ã¥¯ÊÑ¿ô¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-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"
@@ -8608,10 +8613,6 @@ msgid "E1394: Type name must start with an uppercase letter: %s"
msgstr "E1394: ·¿¤Î̾Á°¤Ï±ÑÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s"
#, c-format
-msgid "E1395: Type alias \"%s\" cannot be modified"
-msgstr "E1395: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
-
-#, c-format
msgid "E1396: Type alias \"%s\" already exists"
msgstr "E1396: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤Ï´û¤Ë¸ºß¤·¤Þ¤¹"
@@ -8625,18 +8626,6 @@ msgid "E1399: Type can only be used in a script"
msgstr "E1399: ·¿¤Ï¥¹¥¯¥ê¥×¥È¤ÎÃæ¤Ç¤Î¤ß»ÈÍѤǤ­¤Þ¤¹"
#, c-format
-msgid "E1400: Using type alias \"%s\" as a Number"
-msgstr "E1400: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-
-#, c-format
-msgid "E1401: Using type alias \"%s\" as a Float"
-msgstr "E1401: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-
-#, c-format
-msgid "E1402: Using type alias \"%s\" as a String"
-msgstr "E1402: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-
-#, c-format
msgid "E1403: Type alias \"%s\" cannot be used as a value"
msgstr "E1403: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤òÃͤȤ·¤Æ»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
@@ -8647,9 +8636,6 @@ msgstr "E1404: abstract ¤ò¥¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹Æâ¤Ç»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
msgid "E1405: Class \"%s\" cannot be used as a value"
msgstr "E1405: ¥¯¥é¥¹ \"%s\" ¤òÃͤȤ·¤Æ»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-msgid "E1406: Cannot use a Class as a variable or value"
-msgstr "E1406: ¥¯¥é¥¹¤òÊÑ¿ô¤äÃͤȤ·¤Æ»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-
msgid "E1407: Cannot use a Typealias as a variable or value"
msgstr "E1407: ·¿¥¨¥¤¥ê¥¢¥¹¤òÊÑ¿ô¤äÃͤȤ·¤Æ»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
@@ -8665,6 +8651,76 @@ msgid "E1410: Const variable not supported in an interface"
msgstr "E1410: ¥¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹Æâ¤Ç const ÊÑ¿ô¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
#, c-format
+msgid "E1411: Missing dot after object \"%s\""
+msgstr "E1411: ¥ª¥Ö¥¸¥§¥¯¥È \"%s\" ¤Î¸å¤Ë¥É¥Ã¥È¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E1412: Builtin object method \"%s\" not supported"
+msgstr "E1412: ÁȤ߹þ¤ß¥ª¥Ö¥¸¥§¥¯¥È¥á¥½¥Ã¥É \"%s\" ¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "E1413: Builtin class method not supported"
+msgstr "E1413: ÁȤ߹þ¤ß¥¯¥é¥¹¥á¥½¥Ã¥É¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "E1414: Enum can only be defined in Vim9 script"
+msgstr "E1414: Îóµó·¿¤Ï Vim9 script ¤ÎÃæ¤Ç¤Î¤ßÄêµÁ¤Ç¤­¤Þ¤¹"
+
+#, 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: ¥¯¥é¥¹¤Ï¥¹¥¯¥ê¥×¥È¤ÎÃæ¤Ç¤Î¤ß»ÈÍѤǤ­¤Þ¤¹"
+
+#, c-format
msgid "E1500: Cannot mix positional and non-positional arguments: %s"
msgstr "E1500: °ÌÃÖ°ú¿ô¤ÈÈó°ÌÃÖ°ú¿ô¤òº®¤¼¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó: %s"
@@ -8708,6 +8764,17 @@ msgstr "E1509: ³Èĥ°À­¤ÎÆɹþ¤ß¤Þ¤¿¤Ï½ñ¹þ¤ß¤Ç¥¨¥é¡¼¤¬µ¯¤­¤Þ¤·¤¿"
msgid "E1510: Value too large: %s"
msgstr "E1510: Ãͤ¬Â礭²á¤®¤Þ¤¹: %s"
+#, c-format
+msgid "E1511: Wrong number of characters for field \"%s\""
+msgstr "E1511: ¥Õ¥£¡¼¥ë¥É \"%s\" ¤Îʸ»ú¿ô¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
+
+#, c-format
+msgid "E1512: Wrong character width for field \"%s\""
+msgstr "E1512: ¥Õ¥£¡¼¥ë¥É \"%s\" ¤Îʸ»úÉý¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled"
+msgstr "E1513: ¥Ð¥Ã¥Õ¥¡¤òÀÚ¤êÂؤ¨¤é¤ì¤Þ¤»¤ó¡£'winfixbuf' ¤¬Í­¸ú²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
msgid "--No lines in buffer--"
msgstr "--¥Ð¥Ã¥Õ¥¡¤Ë¹Ô¤¬¤¢¤ê¤Þ¤»¤ó--"
@@ -9096,7 +9163,7 @@ msgid "\" Hit <Enter> on an index line to jump there."
msgstr "\" ¥¤¥ó¥Ç¥Ã¥¯¥¹¹Ô¤Ç <Enter> ¤òÂǤĤȡ¢¤½¤³¤Ë¥¸¥ã¥ó¥×¤·¤Þ¤¹¡£"
msgid "\" Hit <Space> on a \"set\" line to refresh it."
-msgstr "\" \"set\" ¹Ô¤Ç <Spece> ¤òÂǤĤȡ¢ºÇ¿·¤ÎÃͤ¬Æɹþ¤Þ¤ì¤Þ¤¹¡£"
+msgstr "\" \"set\" ¹Ô¤Ç <Space> ¤òÂǤĤȡ¢ºÇ¿·¤ÎÃͤ¬Æɹþ¤Þ¤ì¤Þ¤¹¡£"
msgid "important"
msgstr "½ÅÍ×"
@@ -9415,6 +9482,9 @@ msgstr "¸½ºß¤Î¥¦¥£¥ó¥É¥¦¤Ë»È¤ï¤ì¤ëºÇ¾®¹Ô¿ô"
msgid "minimal number of lines used for any window"
msgstr "Ǥ°Õ¤Î¥¦¥£¥ó¥É¥¦¤Ë»È¤ï¤ì¤ëºÇ¾®¹Ô¿ô"
+msgid "keep window focused on a single buffer"
+msgstr "¥¦¥£¥ó¥É¥¦¤¬Ê̤ΥХåե¡¤ËÀÚ¤êÂؤï¤é¤Ê¤¤¤è¤¦¤Ë¤¹¤ë"
+
msgid "keep the height of the window"
msgstr "¥¦¥£¥ó¥É¥¦¤Î¹â¤µ¤òÊݤÄ"
@@ -9490,6 +9560,9 @@ msgstr "Ê£¿ô¥¿¥Ö¥Ú¡¼¥¸"
msgid "0, 1 or 2; when to use a tab pages line"
msgstr "0, 1 ¤Þ¤¿¤Ï 2; ¥¿¥Ö¥Ú¡¼¥¸¹Ô¤ò¤¤¤Ä»È¤¦¤«"
+msgid "behaviour when closing tab pages: left, uselast or empty"
+msgstr "¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë¤È¤­¤ÎµóÆ°: left, uselast ¤Þ¤¿¤Ï empty"
+
msgid "maximum number of tab pages to open for -p and \"tab all\""
msgstr "-p ¤È \"tab all\" ¤Ç³«¤«¤ì¤ë¥¿¥Ö¥Ú¡¼¥¸¤ÎºÇÂç¿ô"
diff --git a/src/po/ja.po b/src/po/ja.po
index 5464bcc..5bcf8e1 100644
--- a/src/po/ja.po
+++ b/src/po/ja.po
@@ -3,7 +3,7 @@
# Do ":help uganda" in Vim to read copying and usage conditions.
# Do ":help credits" in Vim to see a list of people who contributed.
#
-# Copyright (C) 2001-2023 MURAOKA Taro <koron.kaoriya@gmail.com>,
+# Copyright (C) 2001-2024 MURAOKA Taro <koron.kaoriya@gmail.com>,
# vim-jp <http://vim-jp.org/>
#
# THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
@@ -12,10 +12,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Vim 9.0\n"
+"Project-Id-Version: Vim 9.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-12-18 16:41+0900\n"
-"PO-Revision-Date: 2023-12-19 12:45+0900\n"
+"POT-Creation-Date: 2024-07-23 10:59+0900\n"
+"PO-Revision-Date: 2024-08-15 12:54+0900\n"
"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
"Language-Team: Japanese <https://github.com/vim-jp/lang-ja>\n"
"Language: ja\n"
@@ -175,6 +175,9 @@ msgstr " (file %d of %d)"
msgid " (file (%d) of %d)"
msgstr " (file (%d) of %d)"
+msgid "[Command Line]"
+msgstr "[コマンドライン]"
+
msgid "[Prompt]"
msgstr "[プロンプト]"
@@ -439,10 +442,6 @@ msgstr "片仮å"
msgid "Bopomofo"
msgstr "注音字æ¯"
-msgid "Not enough memory to set references, garbage collection aborted!"
-msgstr ""
-"ガーベッジコレクションを中止ã—ã¾ã—ãŸ! å‚照を作æˆã™ã‚‹ã®ã«ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¾ã—ãŸ"
-
msgid ""
"\n"
"\tLast set from "
@@ -688,9 +687,6 @@ msgstr "エラー"
msgid "Interrupt"
msgstr "割込ã¿"
-msgid "[Command Line]"
-msgstr "[コマンドライン]"
-
msgid "is a directory"
msgstr "ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™"
@@ -854,6 +850,10 @@ msgid "+-%s%3ld line: "
msgid_plural "+-%s%3ld lines: "
msgstr[0] "+-%s%3ld 行: "
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr ""
+"ガーベッジコレクションを中止ã—ã¾ã—ãŸ! å‚照を作æˆã™ã‚‹ã®ã«ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¾ã—ãŸ"
+
msgid "No match at cursor, finding next"
msgstr "カーソルã®ä½ç½®ã«ãƒžãƒƒãƒã¯ã‚ã‚Šã¾ã›ã‚“ã€æ¬¡ã‚’検索ã—ã¦ã„ã¾ã™"
@@ -1337,8 +1337,8 @@ msgstr " ユーザー定義補完 (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " オムニ補完 (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " 綴り修正候補 (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " 綴り修正候補 (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " 局所キーワード補完 (^N^P)"
@@ -1416,6 +1416,9 @@ msgstr "mapnew() ã®å¼•æ•°"
msgid "filter() argument"
msgstr "filter() ã®å¼•æ•°"
+msgid "foreach() argument"
+msgstr "foreach() ã®å¼•æ•°"
+
msgid "extendnew() argument"
msgstr "extendnew() ã®å¼•æ•°"
@@ -2454,6 +2457,9 @@ msgstr "%s 㸠(%s 上ã®)"
msgid "Printing '%s'"
msgstr "å°åˆ·ã—ã¦ã„ã¾ã™: '%s'"
+#~ msgid "DefaultFontNameForWindows"
+#~ msgstr ""
+
#, c-format
msgid "Opening the X display took %ld msec"
msgstr "Xサーãƒãƒ¼ã¸ã®æŽ¥ç¶šã« %ld ミリ秒ã‹ã‹ã‚Šã¾ã—ãŸ"
@@ -3394,8 +3400,8 @@ msgid "%s returning %s"
msgstr "%s ㌠%s ã‚’è¿”ã—ã¾ã—ãŸ"
#, c-format
-msgid "Function %s does not need compiling"
-msgstr "関数 %s ã¯ã‚³ãƒ³ãƒ‘イルã®å¿…è¦ãŒã‚ã‚Šã¾ã›ã‚“"
+msgid "Function %s%s%s does not need compiling"
+msgstr "関数 %s%s%s ã¯ã‚³ãƒ³ãƒ‘イルã®å¿…è¦ãŒã‚ã‚Šã¾ã›ã‚“"
#, c-format
msgid "%s (%s, compiled %s)"
@@ -3554,6 +3560,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: \""
@@ -4158,6 +4167,10 @@ msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :source ã§å–込むファイル以外ã§ã¯ :loadkeymap を使ãˆã¾ã›ã‚“"
#, c-format
+msgid "E106: Unsupported diff output format: %s"
+msgstr "E106: サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„diff出力フォーマットã§ã™: %s"
+
+#, c-format
msgid "E107: Missing parentheses: %s"
msgstr "E107: カッコ '(' ãŒã‚ã‚Šã¾ã›ã‚“: %s"
@@ -4486,8 +4499,8 @@ msgstr "E196: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«åˆå­—ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: 言語を \"%s\" ã«è¨­å®šã§ãã¾ã›ã‚“"
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: アクティブãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‹ãƒãƒƒãƒ•ã‚¡ãŒå‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
+msgid "E199: Active window or buffer changed or deleted"
+msgstr "E199: アクティブãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‹ãƒãƒƒãƒ•ã‚¡ãŒå¤‰æ›´ã¾ãŸã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: *ReadPre 自動コマンド ãŒãƒ•ã‚¡ã‚¤ãƒ«ã‚’読込ä¸å¯ã«ã—ã¾ã—ãŸ"
@@ -5857,9 +5870,6 @@ msgstr "E612: signã®å®šç¾©ãŒå¤šéŽãŽã¾ã™"
msgid "E613: Unknown printer font: %s"
msgstr "E613: 未知ã®ãƒ—リンタオプションã§ã™: %s"
-msgid "E614: Class required"
-msgstr "E614: クラスãŒå¿…è¦ã§ã™"
-
#, c-format
msgid "E616: Object required for argument %d"
msgstr "E616: 引数 %d ã«ã¯ã‚ªãƒ–ジェクトãŒå¿…è¦ã§ã™"
@@ -6696,7 +6706,7 @@ msgid "E862: Cannot use g: here"
msgstr "E862: ã“ã“ã§ã¯ g: ã¯ä½¿ãˆã¾ã›ã‚“"
msgid "E863: Not allowed for a terminal in a popup window"
-msgstr "E863: 端末ã¯ãƒãƒƒãƒ—アップウィンドウã§ã¯è¨±ã•ã‚Œã¾ã›ã‚“"
+msgstr "E863: ãƒãƒƒãƒ—アップウィンドウ内ã®ç«¯æœ«ã§ã¯è¨±ã•ã‚Œã¾ã›ã‚“"
#, no-c-format
msgid ""
@@ -6753,6 +6763,10 @@ msgstr ""
msgid "E876: (NFA regexp) Not enough space to store the whole NFA"
msgstr "E876: (NFA æ­£è¦è¡¨ç¾) NFA全体をä¿å­˜ã™ã‚‹ã«ã¯ç©ºãスペースãŒè¶³ã‚Šã¾ã›ã‚“"
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %d"
+msgstr "E877: (NFA æ­£è¦è¡¨ç¾) 無効ãªæ–‡å­—クラスã§ã™: %d"
+
msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!"
msgstr ""
"E878: (NFA æ­£è¦è¡¨ç¾) ç¾åœ¨æ¨ªæ–­ä¸­ã®ãƒ–ランãƒã«å分ãªãƒ¡ãƒ¢ãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“!"
@@ -8319,21 +8333,12 @@ msgstr "E1317: ä¸æ­£ãªã‚ªãƒ–ジェクト変数ã®å®£è¨€ã§ã™: %s"
msgid "E1318: Not a valid command in a class: %s"
msgstr "E1318: クラス内ã§ã¯ä½¿ãˆãªã„コマンドã§ã™: %s"
-msgid "E1319: Using a Class as a Number"
-msgstr "E1319: クラスを数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-
msgid "E1320: Using an Object as a Number"
msgstr "E1320: オブジェクトを数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-msgid "E1321: Using a Class as a Float"
-msgstr "E1321: クラスを浮動å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-
msgid "E1322: Using an Object as a Float"
msgstr "E1322: オブジェクトを浮動å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-msgid "E1323: Using a Class as a String"
-msgstr "E1323: クラスを文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-
msgid "E1324: Using an Object as a String"
msgstr "E1324: オブジェクトを文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
@@ -8362,14 +8367,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\" ãŒå¿…è¦"
"ã§ã™"
#, c-format
-msgid "E1332: Public variable name cannot start with underscore: %s"
+msgid "E1332: public variable name cannot start with underscore: %s"
msgstr "E1332: パブリック変数åã¯ã‚¢ãƒ³ãƒ€ãƒ¼ã‚¹ã‚³ã‚¢ã§å§‹ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“: %s"
#, c-format
@@ -8575,10 +8580,10 @@ msgstr ""
"E1386: オブジェクトメソッド \"%s\" ã¯ã‚¯ãƒ©ã‚¹ \"%s\" ã®ã‚ªãƒ–ジェクトを使ã†ã“ã¨ã®"
"ã¿ã§ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™"
-msgid "E1387: Public variable not supported in an interface"
+msgid "E1387: public variable not supported in an interface"
msgstr "E1387: インターフェイス内ã§ãƒ‘ブリック変数ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
-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"
@@ -8608,10 +8613,6 @@ msgid "E1394: Type name must start with an uppercase letter: %s"
msgstr "E1394: åž‹ã®åå‰ã¯è‹±å¤§æ–‡å­—ã§å§‹ã¾ã‚‰ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“: %s"
#, c-format
-msgid "E1395: Type alias \"%s\" cannot be modified"
-msgstr "E1395: 型エイリアス \"%s\" ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
-
-#, c-format
msgid "E1396: Type alias \"%s\" already exists"
msgstr "E1396: 型エイリアス \"%s\" ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
@@ -8625,18 +8626,6 @@ msgid "E1399: Type can only be used in a script"
msgstr "E1399: åž‹ã¯ã‚¹ã‚¯ãƒªãƒ—トã®ä¸­ã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™"
#, c-format
-msgid "E1400: Using type alias \"%s\" as a Number"
-msgstr "E1400: 型エイリアス \"%s\" を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-
-#, c-format
-msgid "E1401: Using type alias \"%s\" as a Float"
-msgstr "E1401: 型エイリアス \"%s\" を浮動å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-
-#, c-format
-msgid "E1402: Using type alias \"%s\" as a String"
-msgstr "E1402: 型エイリアス \"%s\" を文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-
-#, c-format
msgid "E1403: Type alias \"%s\" cannot be used as a value"
msgstr "E1403: 型エイリアス \"%s\" を値ã¨ã—ã¦ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“"
@@ -8647,9 +8636,6 @@ msgstr "E1404: abstract をインターフェイス内ã§ä½¿ã†ã“ã¨ã¯ã§ãã
msgid "E1405: Class \"%s\" cannot be used as a value"
msgstr "E1405: クラス \"%s\" を値ã¨ã—ã¦ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-msgid "E1406: Cannot use a Class as a variable or value"
-msgstr "E1406: クラスを変数や値ã¨ã—ã¦ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-
msgid "E1407: Cannot use a Typealias as a variable or value"
msgstr "E1407: 型エイリアスを変数や値ã¨ã—ã¦ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“"
@@ -8665,6 +8651,76 @@ msgid "E1410: Const variable not supported in an interface"
msgstr "E1410: インターフェイス内㧠const 変数ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
#, c-format
+msgid "E1411: Missing dot after object \"%s\""
+msgstr "E1411: オブジェクト \"%s\" ã®å¾Œã«ãƒ‰ãƒƒãƒˆãŒã‚ã‚Šã¾ã›ã‚“"
+
+#, c-format
+msgid "E1412: Builtin object method \"%s\" not supported"
+msgstr "E1412: 組ã¿è¾¼ã¿ã‚ªãƒ–ジェクトメソッド \"%s\" ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+msgid "E1413: Builtin class method not supported"
+msgstr "E1413: 組ã¿è¾¼ã¿ã‚¯ãƒ©ã‚¹ãƒ¡ã‚½ãƒƒãƒ‰ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+msgid "E1414: Enum can only be defined in Vim9 script"
+msgstr "E1414: 列挙型㯠Vim9 script ã®ä¸­ã§ã®ã¿å®šç¾©ã§ãã¾ã™"
+
+#, 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: クラスã¯ã‚¹ã‚¯ãƒªãƒ—トã®ä¸­ã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™"
+
+#, c-format
msgid "E1500: Cannot mix positional and non-positional arguments: %s"
msgstr "E1500: ä½ç½®å¼•æ•°ã¨éžä½ç½®å¼•æ•°ã‚’æ··ãœã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“: %s"
@@ -8708,6 +8764,17 @@ msgstr "E1509: 拡張属性ã®èª­è¾¼ã¿ã¾ãŸã¯æ›¸è¾¼ã¿ã§ã‚¨ãƒ©ãƒ¼ãŒèµ·ãã
msgid "E1510: Value too large: %s"
msgstr "E1510: 値ãŒå¤§ãéŽãŽã¾ã™: %s"
+#, c-format
+msgid "E1511: Wrong number of characters for field \"%s\""
+msgstr "E1511: フィールド \"%s\" ã®æ–‡å­—æ•°ãŒé–“é•ã£ã¦ã„ã¾ã™"
+
+#, c-format
+msgid "E1512: Wrong character width for field \"%s\""
+msgstr "E1512: フィールド \"%s\" ã®æ–‡å­—å¹…ãŒé–“é•ã£ã¦ã„ã¾ã™"
+
+msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled"
+msgstr "E1513: ãƒãƒƒãƒ•ã‚¡ã‚’切り替ãˆã‚‰ã‚Œã¾ã›ã‚“。'winfixbuf' ãŒæœ‰åŠ¹åŒ–ã•ã‚Œã¦ã„ã¾ã™"
+
msgid "--No lines in buffer--"
msgstr "--ãƒãƒƒãƒ•ã‚¡ã«è¡ŒãŒã‚ã‚Šã¾ã›ã‚“--"
@@ -9096,7 +9163,7 @@ msgid "\" Hit <Enter> on an index line to jump there."
msgstr "\" インデックス行㧠<Enter> を打ã¤ã¨ã€ãã“ã«ã‚¸ãƒ£ãƒ³ãƒ—ã—ã¾ã™ã€‚"
msgid "\" Hit <Space> on a \"set\" line to refresh it."
-msgstr "\" \"set\" 行㧠<Spece> を打ã¤ã¨ã€æœ€æ–°ã®å€¤ãŒèª­è¾¼ã¾ã‚Œã¾ã™ã€‚"
+msgstr "\" \"set\" 行㧠<Space> を打ã¤ã¨ã€æœ€æ–°ã®å€¤ãŒèª­è¾¼ã¾ã‚Œã¾ã™ã€‚"
msgid "important"
msgstr "é‡è¦"
@@ -9415,6 +9482,9 @@ msgstr "ç¾åœ¨ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«ä½¿ã‚れる最å°è¡Œæ•°"
msgid "minimal number of lines used for any window"
msgstr "ä»»æ„ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«ä½¿ã‚れる最å°è¡Œæ•°"
+msgid "keep window focused on a single buffer"
+msgstr "ウィンドウãŒåˆ¥ã®ãƒãƒƒãƒ•ã‚¡ã«åˆ‡ã‚Šæ›¿ã‚らãªã„よã†ã«ã™ã‚‹"
+
msgid "keep the height of the window"
msgstr "ウィンドウã®é«˜ã•ã‚’ä¿ã¤"
@@ -9490,6 +9560,9 @@ msgstr "複数タブページ"
msgid "0, 1 or 2; when to use a tab pages line"
msgstr "0, 1 ã¾ãŸã¯ 2; タブページ行をã„ã¤ä½¿ã†ã‹"
+msgid "behaviour when closing tab pages: left, uselast or empty"
+msgstr "タブページを閉ã˜ã‚‹ã¨ãã®æŒ™å‹•: left, uselast ã¾ãŸã¯ empty"
+
msgid "maximum number of tab pages to open for -p and \"tab all\""
msgstr "-p 㨠\"tab all\" ã§é–‹ã‹ã‚Œã‚‹ã‚¿ãƒ–ページã®æœ€å¤§æ•°"
diff --git a/src/po/ja.sjis.po b/src/po/ja.sjis.po
index 589fd5a..7505121 100644
--- a/src/po/ja.sjis.po
+++ b/src/po/ja.sjis.po
@@ -3,7 +3,7 @@
# Do ":help uganda" in Vim to read copying and usage conditions.
# Do ":help credits" in Vim to see a list of people who contributed.
#
-# Copyright (C) 2001-2023 MURAOKA Taro <koron.kaoriya@gmail.com>,
+# Copyright (C) 2001-2024 MURAOKA Taro <koron.kaoriya@gmail.com>,
# vim-jp <http://vim-jp.org/>
#
# THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
@@ -12,10 +12,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Vim 9.0\n"
+"Project-Id-Version: Vim 9.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-12-18 16:41+0900\n"
-"PO-Revision-Date: 2023-12-19 12:45+0900\n"
+"POT-Creation-Date: 2024-07-23 10:59+0900\n"
+"PO-Revision-Date: 2024-08-15 12:54+0900\n"
"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
"Language-Team: Japanese <https://github.com/vim-jp/lang-ja>\n"
"Language: ja\n"
@@ -175,6 +175,9 @@ msgstr " (file %d of %d)"
msgid " (file (%d) of %d)"
msgstr " (file (%d) of %d)"
+msgid "[Command Line]"
+msgstr "[ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“]"
+
msgid "[Prompt]"
msgstr "[ƒvƒƒ“ƒvƒg]"
@@ -439,10 +442,6 @@ msgstr "•Ð‰¼–¼"
msgid "Bopomofo"
msgstr "’‰¹Žš•ê"
-msgid "Not enough memory to set references, garbage collection aborted!"
-msgstr ""
-"ƒK[ƒxƒbƒWƒRƒŒƒNƒVƒ‡ƒ“‚𒆎~‚µ‚Ü‚µ‚½! ŽQÆ‚ð쬂·‚é‚̂Ƀƒ‚ƒŠ‚ª•s‘«‚µ‚Ü‚µ‚½"
-
msgid ""
"\n"
"\tLast set from "
@@ -688,9 +687,6 @@ msgstr "ƒGƒ‰["
msgid "Interrupt"
msgstr "Š„ž‚Ý"
-msgid "[Command Line]"
-msgstr "[ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“]"
-
msgid "is a directory"
msgstr "‚̓fƒBƒŒƒNƒgƒŠ‚Å‚·"
@@ -854,6 +850,10 @@ msgid "+-%s%3ld line: "
msgid_plural "+-%s%3ld lines: "
msgstr[0] "+-%s%3ld s: "
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr ""
+"ƒK[ƒxƒbƒWƒRƒŒƒNƒVƒ‡ƒ“‚𒆎~‚µ‚Ü‚µ‚½! ŽQÆ‚ð쬂·‚é‚̂Ƀƒ‚ƒŠ‚ª•s‘«‚µ‚Ü‚µ‚½"
+
msgid "No match at cursor, finding next"
msgstr "ƒJ[ƒ\\ƒ‹‚̈ʒu‚Ƀ}ƒbƒ`‚Í‚ ‚è‚Ü‚¹‚ñAŽŸ‚ðŒŸõ‚µ‚Ä‚¢‚Ü‚·"
@@ -1337,8 +1337,8 @@ msgstr " ƒ†[ƒU[’è‹`•âŠ® (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " ƒIƒ€ƒj•âŠ® (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " ’Ô‚èC³Œó•â (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " ’Ô‚èC³Œó•â (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " ‹ÇŠƒL[ƒ[ƒh•âŠ® (^N^P)"
@@ -1416,6 +1416,9 @@ msgstr "mapnew() ‚̈ø”"
msgid "filter() argument"
msgstr "filter() ‚̈ø”"
+msgid "foreach() argument"
+msgstr "foreach() ‚̈ø”"
+
msgid "extendnew() argument"
msgstr "extendnew() ‚̈ø”"
@@ -2454,6 +2457,9 @@ msgstr "%s ‚Ö (%s ã‚Ì)"
msgid "Printing '%s'"
msgstr "ˆóü‚µ‚Ä‚¢‚Ü‚·: '%s'"
+#~ msgid "DefaultFontNameForWindows"
+#~ msgstr ""
+
#, c-format
msgid "Opening the X display took %ld msec"
msgstr "XƒT[ƒo[‚Ö‚ÌÚ‘±‚É %ld ƒ~ƒŠ•b‚©‚©‚è‚Ü‚µ‚½"
@@ -3394,8 +3400,8 @@ msgid "%s returning %s"
msgstr "%s ‚ª %s ‚ð•Ô‚µ‚Ü‚µ‚½"
#, c-format
-msgid "Function %s does not need compiling"
-msgstr "ŠÖ” %s ‚̓Rƒ“ƒpƒCƒ‹‚Ì•K—v‚ª‚ ‚è‚Ü‚¹‚ñ"
+msgid "Function %s%s%s does not need compiling"
+msgstr "ŠÖ” %s%s%s ‚̓Rƒ“ƒpƒCƒ‹‚Ì•K—v‚ª‚ ‚è‚Ü‚¹‚ñ"
#, c-format
msgid "%s (%s, compiled %s)"
@@ -3554,6 +3560,9 @@ msgstr " ‘æ2ƒ†[ƒU[ vimrc: \""
msgid " 3rd user vimrc file: \""
msgstr " ‘æ3ƒ†[ƒU[ vimrc: \""
+msgid " 4th user vimrc file: \""
+msgstr " ‘æ4ƒ†[ƒU[ vimrc: \""
+
msgid " user exrc file: \""
msgstr " ƒ†[ƒU[ exrc: \""
@@ -4158,6 +4167,10 @@ msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :source ‚ÅŽæž‚Þƒtƒ@ƒCƒ‹ˆÈŠO‚Å‚Í :loadkeymap ‚ðŽg‚¦‚Ü‚¹‚ñ"
#, c-format
+msgid "E106: Unsupported diff output format: %s"
+msgstr "E106: ƒTƒ|[ƒg‚µ‚Ä‚¢‚È‚¢diffo—̓tƒH[ƒ}ƒbƒg‚Å‚·: %s"
+
+#, c-format
msgid "E107: Missing parentheses: %s"
msgstr "E107: ƒJƒbƒR '(' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
@@ -4486,8 +4499,8 @@ msgstr "E196: ‚±‚̃o[ƒWƒ‡ƒ“‚ɇŽš‚Í‚ ‚è‚Ü‚¹‚ñ"
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: Œ¾Œê‚ð \"%s\" ‚ÉÝ’è‚Å‚«‚Ü‚¹‚ñ"
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: ƒAƒNƒeƒBƒu‚ȃEƒBƒ“ƒhƒE‚©ƒoƒbƒtƒ@‚ªíœ‚³‚ê‚Ü‚µ‚½"
+msgid "E199: Active window or buffer changed or deleted"
+msgstr "E199: ƒAƒNƒeƒBƒu‚ȃEƒBƒ“ƒhƒE‚©ƒoƒbƒtƒ@‚ª•ÏX‚Ü‚½‚Í휂³‚ê‚Ü‚µ‚½"
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: *ReadPre Ž©“®ƒRƒ}ƒ“ƒh ‚ªƒtƒ@ƒCƒ‹‚ð“Çž•s‰Â‚É‚µ‚Ü‚µ‚½"
@@ -5857,9 +5870,6 @@ msgstr "E612: sign‚Ì’è‹`‚ª‘½‰ß‚¬‚Ü‚·"
msgid "E613: Unknown printer font: %s"
msgstr "E613: –¢’m‚̃vƒŠƒ“ƒ^ƒIƒvƒVƒ‡ƒ“‚Å‚·: %s"
-msgid "E614: Class required"
-msgstr "E614: ƒNƒ‰ƒX‚ª•K—v‚Å‚·"
-
#, c-format
msgid "E616: Object required for argument %d"
msgstr "E616: ˆø” %d ‚ɂ̓IƒuƒWƒFƒNƒg‚ª•K—v‚Å‚·"
@@ -6696,7 +6706,7 @@ msgid "E862: Cannot use g: here"
msgstr "E862: ‚±‚±‚Å‚Í g: ‚ÍŽg‚¦‚Ü‚¹‚ñ"
msgid "E863: Not allowed for a terminal in a popup window"
-msgstr "E863: ’[––‚̓|ƒbƒvƒAƒbƒvƒEƒBƒ“ƒhƒE‚Å‚Í‹–‚³‚ê‚Ü‚¹‚ñ"
+msgstr "E863: ƒ|ƒbƒvƒAƒbƒvƒEƒBƒ“ƒhƒE“à‚Ì’[––‚Å‚Í‹–‚³‚ê‚Ü‚¹‚ñ"
#, no-c-format
msgid ""
@@ -6753,6 +6763,10 @@ msgstr ""
msgid "E876: (NFA regexp) Not enough space to store the whole NFA"
msgstr "E876: (NFA ³‹K•\\Œ») NFA‘S‘Ì‚ð•Û‘¶‚·‚é‚ɂ͋󂫃Xƒy[ƒX‚ª‘«‚è‚Ü‚¹‚ñ"
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %d"
+msgstr "E877: (NFA ³‹K•\\Œ») –³Œø‚È•¶ŽšƒNƒ‰ƒX‚Å‚·: %d"
+
msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!"
msgstr ""
"E878: (NFA ³‹K•\\Œ») Œ»Ý‰¡’f’†‚̃uƒ‰ƒ“ƒ`‚É\\•ª‚ȃƒ‚ƒŠ‚ðŠ„‚è“–‚Ä‚ç‚ê‚Ü‚¹‚ñ!"
@@ -8319,21 +8333,12 @@ msgstr "E1317: •s³‚ȃIƒuƒWƒFƒNƒg•Ï”‚Ì錾‚Å‚·: %s"
msgid "E1318: Not a valid command in a class: %s"
msgstr "E1318: ƒNƒ‰ƒX“à‚Å‚ÍŽg‚¦‚È‚¢ƒRƒ}ƒ“ƒh‚Å‚·: %s"
-msgid "E1319: Using a Class as a Number"
-msgstr "E1319: ƒNƒ‰ƒX‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
msgid "E1320: Using an Object as a Number"
msgstr "E1320: ƒIƒuƒWƒFƒNƒg‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-msgid "E1321: Using a Class as a Float"
-msgstr "E1321: ƒNƒ‰ƒX‚ð•‚“®¬”“_”‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
msgid "E1322: Using an Object as a Float"
msgstr "E1322: ƒIƒuƒWƒFƒNƒg‚ð•‚“®¬”“_”‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-msgid "E1323: Using a Class as a String"
-msgstr "E1323: ƒNƒ‰ƒX‚𕶎š—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
msgid "E1324: Using an Object as a String"
msgstr "E1324: ƒIƒuƒWƒFƒNƒg‚𕶎š—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
@@ -8362,14 +8367,14 @@ msgid "E1330: Invalid type for object variable: %s"
msgstr "E1330: ƒIƒuƒWƒFƒNƒg•Ï”‚Æ‚µ‚Ä–³Œø‚ÈŒ^‚Å‚·: %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\" ‚ª•K—v"
"‚Å‚·"
#, c-format
-msgid "E1332: Public variable name cannot start with underscore: %s"
+msgid "E1332: public variable name cannot start with underscore: %s"
msgstr "E1332: ƒpƒuƒŠƒbƒN•Ï”–¼‚̓Aƒ“ƒ_[ƒXƒRƒA‚ÅŽn‚߂邱‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ: %s"
#, c-format
@@ -8575,10 +8580,10 @@ msgstr ""
"E1386: ƒIƒuƒWƒFƒNƒgƒƒ\\ƒbƒh \"%s\" ‚̓Nƒ‰ƒX \"%s\" ‚̃IƒuƒWƒFƒNƒg‚ðŽg‚¤‚±‚Æ‚Ì"
"‚݂ŃAƒNƒZƒX‚Å‚«‚Ü‚·"
-msgid "E1387: Public variable not supported in an interface"
+msgid "E1387: public variable not supported in an interface"
msgstr "E1387: ƒCƒ“ƒ^[ƒtƒFƒCƒX“à‚ŃpƒuƒŠƒbƒN•Ï”‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-msgid "E1388: Public keyword not supported for a method"
+msgid "E1388: public keyword not supported for a method"
msgstr "E1388: ƒCƒ“ƒ^[ƒtƒFƒCƒX“à‚Å public ƒL[ƒ[ƒh‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
msgid "E1389: Missing name after implements"
@@ -8608,10 +8613,6 @@ msgid "E1394: Type name must start with an uppercase letter: %s"
msgstr "E1394: Œ^‚Ì–¼‘O‚͉p‘啶Žš‚ÅŽn‚Ü‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ: %s"
#, c-format
-msgid "E1395: Type alias \"%s\" cannot be modified"
-msgstr "E1395: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ"
-
-#, c-format
msgid "E1396: Type alias \"%s\" already exists"
msgstr "E1396: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚ÍŠù‚É‘¶Ý‚µ‚Ü‚·"
@@ -8625,18 +8626,6 @@ msgid "E1399: Type can only be used in a script"
msgstr "E1399: Œ^‚̓XƒNƒŠƒvƒg‚Ì’†‚Å‚Ì‚ÝŽg—p‚Å‚«‚Ü‚·"
#, c-format
-msgid "E1400: Using type alias \"%s\" as a Number"
-msgstr "E1400: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-#, c-format
-msgid "E1401: Using type alias \"%s\" as a Float"
-msgstr "E1401: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚ð•‚“®¬”“_”‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-#, c-format
-msgid "E1402: Using type alias \"%s\" as a String"
-msgstr "E1402: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚𕶎š—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-#, c-format
msgid "E1403: Type alias \"%s\" cannot be used as a value"
msgstr "E1403: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚ð’l‚Æ‚µ‚ÄŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ"
@@ -8647,9 +8636,6 @@ msgstr "E1404: abstract ‚ðƒCƒ“ƒ^[ƒtƒFƒCƒX“à‚ÅŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ"
msgid "E1405: Class \"%s\" cannot be used as a value"
msgstr "E1405: ƒNƒ‰ƒX \"%s\" ‚ð’l‚Æ‚µ‚ÄŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ"
-msgid "E1406: Cannot use a Class as a variable or value"
-msgstr "E1406: ƒNƒ‰ƒX‚ð•Ï”‚â’l‚Æ‚µ‚ÄŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ"
-
msgid "E1407: Cannot use a Typealias as a variable or value"
msgstr "E1407: Œ^ƒGƒCƒŠƒAƒX‚ð•Ï”‚â’l‚Æ‚µ‚ÄŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ"
@@ -8665,6 +8651,76 @@ msgid "E1410: Const variable not supported in an interface"
msgstr "E1410: ƒCƒ“ƒ^[ƒtƒFƒCƒX“à‚Å const •Ï”‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
#, c-format
+msgid "E1411: Missing dot after object \"%s\""
+msgstr "E1411: ƒIƒuƒWƒFƒNƒg \"%s\" ‚ÌŒã‚Ƀhƒbƒg‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E1412: Builtin object method \"%s\" not supported"
+msgstr "E1412: ‘g‚Ýž‚݃IƒuƒWƒFƒNƒgƒƒ\\ƒbƒh \"%s\" ‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E1413: Builtin class method not supported"
+msgstr "E1413: ‘g‚Ýž‚݃Nƒ‰ƒXƒƒ\\ƒbƒh‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E1414: Enum can only be defined in Vim9 script"
+msgstr "E1414: —ñ‹“Œ^‚Í Vim9 script ‚Ì’†‚Å‚Ì‚Ý’è‹`‚Å‚«‚Ü‚·"
+
+#, c-format
+msgid "E1415: Enum name must start with an uppercase letter: %s"
+msgstr "E1415: —ñ‹“Œ^‚Ì–¼‘O‚͉p‘啶Žš‚ÅŽn‚Ü‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ: %s"
+
+msgid "E1416: Enum cannot extend a class or enum"
+msgstr "E1416: —ñ‹“Œ^‚̓Nƒ‰ƒX‚â—ñ‹“Œ^‚ðŠg’£‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E1417: Abstract cannot be used in an Enum"
+msgstr "E1417: abstract ‚ð—ñ‹“Œ^“à‚ÅŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E1418: Invalid enum value declaration: %s"
+msgstr "E1418: •s³‚È—ñ‹“’l‚Ì錾‚Å‚·: %s"
+
+#, c-format
+msgid "E1419: Not a valid command in an Enum: %s"
+msgstr "E1419: —ñ‹“Œ^“à‚Å‚ÍŽg‚¦‚È‚¢ƒRƒ}ƒ“ƒh‚Å‚·: %s"
+
+msgid "E1420: Missing :endenum"
+msgstr "E1420: :endenum ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E1421: Enum \"%s\" cannot be used as a value"
+msgstr "E1421: —ñ‹“Œ^ \"%s\" ‚ð’l‚Æ‚µ‚ÄŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E1422: Enum value \"%s\" not found in enum \"%s\""
+msgstr "E1422: —ñ‹“’l \"%s\" ‚ª—ñ‹“Œ^ \"%s\" “à‚ÅŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E1423: Enum value \"%s.%s\" cannot be modified"
+msgstr "E1423: —ñ‹“’l \"%s.%s\" ‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E1424: Using an Enum \"%s\" as a Number"
+msgstr "E1424: —ñ‹“Œ^ \"%s\" ‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
+
+#, 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\" ‚̇˜’l‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E1427: Enum \"%s\" name cannot be modified"
+msgstr "E1427: —ñ‹“Œ^ \"%s\" ‚Ì–¼‘O‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E1428: Duplicate enum value: %s"
+msgstr "E1428: —ñ‹“’l‚ªd•¡‚µ‚Ä‚¢‚Ü‚·: %s"
+
+msgid "E1429: Class can only be used in a script"
+msgstr "E1429: ƒNƒ‰ƒX‚̓XƒNƒŠƒvƒg‚Ì’†‚Å‚Ì‚ÝŽg—p‚Å‚«‚Ü‚·"
+
+#, c-format
msgid "E1500: Cannot mix positional and non-positional arguments: %s"
msgstr "E1500: ˆÊ’uˆø”‚Æ”ñˆÊ’uˆø”‚𬂺‚邱‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ: %s"
@@ -8708,6 +8764,17 @@ msgstr "E1509: Šg’£‘®«‚Ì“Çž‚Ý‚Ü‚½‚Í‘ž‚݂ŃGƒ‰[‚ª‹N‚«‚Ü‚µ‚½"
msgid "E1510: Value too large: %s"
msgstr "E1510: ’l‚ª‘å‚«‰ß‚¬‚Ü‚·: %s"
+#, c-format
+msgid "E1511: Wrong number of characters for field \"%s\""
+msgstr "E1511: ƒtƒB[ƒ‹ƒh \"%s\" ‚Ì•¶Žš”‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "E1512: Wrong character width for field \"%s\""
+msgstr "E1512: ƒtƒB[ƒ‹ƒh \"%s\" ‚Ì•¶Žš•‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
+
+msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled"
+msgstr "E1513: ƒoƒbƒtƒ@‚ðØ‚è‘Ö‚¦‚ç‚ê‚Ü‚¹‚ñB'winfixbuf' ‚ª—LŒø‰»‚³‚ê‚Ä‚¢‚Ü‚·"
+
msgid "--No lines in buffer--"
msgstr "--ƒoƒbƒtƒ@‚És‚ª‚ ‚è‚Ü‚¹‚ñ--"
@@ -9096,7 +9163,7 @@ msgid "\" Hit <Enter> on an index line to jump there."
msgstr "\" ƒCƒ“ƒfƒbƒNƒXs‚Å <Enter> ‚ð‘ł‚ÆA‚»‚±‚ɃWƒƒƒ“ƒv‚µ‚Ü‚·B"
msgid "\" Hit <Space> on a \"set\" line to refresh it."
-msgstr "\" \"set\" s‚Å <Spece> ‚ð‘ł‚ÆAÅV‚Ì’l‚ª“Çž‚Ü‚ê‚Ü‚·B"
+msgstr "\" \"set\" s‚Å <Space> ‚ð‘ł‚ÆAÅV‚Ì’l‚ª“Çž‚Ü‚ê‚Ü‚·B"
msgid "important"
msgstr "d—v"
@@ -9415,6 +9482,9 @@ msgstr "Œ»Ý‚̃EƒBƒ“ƒhƒE‚ÉŽg‚í‚ê‚éŬs”"
msgid "minimal number of lines used for any window"
msgstr "”CˆÓ‚̃EƒBƒ“ƒhƒE‚ÉŽg‚í‚ê‚éŬs”"
+msgid "keep window focused on a single buffer"
+msgstr "ƒEƒBƒ“ƒhƒE‚ª•Ê‚̃oƒbƒtƒ@‚ÉØ‚è‘Ö‚í‚ç‚È‚¢‚悤‚É‚·‚é"
+
msgid "keep the height of the window"
msgstr "ƒEƒBƒ“ƒhƒE‚Ì‚‚³‚ð•Û‚Â"
@@ -9490,6 +9560,9 @@ msgstr "•¡”ƒ^ƒuƒy[ƒW"
msgid "0, 1 or 2; when to use a tab pages line"
msgstr "0, 1 ‚Ü‚½‚Í 2; ƒ^ƒuƒy[ƒWs‚ð‚¢‚ÂŽg‚¤‚©"
+msgid "behaviour when closing tab pages: left, uselast or empty"
+msgstr "ƒ^ƒuƒy[ƒW‚ð•Â‚¶‚é‚Æ‚«‚Ì‹““®: left, uselast ‚Ü‚½‚Í empty"
+
msgid "maximum number of tab pages to open for -p and \"tab all\""
msgstr "-p ‚Æ \"tab all\" ‚ÅŠJ‚©‚ê‚éƒ^ƒuƒy[ƒW‚ÌÅ‘å”"
diff --git a/src/po/ko.UTF-8.po b/src/po/ko.UTF-8.po
index a9ee0ca..f7714ae 100644
--- a/src/po/ko.UTF-8.po
+++ b/src/po/ko.UTF-8.po
@@ -411,8 +411,8 @@ msgstr " ì‚¬ìš©ìž ì •ì˜ ì™„ì„± (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni 완성 (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " 단어 제안 (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " 단어 제안 (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " ë‚±ë§ ë¡œì»¬ 완성 (^N^P)"
diff --git a/src/po/ko.po b/src/po/ko.po
index 00fb486..2b3c785 100644
--- a/src/po/ko.po
+++ b/src/po/ko.po
@@ -1,8 +1,8 @@
-# Generated from ko.UTF-8.po, DO NOT EDIT
+# Korean translation for Vim
#
# FIRST AUTHOR SungHyun Nam <goweol@gmail.com>, 2000-2018
#
-# Original translations.
+# Generated from ko.UTF-8.po, DO NOT EDIT.
#
msgid ""
msgstr ""
@@ -14,7 +14,7 @@ msgstr ""
"Language-Team: Korean\n"
"Language: ko\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=euc-kr\n"
+"Content-Type: text/plain; charset=EUC-KR\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -411,8 +411,8 @@ msgstr " »ç¿ëÀÚ Á¤ÀÇ ¿Ï¼º (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni ¿Ï¼º (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " ´Ü¾î Á¦¾È (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " ´Ü¾î Á¦¾È (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " ³¹¸» ·ÎÄà ¿Ï¼º (^N^P)"
diff --git a/src/po/nb.po b/src/po/nb.po
index d9f527b..957b99d 100644
--- a/src/po/nb.po
+++ b/src/po/nb.po
@@ -283,9 +283,8 @@ msgstr " Brukerdefinert fullføring (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni-fullføring (^O^N^P)"
-#, fuzzy
-#~ msgid " Spelling suggestion (s^N^P)"
-#~ msgstr " Staveforslag (^S^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Staveforslag (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Lokal nøkkelordfullføring (^N^P)"
diff --git a/src/po/nl.po b/src/po/nl.po
index 09f281b..6ac59ca 100644
--- a/src/po/nl.po
+++ b/src/po/nl.po
@@ -287,8 +287,8 @@ msgstr " gebruikergedefinieerde voltooiing (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " omni-voltooiing (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " spellingsuggestie (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " spellingsuggestie (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " lokaal-trefwoordvoltooiing (^N^P)"
diff --git a/src/po/no.po b/src/po/no.po
index d9f527b..957b99d 100644
--- a/src/po/no.po
+++ b/src/po/no.po
@@ -283,9 +283,8 @@ msgstr " Brukerdefinert fullføring (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni-fullføring (^O^N^P)"
-#, fuzzy
-#~ msgid " Spelling suggestion (s^N^P)"
-#~ msgstr " Staveforslag (^S^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Staveforslag (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Lokal nøkkelordfullføring (^N^P)"
diff --git a/src/po/pl.UTF-8.po b/src/po/pl.UTF-8.po
index c9036a3..39064f6 100644
--- a/src/po/pl.UTF-8.po
+++ b/src/po/pl.UTF-8.po
@@ -298,8 +298,8 @@ msgstr "Dopełnianie zdefiniowane przez użytkownika (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni uzupełnianie (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr "Propozycja pisowni (^L^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr "Propozycja pisowni (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Lokalne dopełnianie słów kluczowych (^N^P)"
diff --git a/src/po/pl.cp1250.po b/src/po/pl.cp1250.po
index 9280d2f..6f9b66d 100644
--- a/src/po/pl.cp1250.po
+++ b/src/po/pl.cp1250.po
@@ -17,7 +17,7 @@ msgstr ""
"Language-Team: Polish\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=cp1250\n"
+"Content-Type: text/plain; charset=CP1250\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 1.0\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
@@ -298,8 +298,8 @@ msgstr "Dope³nianie zdefiniowane przez u¿ytkownika (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni uzupe³nianie (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr "Propozycja pisowni (^L^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr "Propozycja pisowni (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Lokalne dope³nianie s³ów kluczowych (^N^P)"
diff --git a/src/po/pl.po b/src/po/pl.po
index f10897d..aebc33f 100644
--- a/src/po/pl.po
+++ b/src/po/pl.po
@@ -298,8 +298,8 @@ msgstr "Dope³nianie zdefiniowane przez u¿ytkownika (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni uzupe³nianie (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr "Propozycja pisowni (^L^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr "Propozycja pisowni (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Lokalne dope³nianie s³ów kluczowych (^N^P)"
diff --git a/src/po/pt_BR.po b/src/po/pt_BR.po
index 3a8844a..1cf15b5 100644
--- a/src/po/pt_BR.po
+++ b/src/po/pt_BR.po
@@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: Vim 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-10 11:11-0300\n"
-"PO-Revision-Date: 2017-09-10 11:12-0300\n"
+"PO-Revision-Date: 2024-08-23 18:04+0200\n"
"Last-Translator: Eduardo S. Dobay <edudobay@gmail.com>\n"
"Language-Team: Brazilian Portuguese\n"
"Language: pt_BR\n"
@@ -226,20 +226,20 @@ msgstr "E898: socket() em channel_open()"
# TODO: Capitalise first word of message?
msgid "E903: Received command with non-string argument"
-msgstr "E903: comando recebido com argumento não-string"
+msgstr "E903: Comando recebido com argumento não-string"
# TODO: Capitalise first word of message?
msgid "E904: Last argument for expr/call must be a number"
-msgstr "E904: último argumento para expr/call deve ser numérico"
+msgstr "E904: Último argumento para expr/call deve ser numérico"
# TODO: Capitalise first word of message?
msgid "E904: Third argument for call must be a list"
-msgstr "E904: terceiro argumento para call deve ser uma lista"
+msgstr "E904: Terceiro argumento para call deve ser uma lista"
#, c-format
# TODO: Capitalise first word of message?
msgid "E905: Received unknown command: %s"
-msgstr "E905: comando desconhecido recebido: %s"
+msgstr "E905: Comando desconhecido recebido: %s"
#, c-format
# TODO: Capitalise first word of message?
@@ -273,7 +273,7 @@ msgstr "E915: buffer in_io requer definição de in_buf ou in_name"
#, c-format
# TODO: Capitalise first word of message?
msgid "E918: Buffer must be loaded: %s"
-msgstr "E918: buffer precisa ser carregado: %s"
+msgstr "E918: Buffer precisa ser carregado: %s"
msgid "E821: File is encrypted with unknown method"
msgstr "E821: Arquivo criptografado com método desconhecido"
@@ -406,8 +406,8 @@ msgstr " Completar definido pelo usuário (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Completação inteligente (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Sugestão de ortografia (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Sugestão de ortografia (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Completar palavra-chave local (^N^P)"
@@ -536,7 +536,7 @@ msgstr "E940: Impossível travar ou destravar variável %s"
# TODO: Capitalise first word of message?
msgid "E743: Variable nested too deep for (un)lock"
-msgstr "E743: variável aninhada demais para (des)bloquear"
+msgstr "E743: Variável aninhada demais para (des)bloquear"
msgid "E109: Missing ':' after '?'"
msgstr "E109: ':' faltando depois de '?'"
@@ -590,7 +590,7 @@ msgstr ""
# TODO: Capitalise first word of message?
msgid "E724: Variable nested too deep for displaying"
-msgstr "E724: variável aninhada demais para ser exibida"
+msgstr "E724: Variável aninhada demais para ser exibida"
msgid "E805: Using a Float as a Number"
msgstr "E805: Float usado como Número"
@@ -669,7 +669,7 @@ msgstr "E742: Não é possível mudar valor de %s"
# TODO: Capitalise first word of message?
msgid "E698: Variable nested too deep for making a copy"
-msgstr "E698: variável aninhada demais para fazer uma cópia"
+msgstr "E698: Variável aninhada demais para fazer uma cópia"
msgid ""
"\n"
@@ -739,7 +739,7 @@ msgstr "E786: Intervalos não são permitidos"
# TODO: Capitalise first word of message?
msgid "E916: Not a valid job"
-msgstr "E916: não é um trabalho válido"
+msgstr "E916: Não é um trabalho válido"
msgid "E701: Invalid type for len()"
msgstr "E701: Tipo inválido para len()"
@@ -808,7 +808,7 @@ msgstr "(Inválido)"
#, c-format
# TODO: Capitalise first word of message?
msgid "E935: Invalid submatch number: %d"
-msgstr "E935: número inválido para subpadrão: %d"
+msgstr "E935: Número inválido para subpadrão: %d"
msgid "E677: Error writing temp file"
msgstr "E677: Erro ao gravar o arquivo temporário"
@@ -1107,7 +1107,7 @@ msgstr "E157: ID de sinal inválido: %ld"
#, c-format
msgid "E885: Not possible to change sign %s"
-msgstr "E885: Não é possível mudar o sinal %s"
+msgstr "E885: Não é possível alterar o sinal %s"
msgid " (NOT FOUND)"
msgstr " (NÃO ENCONTRADO)"
@@ -1184,7 +1184,7 @@ msgstr "E165: Impossível ir além do último arquivo"
#, c-format
# TODO: Capitalise first word of message?
msgid "E666: Compiler not supported: %s"
-msgstr "E666: compilador não suportado: %s"
+msgstr "E666: Compilador não suportado: %s"
#, c-format
msgid "Searching for \"%s\" in \"%s\""
@@ -1409,6 +1409,9 @@ msgstr "E784: Não é possível fechar a última aba"
msgid "Already only one tab page"
msgstr "Já há apenas uma aba"
+msgid "Edit File in new tab page"
+msgstr "Editar arquivo na nova aba"
+
msgid "Edit File in new window"
msgstr "Editar arquivo em nova janela"
@@ -1653,7 +1656,7 @@ msgstr ""
"# Histórico de %s (mais recente primeiro):\n"
msgid "Command Line"
-msgstr "linha de comando"
+msgstr "Linha de comando"
msgid "Search String"
msgstr "expressões de busca"
@@ -1725,7 +1728,7 @@ msgid "[socket]"
msgstr "[socket]"
msgid "[character special]"
-msgstr "[dispositivo de caractere]"
+msgstr "[caractere especial]"
msgid "[CR missing]"
msgstr "[CR faltando]"
@@ -1838,7 +1841,7 @@ msgstr " ERRO DE CONVERSÃO"
#, c-format
msgid " in line %ld;"
-msgstr "na linha %ld;"
+msgstr " na linha %ld;"
msgid "[Device]"
msgstr "[Dispositivo]"
diff --git a/src/po/ru.cp1251.po b/src/po/ru.cp1251.po
index 05d10e0..d598cbf 100644
--- a/src/po/ru.cp1251.po
+++ b/src/po/ru.cp1251.po
@@ -475,8 +475,7 @@ msgstr ""
# :!~ Restorer
#, c-format
msgid "xchacha20v2: using custom algorithm \"%d\" for Key derivation."
-msgstr ""
-"XChaCha20v2: äëÿ ïîëó÷åíèÿ êëþ÷à ïðèìåí¸í íåñòàíäàðòíûé àëãîðèòì \"%d\""
+msgstr "XChaCha20v2: äëÿ ïîëó÷åíèÿ êëþ÷à ïðèìåí¸í íåñòàíäàðòíûé àëãîðèòì \"%d\""
# #Restorer: âûâîäèòñÿ ïðè çíà÷åíèè 'verbose'>0
# :!~ Restorer
@@ -722,8 +721,7 @@ msgstr ""
# :!~ Restorer
msgid "called inputrestore() more often than inputsave()"
msgstr ""
-"Êîëè÷åñòâî âûçîâîâ ôóíêöèè inputrestore() ïðåâûøàåò âûçîâû ôóíêöèè "
-"inputsave()"
+"Êîëè÷åñòâî âûçîâîâ ôóíêöèè inputrestore() ïðåâûøàåò âûçîâû ôóíêöèè inputsave()"
# #Restorer: íàïðèìåð, êîìàíäà `:ascii` è `ga`
# #Restorer: åñëè ïîäêëþ÷åí êîìïîíåíò +digraphs è äëÿ ñèìâîëà åñòü äèãðàô
@@ -1243,8 +1241,7 @@ msgstr "[íåò ñèìâîëà çàâåðøåíèÿ ñòðîêè]"
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
"well"
-msgstr ""
-"W12: Âíèìàíèå! Íå ñâÿçàííûå èçìåíåíèÿ ñîäåðæèìîãî áóôåðà è ôàéëà \"%s\""
+msgstr "W12: Âíèìàíèå! Íå ñâÿçàííûå èçìåíåíèÿ ñîäåðæèìîãî áóôåðà è ôàéëà \"%s\""
# :!~ Restorer
msgid "See \":help W12\" for more info."
@@ -1264,8 +1261,7 @@ msgstr "×òîáû ïîëó÷èòü äîïîëíèòåëüíóþ èíôîðìàöèþ, íàáåðèòå `:help W11`"
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr ""
-"W16: Âíèìàíèå! Ïîñëå ñ÷èòûâàíèÿ â áóôåð, èçìåíåíû ïðàâà äîñòóïà ê ôàéëó "
-"\"%s\""
+"W16: Âíèìàíèå! Ïîñëå ñ÷èòûâàíèÿ â áóôåð, èçìåíåíû ïðàâà äîñòóïà ê ôàéëó \"%s\""
# :!~ Restorer
msgid "See \":help W16\" for more info."
@@ -1958,12 +1954,10 @@ msgstr "âûïîëíåíèå ïðåðâàíî ïîëüçîâàòåëåì"
# :!~ Restorer
msgid "cannot create buffer/window command: object is being deleted"
msgstr ""
-"îáúåêò áóôåðà èëè îêíà â ïðîöåññå óäàëåíèÿ. Íå óäàëîñü ñîçäàòü äëÿ íèõ "
-"êîìàíäó"
+"îáúåêò áóôåðà èëè îêíà â ïðîöåññå óäàëåíèÿ. Íå óäàëîñü ñîçäàòü äëÿ íèõ êîìàíäó"
# :!~ Restorer
-msgid ""
-"cannot register callback command: buffer/window is already being deleted"
+msgid "cannot register callback command: buffer/window is already being deleted"
msgstr ""
"îáúåêò áóôåðà èëè îêíà â ïðîöåññå óäàëåíèÿ. Íå óäàëîñü çàðåãèñòðèðîâàòü "
"êîìàíäó"
@@ -2045,7 +2039,7 @@ msgid " Omni completion (^O^N^P)"
msgstr " Ïîäñòàíîâêà ïî êîíòåêñòó CTRL+O è CTRL+N èëè CTRL+P"
# :!~ Restorer
-msgid " Spelling suggestion (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
msgstr " Ïîäñòàíîâêà âàðèàíòîâ íàïèñàíèÿ CTRL+S è CTRL+N èëè CTRL+P"
# :!~ Restorer
@@ -2248,8 +2242,7 @@ msgstr ""
# :!~ Restorer
msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
-msgstr ""
-"Ïðîãðàììà Vim. Äàííàÿ âåðñèÿ ïðîãðàììû íå ðàáîòàåò â òåðìèíàëå Cygwin\n"
+msgstr "Ïðîãðàììà Vim. Äàííàÿ âåðñèÿ ïðîãðàììû íå ðàáîòàåò â òåðìèíàëå Cygwin\n"
# :!~ Restorer
msgid "Vim: Warning: Output is not to a terminal\n"
@@ -2481,8 +2474,7 @@ msgstr "--not-a-term\t\tÍå ñîîáùàòü îá îòñóòñòâèè òåðìèíàëà äëÿ ââîäà-âûâîäà"
# :!~ Restorer
msgid "--gui-dialog-file {fname} For testing: write dialog text"
-msgstr ""
-"--gui-dialog-file {ôàéë} Çàïèñü ñîîáùåíèé äèàëîãîâûõ îêîí. Äëÿ îòëàäêè"
+msgstr "--gui-dialog-file {ôàéë} Çàïèñü ñîîáùåíèé äèàëîãîâûõ îêîí. Äëÿ îòëàäêè"
# :!~ Restorer
msgid "--ttyfail\t\tExit if input or output is not a terminal"
@@ -2564,13 +2556,11 @@ msgstr "-X\t\t\tÇàïóñê ïðîãðàììû áåç ïîäêëþ÷åíèÿ ê X-ñåðâåðó"
# :!~ Restorer
msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-msgstr ""
-"--remote <ôàéëû>\tÐåäàêòèðîâàíèå <ôàéëîâ> íà Vim-ñåðâåðå, åñëè äîñòóïåí"
+msgstr "--remote <ôàéëû>\tÐåäàêòèðîâàíèå <ôàéëîâ> íà Vim-ñåðâåðå, åñëè äîñòóïåí"
# :!~ Restorer
msgid "--remote-silent <files> Same, don't complain if there is no server"
-msgstr ""
-"--remote-silent <ôàéëû> Òî æå, íî íå ñîîáùàòü î íåäîñòóïíîñòè ñåðâåðà"
+msgstr "--remote-silent <ôàéëû> Òî æå, íî íå ñîîáùàòü î íåäîñòóïíîñòè ñåðâåðà"
# #Restorer: äîáàâèë ïàðó ïðîáåëüíûõ ñèìâîëîâ, äàáû ïîäðàâíÿòü ñîîáùåíèå
# ~!: earlier
@@ -2580,8 +2570,7 @@ msgstr ""
"--remote-wait <ôàéëû> Òî æå, ÷òî è --remote, íî ñ îæèäàíèåì çàâåðøåíèÿ"
# :!~ Restorer
-msgid ""
-"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgid "--remote-wait-silent <files> Same, don't complain if there is no server"
msgstr ""
"--remote-wait-silent <ôàéëû> Òî æå, íî íå ñîîáùàòü î íåäîñòóïíîñòè ñåðâåðà"
@@ -2614,8 +2603,7 @@ msgstr "--startuptime <ôàéë>\tÇàïèñàòü õðîíîìåòðàæ çàïóñêà ïðîãðàììû â <ôàéë>"
# :!~ Restorer
msgid "--log <file>\t\tStart logging to <file> early"
-msgstr ""
-"--log <ôàéë>\t\tÇàïèñü ïðîòîêîëà ðàáîòû ñ ýòàïà èíèöèàëèçàöèè ïðîãðàììû"
+msgstr "--log <ôàéë>\t\tÇàïèñü ïðîòîêîëà ðàáîòû ñ ýòàïà èíèöèàëèçàöèè ïðîãðàììû"
# :!~ Restorer
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
@@ -2715,8 +2703,7 @@ msgstr ""
# :!~ Restorer
msgid "--role <role>\tSet a unique role to identify the main window"
-msgstr ""
-"--role <ðîëü>\tÇàäàòü óíèêàëüíóþ <ðîëü> ãëàâíîãî îêíà äëÿ èäåíòèôèêàöèè"
+msgstr "--role <ðîëü>\tÇàäàòü óíèêàëüíóþ <ðîëü> ãëàâíîãî îêíà äëÿ èäåíòèôèêàöèè"
# :!~ Restorer
msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
@@ -2841,8 +2828,7 @@ msgstr "Äëÿ âîññòàíîâëåíèÿ ýòîãî ôàéëà, èñïîëüçóéòå ïðîãðàììó Vim âåðñèè 3.0\n"
# :!~ Restorer
msgid " cannot be used on this computer.\n"
-msgstr ""
-" íåñîâìåñòèì ñ ïðîãðàììíî-àïïàðàòíîé àðõèòåêòóðîé äàííîãî êîìïüþòåðà.\n"
+msgstr " íåñîâìåñòèì ñ ïðîãðàììíî-àïïàðàòíîé àðõèòåêòóðîé äàííîãî êîìïüþòåðà.\n"
# ~!: earlier
msgid "The file was created on "
@@ -3098,8 +3084,7 @@ msgid ""
" [not usable on this computer]"
msgstr ""
"\n"
-" [íåñîâìåñòèì ñ ïðîãðàììíî-àïïàðàòíîé àðõèòåêòóðîé äàííîãî "
-"êîìïüþòåðà]"
+" [íåñîâìåñòèì ñ ïðîãðàììíî-àïïàðàòíîé àðõèòåêòóðîé äàííîãî êîìïüþòåðà]"
# :!~ Restorer
msgid " [cannot be read]"
@@ -3169,8 +3154,7 @@ msgstr ""
"(1) Âîçìîæíî, ðåäàêòèðîâàíèå ýòîãî æå ôàéëà âûïîëíÿåòñÿ â äðóãîé ïðîãðàììå\n"
" íà ýòîì æå êîìïüþòåðå èëè ïî ñåòåâîìó ïîäêëþ÷åíèþ.\n"
"\n"
-" ýòîì ñëó÷àå ëó÷øå íå ðåäàêòèðîâàòü ýòîò ôàéë èëè äåëàòü ýòî "
-"îñìîòðèòåëüíî,\n"
+" ýòîì ñëó÷àå ëó÷øå íå ðåäàêòèðîâàòü ýòîò ôàéë èëè äåëàòü ýòî îñìîòðèòåëüíî,\n"
"÷òîáû íå ïîÿâèëîñü äâà âàðèàíòà îäíîãî è òîãî æå ôàéëà.\n"
"Áóäüòå âíèìàòåëüíû è åù¸ ðàç âñ¸ ïðîâåðüòå.\n"
"\n"
@@ -3495,8 +3479,8 @@ msgid ""
"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
"%lld of %lld"
msgstr ""
-"Êîëîíêà %s èç %s; ñòðîêà %ld èç %ld; ñëîâî %lld èç %lld; ëèòåðà %lld èç "
-"%lld; áàéò %lld èç %lld"
+"Êîëîíêà %s èç %s; ñòðîêà %ld èç %ld; ñëîâî %lld èç %lld; ëèòåðà %lld èç %lld; "
+"áàéò %lld èç %lld"
# #Restorer: äîáàâëÿåòñÿ ê ñîîáùåíèþ î ïîçèöèè êàðåòêè èç ïðåäûäóùèõ msgid
# #Restorer: âñòàâèë ïðîáåë ïåðåä ñêîáêîé, ïîñìîòðèì, êàê áóäåò âûãëÿäåòü
@@ -3509,8 +3493,7 @@ msgstr " (+%lld ñ ó÷¸òîì ÌÏÁ)"
# :!~ Restorer
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr ""
-"W17: Äëÿ ðàáîòû ñ àðàáñêîé ïèñüìåííîñòüþ ââåäèòå êîìàíäó `:set "
-"encoding=utf-8`"
+"W17: Äëÿ ðàáîòû ñ àðàáñêîé ïèñüìåííîñòüþ ââåäèòå êîìàíäó `:set encoding=utf-8`"
# #Restorer: âûâîäèòñÿ ïî êîìàíäå `:set termcap`
# :!~ Restorer
@@ -3559,8 +3542,7 @@ msgstr "Ïðîãðàììà VIM. Íå óäàëîñü îòîáðàçèòü îêíî íà ýêðàíå!\n"
# :!~ Restorer
msgid "Need Amigados version 2.04 or later\n"
-msgstr ""
-"Òðåáóåòñÿ îïåðàöèîííàÿ ñèñòåìà Amigados âåðñèè 2.04 èëè áîëåå ïîçäíåé\n"
+msgstr "Òðåáóåòñÿ îïåðàöèîííàÿ ñèñòåìà Amigados âåðñèè 2.04 èëè áîëåå ïîçäíåé\n"
# :!~ Restorer
#, c-format
@@ -3858,8 +3840,7 @@ msgstr "Íå óäàëîñü îòêðûòü ôàéë \"%s\""
# :!~ Restorer
msgid "cannot have both a list and a \"what\" argument"
msgstr ""
-"â ôóíêöèè setqflist(). Äîëæåí áûòü óêàçàí ëèáî ïåðâûé, ëèáî ïîñëåäíèé "
-"àðãóìåíò"
+"â ôóíêöèè setqflist(). Äîëæåí áûòü óêàçàí ëèáî ïåðâûé, ëèáî ïîñëåäíèé àðãóìåíò"
# #Restorer: âûâîäèòñÿ ïðè 'verbose'>0
# :!~ Restorer
@@ -4308,8 +4289,7 @@ msgstr " ôàéëå %s íà ñòðîêå %d íåäîïóñòèìîå çíà÷åíèå ïðàâèëà COMPOUNDMIN %s"
# :!~ Restorer
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr ""
-" ôàéëå %s íà ñòðîêå %d íåäîïóñòèìîå çíà÷åíèå ïðàâèëà COMPOUNDSYLMAX %s"
+msgstr " ôàéëå %s íà ñòðîêå %d íåäîïóñòèìîå çíà÷åíèå ïðàâèëà COMPOUNDSYLMAX %s"
# :!~ Restorer
#, c-format
@@ -4321,8 +4301,7 @@ msgstr ""
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
-"Â ôàéëå %s íà ñòðîêå %d íåäîïóñòèìûé ïðèçíàê êîìáèíèðîâàíèÿ áëîêîâ àôôèêñîâ "
-"%s"
+"Â ôàéëå %s íà ñòðîêå %d íåäîïóñòèìûé ïðèçíàê êîìáèíèðîâàíèÿ áëîêîâ àôôèêñîâ %s"
# :!~ Restorer
#, c-format
@@ -4351,8 +4330,7 @@ msgstr "Â ôàéëå %s íà ñòðîêå %d íåäîïóñòèìîå äëÿ âûïîëíåíèÿ ïîèñêà óñëîâèå %s"
# :!~ Restorer
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
-msgstr ""
-" ôàéëå %s íà ñòðîêå %d äëÿ ïðàâèë REP èëè REPSAL íå óêàçàíî êîëè÷åñòâî"
+msgstr " ôàéëå %s íà ñòðîêå %d äëÿ ïðàâèë REP èëè REPSAL íå óêàçàíî êîëè÷åñòâî"
# :!~ Restorer
#, c-format
@@ -4539,8 +4517,7 @@ msgstr "Îöåíêà èñïîëüçîâàíèÿ ïàìÿòè ïðè âûïîëíåíèè: %d áàéò"
# :!~ Restorer
msgid "Warning: both compounding and NOBREAK specified"
-msgstr ""
-"Âíèìàíèå! Óêàçàíû êàê ïðàâèëà äëÿ ñîñòàâíûõ ñëîâ, òàê è ïðàâèëî NOBREAK"
+msgstr "Âíèìàíèå! Óêàçàíû êàê ïðàâèëà äëÿ ñîñòàâíûõ ñëîâ, òàê è ïðàâèëî NOBREAK"
# :!~ Restorer
#, c-format
@@ -5307,32 +5284,28 @@ msgstr "Íåñ÷àñòíûì äåòÿì Óãàíäû òðåáóåòñÿ âàøà ïîìîùü!"
# :!~ Restorer
msgid "type :help iccf<Enter> for information "
msgstr ""
-"íàáåðèòå :help iccf<ENTER> ÷òîáû óçíàòü îá ýòîì "
-"ïîäðîáíåå "
+"íàáåðèòå :help iccf<ENTER> ÷òîáû óçíàòü îá ýòîì ïîäðîáíåå "
# #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé
# #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ
# :!~ Restorer
msgid "type :q<Enter> to exit "
msgstr ""
-"íàáåðèòå :q<ENTER> ÷òîáû çàâåðøèòü ðàáîòó ñ "
-"ïðîãðàììîé "
+"íàáåðèòå :q<ENTER> ÷òîáû çàâåðøèòü ðàáîòó ñ ïðîãðàììîé "
# #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé
# #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ
# :!~ Restorer
msgid "type :help<Enter> or <F1> for on-line help"
msgstr ""
-"íàáåðèòå :help<ENTER> èëè íàæìèòå <F1> ÷òîáû îçíàêîìèòüñÿ ñ "
-"äîêóìåíòàöèåé "
+"íàáåðèòå :help<ENTER> èëè íàæìèòå <F1> ÷òîáû îçíàêîìèòüñÿ ñ äîêóìåíòàöèåé "
# #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé
# #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ
# :!~ Restorer
msgid "type :help version9<Enter> for version info"
msgstr ""
-"íàáåðèòå :help version9<ENTER> ÷òîáû óçíàòü ïîäðîáíåå îá ýòîé "
-"âåðñèè"
+"íàáåðèòå :help version9<ENTER> ÷òîáû óçíàòü ïîäðîáíåå îá ýòîé âåðñèè"
# :!~ Restorer
msgid "Running in Vi compatible mode"
@@ -5343,61 +5316,53 @@ msgstr "Ïðîãðàììà ðàáîòàåò â ðåæèìå ñîâìåñòèìîñòè ñ ðåäàêòîðîì Vi"
# :!~ Restorer
msgid "type :set nocp<Enter> for Vim defaults"
msgstr ""
-"íàáåðèòå :set nocp<ENTER> ÷òîáû àêòèâèðîâàòü âîçìîæíîñòè "
-"Vim "
+"íàáåðèòå :set nocp<ENTER> ÷òîáû àêòèâèðîâàòü âîçìîæíîñòè Vim "
# #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé
# #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ
# :!~ Restorer
msgid "type :help cp-default<Enter> for info on this"
msgstr ""
-"íàáåðèòå :help cp-default<ENTER> ÷òîáû óçíàòü îá ýòîì "
-"ïîäðîáíåå "
+"íàáåðèòå :help cp-default<ENTER> ÷òîáû óçíàòü îá ýòîì ïîäðîáíåå "
# #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé
# #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ
# :!~ Restorer
msgid "menu Help->Orphans for information "
msgstr ""
-"ìåíþ Ñïðàâêà->Áëàãîòâîðèòåëüíîñòü ÷òîáû óçíàòü îá ýòîì "
-"ïîäðîáíåå"
+"ìåíþ Ñïðàâêà->Áëàãîòâîðèòåëüíîñòü ÷òîáû óçíàòü îá ýòîì ïîäðîáíåå"
# #Restorer: âûâîäèòñÿ òîëüêî â ÃÈÏ ïðè çàïóñêå gVim Easy
# :!~ Restorer
msgid "Running modeless, typed text is inserted"
msgstr ""
-"Óïðîù¸ííûé âàðèàíò. Âñ¸ ÷òî íàáèðàåòñÿ, ñ÷èòàåòñÿ òåêñòîì è ïîìåùàåòñÿ â "
-"áóôåð"
+"Óïðîù¸ííûé âàðèàíò. Âñ¸ ÷òî íàáèðàåòñÿ, ñ÷èòàåòñÿ òåêñòîì è ïîìåùàåòñÿ â áóôåð"
# #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé
# #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ
# :!~ Restorer
msgid "menu Edit->Global Settings->Toggle Insert Mode "
msgstr ""
-"ìåíþ Ïðàâêà->Îáùèå ïàðàìåòðû->Ðåæèì âñòàâêè ÷òîáû ïåðåêëþ÷àòü "
-"èç "
+"ìåíþ Ïðàâêà->Îáùèå ïàðàìåòðû->Ðåæèì âñòàâêè ÷òîáû ïåðåêëþ÷àòü èç "
# #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé
# :!~ Restorer
msgid " for two modes "
msgstr ""
-" ðåæèìà âñòàâêè â ðåæèì "
-"êîìàíä"
+" ðåæèìà âñòàâêè â ðåæèì êîìàíä"
# #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé
# #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ
# :!~ Restorer
msgid "menu Edit->Global Settings->Toggle Vi Compatible"
msgstr ""
-"ìåíþ Ïðàâêà->Îáùèå ïàðàìåòðû->Ñîâìåñòèìîñòü ñ Vi ÷òîáû "
-"àêòèâèðîâàòü "
+"ìåíþ Ïðàâêà->Îáùèå ïàðàìåòðû->Ñîâìåñòèìîñòü ñ Vi ÷òîáû àêòèâèðîâàòü "
# #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé
# :!~ Restorer
msgid " for Vim defaults "
msgstr ""
-" âîçìîæíîñòè ðåäàêòîðà "
-"Vim "
+" âîçìîæíîñòè ðåäàêòîðà Vim "
# :!~ Restorer
msgid "Sponsor Vim development!"
@@ -5426,8 +5391,7 @@ msgstr ""
# :!~ Restorer
msgid "menu Help->Sponsor/Register for information "
msgstr ""
-"ìåíþ Ñïðàâêà->Ñîäåéñòâèå è ðåãèñòðàöèÿ ÷òîáû óçíàòü îá ýòîì "
-"ïîäðîáíåå"
+"ìåíþ Ñïðàâêà->Ñîäåéñòâèå è ðåãèñòðàöèÿ ÷òîáû óçíàòü îá ýòîì ïîäðîáíåå"
# #Restorer: ïîäñòàâëÿåòñÿ â «E1016: Cannot declare a %s variable: %s» êàê
# #Restorer: ïåðâàÿ %s. Ìîæåò ëó÷øå íå ïåðåâîäèòü? Ïîêà ñäåëàë. Âûãëÿäèò òàê
@@ -6120,8 +6084,7 @@ msgstr "E108: Íå ñóùåñòâóåò ïåðåìåííîé \"%s\""
# :!~ Restorer
msgid "E109: Missing ':' after '?'"
-msgstr ""
-"E109: Îòñóòñòâóåò ñèìâîë äâîåòî÷èÿ ':' â îïåðàòîðå ïðîâåðêè óñëîâèÿ `?`"
+msgstr "E109: Îòñóòñòâóåò ñèìâîë äâîåòî÷èÿ ':' â îïåðàòîðå ïðîâåðêè óñëîâèÿ `?`"
# :!~ Restorer
msgid "E110: Missing ')'"
@@ -6237,8 +6200,7 @@ msgstr "E131: Óäàëåíèå íå âûïîëíåíî. Ýòà ôóíêöèÿ ñåé÷àñ èñïîëüçóåòñÿ %s"
# :!~ Restorer
msgid "E132: Function call depth is higher than 'maxfuncdepth'"
msgstr ""
-"E132: Êîëè÷åñòâî âûçîâîâ ôóíêöèé ïðåâûøàåò çíà÷åíèå â ïàðàìåòðå "
-"'maxfuncdepth'"
+"E132: Êîëè÷åñòâî âûçîâîâ ôóíêöèé ïðåâûøàåò çíà÷åíèå â ïàðàìåòðå 'maxfuncdepth'"
# :!~ Restorer
msgid "E133: :return not inside a function"
@@ -6258,8 +6220,7 @@ msgstr ""
# :!~ Restorer
msgid "E136: viminfo: Too many errors, skipping rest of file"
msgstr ""
-"E136: Îáíàðóæåíî ìíîæåñòâî îøèáîê â viminfo-ôàéëå. Ñ÷èòûâàíèå ôàéëà "
-"ïðåêðàùåíî"
+"E136: Îáíàðóæåíî ìíîæåñòâî îøèáîê â viminfo-ôàéëå. Ñ÷èòûâàíèå ôàéëà ïðåêðàùåíî"
# :!~ Restorer
#, c-format
@@ -6565,8 +6526,7 @@ msgstr "E199: Óäàëåíèå èëè èçìåíåíèå òåêóùåãî îêíà èëè áóôåðà"
# :!~ Restorer
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr ""
-"E200: Â ðåçóëüòàòå äåéñòâèé àâòîêîìàíä ïî ñîáûòèÿì *ReadPre ôàéë ñòàë "
-"íå÷èòàåì"
+"E200:  ðåçóëüòàòå äåéñòâèé àâòîêîìàíä ïî ñîáûòèÿì *ReadPre ôàéë ñòàë íå÷èòàåì"
# :!~ Restorer
msgid "E201: *ReadPre autocommands must not change current buffer"
@@ -6800,8 +6760,7 @@ msgstr "E250: Â íàáîðå øðèôòîâ %s îòñóòñòâóþò øðèôòû ñî ñëåäóþùèìè ñèìâîëàìè:"
# :!~ Restorer
msgid "E251: VIM instance registry property is badly formed. Deleted!"
msgstr ""
-"E251: Óäàëåíî çàðåãèñòðèðîâàííîå ïðîãðàììîé Vim ñâîéñòâî íåäîïóñòèìîãî "
-"ôîðìàòà"
+"E251: Óäàëåíî çàðåãèñòðèðîâàííîå ïðîãðàììîé Vim ñâîéñòâî íåäîïóñòèìîãî ôîðìàòà"
# :!~ Restorer
#, c-format
@@ -6853,11 +6812,9 @@ msgstr "E262: Îøèáêà ïðè ñ÷èòûâàíèè èç áàçû äàííûõ cscope íîìåð %d"
# :!~ Restorer
msgid ""
-"E263: Sorry, this command is disabled, the Python library could not be "
-"loaded."
+"E263: Sorry, this command is disabled, the Python library could not be loaded."
msgstr ""
-"E263: Íå óäàëîñü ïîäêëþ÷èòü ôàéë áèáëèîòåêè ÿçûêà Python. Êîìàíäà íå "
-"âûïîëíåíà"
+"E263: Íå óäàëîñü ïîäêëþ÷èòü ôàéë áèáëèîòåêè ÿçûêà Python. Êîìàíäà íå âûïîëíåíà"
# :!~ Restorer
msgid "E264: Python: Error initialising I/O objects"
@@ -6953,8 +6910,7 @@ msgstr "E286: Îøèáêà ïðè çàïóñêå ñëóæáû ìåòîäà ââîäà"
# :!~ Restorer
msgid "E287: Warning: Could not set destroy callback to IM"
msgstr ""
-"E287: Âíèìàíèå! Íå óäàëîñü íàçíà÷èòü ôóíêöèþ äëÿ îñòàíîâêè ñëóæáû ìåòîäà "
-"ââîäà"
+"E287: Âíèìàíèå! Íå óäàëîñü íàçíà÷èòü ôóíêöèþ äëÿ îñòàíîâêè ñëóæáû ìåòîäà ââîäà"
# :!~ Restorer
msgid "E288: Input method doesn't support any style"
@@ -6963,8 +6919,7 @@ msgstr "E288: Ñëóæáà ìåòîäà ââîäà íå ïîääåðæèâàåò ñòèëè îòîáðàæåíèÿ"
# #Restorer: âûâîäèòñÿ òîëüêî ïðè çíà÷åíèè ïàðàìåòðà 'verbose'>0
# :!~ Restorer
msgid "E289: Input method doesn't support my preedit type"
-msgstr ""
-"E289: Ñëóæáà ìåòîäà ââîäà íå ïîääåðæèâàåò íàçíà÷åííûé ñòèëü îòîáðàæåíèÿ"
+msgstr "E289: Ñëóæáà ìåòîäà ââîäà íå ïîääåðæèâàåò íàçíà÷åííûé ñòèëü îòîáðàæåíèÿ"
# #Restorer: âûâîäèòñÿ äëÿ ôóíêöèè matchaddpos()
# :!~ Restorer
@@ -7039,16 +6994,14 @@ msgstr "E309: Íå óäàëîñü ñ÷èòàòü áëîê íîìåð 1 èç %s"
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr ""
-"E310: Íåäîïóñòèìûé èäåíòèôèêàòîð â áëîêå 1 (âîçìîæíî, ýòî íå ôàéë ïîäêà÷êè "
-"%s)"
+"E310: Íåäîïóñòèìûé èäåíòèôèêàòîð â áëîêå 1 (âîçìîæíî, ýòî íå ôàéë ïîäêà÷êè %s)"
# ~!: earlier
msgid "E311: Recovery Interrupted"
msgstr "E311: Âîññòàíîâëåíèå ïðåðâàíî"
# :!~ Restorer
-msgid ""
-"E312: Errors detected while recovering; look for lines starting with ???"
+msgid "E312: Errors detected while recovering; look for lines starting with ???"
msgstr "E312: Îøèáêè ïðè âîññòàíîâëåíèè. Òàêèå ñòðîêè ïîìå÷åíû ñèìâîëàìè ???"
# :!~ Restorer
@@ -7110,8 +7063,7 @@ msgstr ""
# :!~ Restorer
msgid "E333: Menu path must lead to a menu item"
-msgstr ""
-"E333: Öåïî÷êà ïóíêòîâ ìåíþ äîëæíà îêàí÷èâàòüñÿ èñïîëíÿåìûì ïóíêòîì ìåíþ"
+msgstr "E333: Öåïî÷êà ïóíêòîâ ìåíþ äîëæíà îêàí÷èâàòüñÿ èñïîëíÿåìûì ïóíêòîì ìåíþ"
# :!~ Restorer
#, c-format
@@ -7143,8 +7095,7 @@ msgstr "E339: Ïðåâûøåíà äëèíà ðåãóëÿðíîãî âûðàæåíèÿ"
# :!~ Restorer
msgid "E340: Internal error; if you can reproduce please report a bug"
msgstr ""
-"E340: Âíóòðåííÿÿ îøèáêà. Åñëè âîçìîæíî å¸ âîñïðîèçâåñòè, ñîîáùèòå "
-"ðàçðàáîò÷èêó"
+"E340: Âíóòðåííÿÿ îøèáêà. Åñëè âîçìîæíî å¸ âîñïðîèçâåñòè, ñîîáùèòå ðàçðàáîò÷èêó"
# :!~ Restorer
#, c-format
@@ -7240,8 +7191,8 @@ msgstr "E359: Óñòàíîâêà ðåæèìà ýêðàíà íå ïîääåðæèâàåòñÿ"
# :!~ Restorer
msgid "E360: Cannot execute shell with -f option"
msgstr ""
-"E360: Íå óäàëîñü âûçâàòü êîìàíäíóþ îáîëî÷êó. Ïðîãðàììà çàïóùåíà ñ àðãóìåíòîì "
-"-f"
+"E360: Íå óäàëîñü âûçâàòü êîìàíäíóþ îáîëî÷êó. Ïðîãðàììà çàïóùåíà ñ àðãóìåíòîì -"
+"f"
# :!~ Restorer
msgid "E362: Using a boolean value as a Float"
@@ -7303,8 +7254,7 @@ msgstr "E373: Â ôîðìàòíîé ñòðîêå íåïðåäâèäåííîå ïîÿâëåíèå ñïåöèôèêàòîðà %%%c"
# :!~ Restorer
msgid "E374: Missing ] in format string"
-msgstr ""
-"E374: Íå óêàçàí ñèìâîë çàêðûâàþùåé êâàäðàòíîé ñêîáêè â ôîðìàòíîé ñòðîêå"
+msgstr "E374: Íå óêàçàí ñèìâîë çàêðûâàþùåé êâàäðàòíîé ñêîáêè â ôîðìàòíîé ñòðîêå"
# :!~ Restorer
#, c-format
@@ -7339,8 +7289,7 @@ msgstr "E381: Äîñòèãíóòà âåðõíÿÿ ãðàíèöà ñïèñêà ðåçóëüòàòîâ"
# :!~ Restorer
msgid "E382: Cannot write, 'buftype' option is set"
-msgstr ""
-"E382: Íåâîçìîæíà çàïèñü áóôåðà ïðè òåêóùåì çíà÷åíèè ïàðàìåòðà 'buftype'"
+msgstr "E382: Íåâîçìîæíà çàïèñü áóôåðà ïðè òåêóùåì çíà÷åíèè ïàðàìåòðà 'buftype'"
# :!~ Restorer
#, c-format
@@ -7477,8 +7426,7 @@ msgstr "E411: Íå íàéäåíà ãðóïïó ïîäñâåòêè %s"
# :!~ Restorer
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
-msgstr ""
-"E412: Óêàçàíû íå âñå òðåáóåìûå ïàðàìåòðû â êîìàíäå `:highlight link %s`"
+msgstr "E412: Óêàçàíû íå âñå òðåáóåìûå ïàðàìåòðû â êîìàíäå `:highlight link %s`"
# :!~ Restorer
#, c-format
@@ -7606,8 +7554,7 @@ msgstr "E441: Îòñóòñòâóåò îêíî ïðîñìîòðà"
# :!~ Restorer
msgid "E442: Can't split topleft and botright at the same time"
-msgstr ""
-"E442: Íå äîïóñêàåòñÿ îäíîâðåìåííîå óêàçàíèå êîìàíä :topleft è :botright"
+msgstr "E442: Íå äîïóñêàåòñÿ îäíîâðåìåííîå óêàçàíèå êîìàíä :topleft è :botright"
# :!~ Restorer
msgid "E443: Cannot rotate when another window is split"
@@ -7942,8 +7889,7 @@ msgstr "E503: Êîôå åù¸ íå ãîòîâ"
# #Restorer: îøèáêà E504:
# :!~ Restorer
msgid "is read-only (cannot override: \"W\" in 'cpoptions')"
-msgstr ""
-"ôàéë òîëüêî äëÿ ÷òåíèÿ (÷òîáû çàïèñàòü, óáåðèòå ôëàã 'W' â 'cpoptions')"
+msgstr "ôàéë òîëüêî äëÿ ÷òåíèÿ (÷òîáû çàïèñàòü, óáåðèòå ôëàã 'W' â 'cpoptions')"
# #Restorer: îøèáêà E505:
# :!~ Restorer
@@ -8279,8 +8225,7 @@ msgstr "íåäîïóñòèìûé íà÷àëüíûé ñèìâîë"
# #Restorer: âûâîäèòñÿ êàê îøèáêà E576:
# :!~ Restorer
msgid "Missing '>'"
-msgstr ""
-"îòñóòñòâóåò ñèìâîë çàêðûâàþùåé óãëîâîé ñêîáêè â çàïèñè æóðíàëà çàêëàäîê"
+msgstr "îòñóòñòâóåò ñèìâîë çàêðûâàþùåé óãëîâîé ñêîáêè â çàïèñè æóðíàëà çàêëàäîê"
# #Restorer: âûâîäèòñÿ êàê îøèáêà E577:
# :!~ Restorer
@@ -8422,8 +8367,7 @@ msgstr "E607: Íåñêîëüêî ñëåäóþùèõ îäíà çà äðóãîé êîìàíä :finally"
# :!~ Restorer
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr ""
-"E608:  íàçíà÷åííûõ ïîëüçîâàòåëåì èñêëþ÷åíèÿõ çàïðåùåíî óêàçàíèå ïðèñòàâêè "
-"VIM"
+"E608:  íàçíà÷åííûõ ïîëüçîâàòåëåì èñêëþ÷åíèÿõ çàïðåùåíî óêàçàíèå ïðèñòàâêè VIM"
# :!~ Restorer
#, c-format
@@ -8634,8 +8578,7 @@ msgstr "E658: Ïîòåðÿíî ñîåäèíåíèå ñðåäû ðàçðàáîòêè NetBeans ñ áóôåðîì %d"
# :!~ Restorer
msgid "E659: Cannot invoke Python recursively"
msgstr ""
-"E659: Â äàííîé âåðñèè ïðîãðàììû íå äîïóñêàåòñÿ ðåêóðñèâíûé âûçîâ êîìàíä "
-"Python"
+"E659: Â äàííîé âåðñèè ïðîãðàììû íå äîïóñêàåòñÿ ðåêóðñèâíûé âûçîâ êîìàíä Python"
# :!~ Restorer
#, c-format
@@ -8767,14 +8710,12 @@ msgstr "E686: Â ôóíêöèè %s òèï àðãóìåíòà äîëæåí áûòü List"
# :!~ Restorer
msgid "E687: Less targets than List items"
msgstr ""
-"E687: Êîëè÷åñòâî ïåðåìåííûõ ìåíüøå êîëè÷åñòâà ïðèñâàèâàåìûõ çíà÷åíèé "
-"âûðàæåíèÿ"
+"E687: Êîëè÷åñòâî ïåðåìåííûõ ìåíüøå êîëè÷åñòâà ïðèñâàèâàåìûõ çíà÷åíèé âûðàæåíèÿ"
# :!~ Restorer
msgid "E688: More targets than List items"
msgstr ""
-"E688: Êîëè÷åñòâî ïåðåìåííûõ áîëüøå êîëè÷åñòâà ïðèñâàèâàåìûõ çíà÷åíèé "
-"âûðàæåíèÿ"
+"E688: Êîëè÷åñòâî ïåðåìåííûõ áîëüøå êîëè÷åñòâà ïðèñâàèâàåìûõ çíà÷åíèé âûðàæåíèÿ"
# :!~ Restorer
#, c-format
@@ -8811,8 +8752,7 @@ msgstr "E695: Íå äîïóñêàåòñÿ óêàçàíèå èíäåêñà äëÿ ïåðåìåííûõ ñ òèïîì Funcref"
#, c-format
msgid "E696: Missing comma in List: %s"
msgstr ""
-"E696: Â äàííûõ òèï List íå óêàçàí ñèìâîë çàïÿòîé, êàê ðàçäåëèòåëü ýëåìåíòîâ "
-"%s"
+"E696: Â äàííûõ òèï List íå óêàçàí ñèìâîë çàïÿòîé, êàê ðàçäåëèòåëü ýëåìåíòîâ %s"
# :!~ Restorer
#, c-format
@@ -8848,8 +8788,7 @@ msgstr "E703: Îæèäàëñÿ òèï äàííûõ Number, à ïîëó÷åí Funcref"
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
msgstr ""
-"E704: Íàèìåíîâàíèå ïåðåìåííîé ñ òèïîì Funcref äîëæíî áûòü ñ ïðîïèñíîé áóêâû "
-"%s"
+"E704: Íàèìåíîâàíèå ïåðåìåííîé ñ òèïîì Funcref äîëæíî áûòü ñ ïðîïèñíîé áóêâû %s"
# :!~ Restorer
#, c-format
@@ -9253,8 +9192,7 @@ msgstr "E787: Ñîäåðæèìîå áóôåðà áûëî íåïðåäâèäåííî èçìåíåíî"
# :!~ Restorer
msgid "E788: Not allowed to edit another buffer now"
msgstr ""
-"E788: Çàïðåùåíà ïðàâêà áóôåðîâ, åñëè åñòü èçìåíåíèÿ â áóôåðå òîëüêî äëÿ "
-"÷òåíèÿ"
+"E788: Çàïðåùåíà ïðàâêà áóôåðîâ, åñëè åñòü èçìåíåíèÿ â áóôåðå òîëüêî äëÿ ÷òåíèÿ"
# :!~ Restorer
#, c-format
@@ -9388,8 +9326,7 @@ msgstr ""
# :!~ Restorer
msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr ""
-"E814: Íå óäàëîñü çàêðûòü òåêóùåå îêíî. Èñïîëíÿþòñÿ àêòèâíûå àâòîêîìàíäû"
+msgstr "E814: Íå óäàëîñü çàêðûòü òåêóùåå îêíî. Èñïîëíÿþòñÿ àêòèâíûå àâòîêîìàíäû"
# :!~ Restorer
msgid ""
@@ -9440,8 +9377,7 @@ msgstr "E823: Ôàéë ïîâðåæä¸í èëè íå ÿâëÿåòñÿ ôàéëîì èçìåíåíèé %s"
# :!~ Restorer
#, c-format
msgid "E824: Incompatible undo file: %s"
-msgstr ""
-"E824: Íå ïîääåðæèâàåìàÿ äàííîé ïðîãðàììîé Vim âåðñèÿ ôàéëà èçìåíåíèé %s"
+msgstr "E824: Íå ïîääåðæèâàåìàÿ äàííîé ïðîãðàììîé Vim âåðñèÿ ôàéëà èçìåíåíèé %s"
# :!~ Restorer
#, c-format
@@ -9476,8 +9412,7 @@ msgstr "E830: Íå íàéäåíî èçìåíåíèå íîìåð %ld"
# :!~ Restorer
#, c-format
msgid "E832: Non-encrypted file has encrypted undo file: %s"
-msgstr ""
-"E832: Ðåäàêòèðóåìûé ôàéë íå øèôðîâàí, íî øèôðîâàí åãî ôàéë èçìåíåíèé %s"
+msgstr "E832: Ðåäàêòèðóåìûé ôàéë íå øèôðîâàí, íî øèôðîâàí åãî ôàéë èçìåíåíèé %s"
# :!~ Restorer
#, c-format
@@ -9497,13 +9432,11 @@ msgstr "E835: Êîíôëèêò çíà÷åíèé ïàðàìåòðîâ 'ambiwidth' è 'fillchars'"
# :!~ Restorer
msgid "E836: This Vim cannot execute :python after using :py3"
-msgstr ""
-"E836:  äàííîé âåðñèè çàïðåù¸í âûçîâ êîìàíäû :python ïîñëå êîìàíäû :py3"
+msgstr "E836:  äàííîé âåðñèè çàïðåù¸í âûçîâ êîìàíäû :python ïîñëå êîìàíäû :py3"
# :!~ Restorer
msgid "E837: This Vim cannot execute :py3 after using :python"
-msgstr ""
-"E837:  äàííîé âåðñèè çàïðåù¸í âûçîâ êîìàíäû :py3 ïîñëå êîìàíäû :python"
+msgstr "E837:  äàííîé âåðñèè çàïðåù¸í âûçîâ êîìàíäû :py3 ïîñëå êîìàíäû :python"
# :!~ Restorer
msgid "E838: NetBeans is not supported with this GUI"
@@ -9514,8 +9447,7 @@ msgstr ""
# :!~ Restorer
msgid "E840: Completion function deleted text"
msgstr ""
-"E840: Ôóíêöèÿ, çàäàííàÿ ïîëüçîâàòåëåì äëÿ ïîäñòàíîâêè, âûçâàëà óäàëåíèå "
-"òåêñòà"
+"E840: Ôóíêöèÿ, çàäàííàÿ ïîëüçîâàòåëåì äëÿ ïîäñòàíîâêè, âûçâàëà óäàëåíèå òåêñòà"
# :!~ Restorer
msgid "E841: Reserved name, cannot be used for user defined command"
@@ -9613,8 +9545,8 @@ msgstr ""
# :!~ Restorer
msgid "E860: Need 'id' and 'type' or 'types' with 'both'"
msgstr ""
-"E860: Åñëè çàäàí êëþ÷ \"both\", óêàæèòå çíà÷åíèå êëþ÷åé \"id\" è \"type\" "
-"èëè \"types\""
+"E860: Åñëè çàäàí êëþ÷ \"both\", óêàæèòå çíà÷åíèå êëþ÷åé \"id\" è \"type\" èëè "
+"\"types\""
# :!~ Restorer
msgid "E861: Cannot open a second popup with a terminal"
@@ -9726,11 +9658,9 @@ msgstr "E882: Îøèáêà ïðè âûïîëíåíèè ñðàâíåíèÿ â ôóíêöèè ïîèñêà äóáëèêàòîâ"
# :!~ Restorer
msgid ""
-"E883: Search pattern and expression register may not contain two or more "
-"lines"
+"E883: Search pattern and expression register may not contain two or more lines"
msgstr ""
-"E883: Ðåãèñòð ïîèñêà è ðåãèñòð âûðàæåíèÿ íå ìîãóò ñîäåðæàòü áîëåå îäíîé "
-"ñòðîêè"
+"E883: Ðåãèñòð ïîèñêà è ðåãèñòð âûðàæåíèÿ íå ìîãóò ñîäåðæàòü áîëåå îäíîé ñòðîêè"
# :!~ Restorer
#, c-format
@@ -9790,8 +9720,7 @@ msgid ""
"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
"could not be loaded."
msgstr ""
-"E895: Íå ïîäêëþ÷åí ìîäóëü racket/base äëÿ ÿçûêà MzScheme. Êîìàíäà íå "
-"âûïîëíåíà"
+"E895: Íå ïîäêëþ÷åí ìîäóëü racket/base äëÿ ÿçûêà MzScheme. Êîìàíäà íå âûïîëíåíà"
# :!~ Restorer
#, c-format
@@ -9842,8 +9771,7 @@ msgstr "E903: Àðãóìåíòû ïîëó÷åííîé êîìàíäû íå çàêëþ÷åíû â äâîéíûå êàâû÷êè"
# :!~ Restorer
msgid "E904: Last argument for expr/call must be a number"
msgstr ""
-"E904: Òèï äàííûõ ïîñëåäíåãî ïàðàìåòðà êîìàíäû expr èëè call äîëæåí áûòü "
-"Number"
+"E904: Òèï äàííûõ ïîñëåäíåãî ïàðàìåòðà êîìàíäû expr èëè call äîëæåí áûòü Number"
# #Restorer: âûâîäèòñÿ ïðè 'verbose'>3
# :!~ Restorer
@@ -9897,8 +9825,8 @@ msgstr "E914: Îæèäàëñÿ òèï äàííûõ Float, à ïîëó÷åí Channel"
# :!~ Restorer
msgid "E915: in_io buffer requires in_buf or in_name to be set"
msgstr ""
-"E915: Ïðè óñòàíîâêå êëþ÷ó in_io çíà÷åíèÿ buffer, òðåáóåòñÿ çàäàòü êëþ÷ "
-"in_buf èëè in_name"
+"E915: Ïðè óñòàíîâêå êëþ÷ó in_io çíà÷åíèÿ buffer, òðåáóåòñÿ çàäàòü êëþ÷ in_buf "
+"èëè in_name"
# :!~ Restorer
msgid "E916: Not a valid job"
@@ -9922,8 +9850,7 @@ msgstr "E919: Â êàòàëîãàõ, óêàçàííûõ â ïàðàìåòðå '%s', íå íàéäåíî \"%s\""
# :!~ Restorer
msgid "E920: _io file requires _name to be set"
msgstr ""
-"E920: Ïðè óñòàíîâêå êëþ÷àì *_io çíà÷åíèÿ file, òðåáóåòñÿ çàäàòü è êëþ÷è "
-"*_name"
+"E920: Ïðè óñòàíîâêå êëþ÷àì *_io çíà÷åíèÿ file, òðåáóåòñÿ çàäàòü è êëþ÷è *_name"
# :!~ Restorer
msgid "E921: Invalid callback argument"
@@ -10293,8 +10220,7 @@ msgstr "E997: Íå óäàëîñü íàéòè âêëàäêó ïîä íîìåðîì %d"
# :!~ Restorer
#, c-format
msgid "E998: Reduce of an empty %s with no initial value"
-msgstr ""
-"E998: Ôóíêöèÿ reduce() âûçâàíà äëÿ ïóñòîãî %s è áåç íà÷àëüíîãî çíà÷åíèÿ"
+msgstr "E998: Ôóíêöèÿ reduce() âûçâàíà äëÿ ïóñòîãî %s è áåç íà÷àëüíîãî çíà÷åíèÿ"
# :!~ Restorer
#, c-format
@@ -10480,8 +10406,7 @@ msgstr "E1034: Îáíàðóæåíî èñïîëüçîâàíèå çàðåçåðâèðîâàííîãî ñëîâà â %s"
# :!~ Restorer
#, no-c-format
msgid "E1035: % requires number arguments"
-msgstr ""
-"E1035: Äëÿ îïåðàöèè äåëåíèå ñ îñòàòêîì òèï îïåðàíäîâ äîëæåí áûòü Number"
+msgstr "E1035: Äëÿ îïåðàöèè äåëåíèå ñ îñòàòêîì òèï îïåðàíäîâ äîëæåí áûòü Number"
# :!~ Restorer
#, c-format
@@ -10592,8 +10517,7 @@ msgstr "E1059: Çàïðåù¸í ïðîáåëüíûé ñèìâîë ïåðåä ñèìâîëîì äâîåòî÷èå â %s"
# :!~ Restorer
#, c-format
msgid "E1060: Expected dot after name: %s"
-msgstr ""
-"E1060:  êîìàíäå :import îòñóòñòâóåò ñèìâîë òî÷êè ïîñëå íàèìåíîâàíèÿ %s"
+msgstr "E1060:  êîìàíäå :import îòñóòñòâóåò ñèìâîë òî÷êè ïîñëå íàèìåíîâàíèÿ %s"
# :!~ Restorer
#, c-format
@@ -10654,8 +10578,7 @@ msgstr "E1073: Íàèìåíîâàíèå ôóíêöèè óæå îïðåäåëåíî %s"
# :!~ Restorer
msgid "E1074: No white space allowed after dot"
-msgstr ""
-"E1074: Çàïðåù¸í ïðîáåëüíûé ñèìâîë ïîñëå ñèìâîëà òî÷êè â êîìàíäå :import"
+msgstr "E1074: Çàïðåù¸í ïðîáåëüíûé ñèìâîë ïîñëå ñèìâîëà òî÷êè â êîìàíäå :import"
# :!~ Restorer
#, c-format
@@ -10841,13 +10764,11 @@ msgstr ""
# :!~ Restorer
msgid "E1116: \"assert_fails()\" fifth argument must be a string"
msgstr ""
-"E1116:  ôóíêöèè assert_fails() çíà÷åíèåì àðãóìåíòà íîìåð 5 äîëæíà áûòü "
-"ñòðîêà"
+"E1116:  ôóíêöèè assert_fails() çíà÷åíèåì àðãóìåíòà íîìåð 5 äîëæíà áûòü ñòðîêà"
# :!~ Restorer
msgid "E1117: Cannot use ! with nested :def"
-msgstr ""
-"E1117: Íå äîïóñêàåòñÿ óêàçàíèå ìîäèôèêàòîðà ! äëÿ âëîæåííûõ êîìàíä :def"
+msgstr "E1117: Íå äîïóñêàåòñÿ óêàçàíèå ìîäèôèêàòîðà ! äëÿ âëîæåííûõ êîìàíä :def"
# :!~ Restorer
msgid "E1118: Cannot change locked list"
@@ -10856,8 +10777,7 @@ msgstr "E1118: Èçìåíåíèå ñïèñêà íå âûïîëíåíî. Óñòàíîâëåíà áëîêèðîâêà ñïèñêà"
# :!~ Restorer
msgid "E1119: Cannot change locked list item"
msgstr ""
-"E1119: Èçìåíåíèå ýëåìåíòà ñïèñêà íå âûïîëíåíî. Óñòàíîâëåíà áëîêèðîâêà "
-"ýëåìåíòà"
+"E1119: Èçìåíåíèå ýëåìåíòà ñïèñêà íå âûïîëíåíî. Óñòàíîâëåíà áëîêèðîâêà ýëåìåíòà"
# :!~ Restorer
msgid "E1120: Cannot change dict"
@@ -10936,8 +10856,7 @@ msgstr "E1135: Îæèäàëîñü ëîãè÷åñêîå çíà÷åíèå, à ïîëó÷åí String \"%s\""
# :!~ Restorer
msgid "E1136: <Cmd> mapping must end with <CR> before second <Cmd>"
msgstr ""
-"E1136: Íàçíà÷àåìàÿ êîìàíäà <Cmd> äîëæíà çàâåðøàåòñÿ <CR> ïåðåä ñëåäóþùåé "
-"<Cmd>"
+"E1136: Íàçíà÷àåìàÿ êîìàíäà <Cmd> äîëæíà çàâåðøàåòñÿ <CR> ïåðåä ñëåäóþùåé <Cmd>"
# :!~ Restorer
msgid "E1138: Using a Bool as a Number"
@@ -11041,8 +10960,7 @@ msgstr "E1159: Íå äîïóñêàåòñÿ ðàçáèåíèå îêíà îäíîâðåìåííî ñ çàêðûòèåì áóôåðà"
# :!~ Restorer
msgid "E1160: Cannot use a default for variable arguments"
msgstr ""
-"E1160: Íå äîïóñêàåòñÿ óêàçàíèå çíà÷åíèÿ ïî óìîë÷àíèþ äëÿ îñòàòî÷íûõ "
-"ïàðàìåòðîâ"
+"E1160: Íå äîïóñêàåòñÿ óêàçàíèå çíà÷åíèÿ ïî óìîë÷àíèþ äëÿ îñòàòî÷íûõ ïàðàìåòðîâ"
# :!~ Restorer
#, c-format
@@ -11187,8 +11105,7 @@ msgstr "E1187: Ïðîèçîøëà îøèáêà ïðè îáðàáîòêå ôàéëà defaults.vim"
# :!~ Restorer
msgid "E1188: Cannot open a terminal from the command line window"
-msgstr ""
-"E1188: Íå äîïóñêàåòñÿ ïåðåõîä â îêíî òåðìèíàëà èç îêíà êîìàíäíîé ñòðîêè"
+msgstr "E1188: Íå äîïóñêàåòñÿ ïåðåõîä â îêíî òåðìèíàëà èç îêíà êîìàíäíîé ñòðîêè"
# :!~ Restorer
#, c-format
@@ -11318,8 +11235,7 @@ msgid "E1215: Digraph must be one character: %s"
msgstr "E1215: Ñàì äèãðàô äîëæåí áûòü çàäàí êàê îäèí ñèìâîë, à íå %s"
# :!~ Restorer
-msgid ""
-"E1216: digraph_setlist() argument must be a list of lists with two items"
+msgid "E1216: digraph_setlist() argument must be a list of lists with two items"
msgstr ""
"E1216: Â ôóíêöèè digraph_setlist() òèï àðãóìåíòà äîëæåí áûòü List, ãäå "
"âëîæåííûå òèïû List ñîäåðæàò äâà ýëåìåíòà"
@@ -11390,14 +11306,12 @@ msgstr ""
# :!~ Restorer
#, c-format
msgid "E1229: Expected dictionary for using key \"%s\", but got %s"
-msgstr ""
-"E1229: Îæèäàëñÿ òèï Dictionary äëÿ îáðàáîòêè êëþ÷à \"%s\", à ïîëó÷åí %s"
+msgstr "E1229: Îæèäàëñÿ òèï Dictionary äëÿ îáðàáîòêè êëþ÷à \"%s\", à ïîëó÷åí %s"
# :!~ Restorer
msgid "E1230: Encryption: sodium_mlock() failed"
msgstr ""
-"E1230: Îøèáêà øèôðîâàíèÿ. Ïðîèçîø¸ë ñáîé â áèáëèîòå÷íîé ôóíêöèè "
-"sodium_mlock()"
+"E1230: Îøèáêà øèôðîâàíèÿ. Ïðîèçîø¸ë ñáîé â áèáëèîòå÷íîé ôóíêöèè sodium_mlock()"
# :!~ Restorer
#, c-format
@@ -11744,8 +11658,7 @@ msgstr ""
#, c-format
msgid "E1301: String, Number, List or Blob required for argument %d"
msgstr ""
-"E1301: Òèï äàííûõ àðãóìåíòà íîìåð %d äîëæåí áûòü String, Number, List èëè "
-"BLOB"
+"E1301: Òèï äàííûõ àðãóìåíòà íîìåð %d äîëæåí áûòü String, Number, List èëè BLOB"
# :!~ Restorer
msgid "E1302: Script variable was deleted"
@@ -11764,8 +11677,7 @@ msgid "E1304: Cannot use type with this variable: %s"
msgstr "E1304: Íå äîïóñêàåòñÿ óêàçûâàòü òèïà äàííûõ äëÿ ïåðåìåííîé %s"
# :!~ Restorer
-msgid ""
-"E1305: Cannot use \"length\", \"end_col\" and \"end_lnum\" with \"text\""
+msgid "E1305: Cannot use \"length\", \"end_col\" and \"end_lnum\" with \"text\""
msgstr ""
"E1305: Íåäîïóñòèìî óêàçûâàòü êëþ÷è \"length\", \"end_col\" è \"end_lnum\" c "
"êëþ÷îì \"text\""
@@ -11917,8 +11829,8 @@ msgstr "E1337: Ó êëàññà \"%2$s\" îòñóòñòâóåò ïåðåìåííàÿ êëàññà \"%1$s\""
# :!~ Restorer
msgid ""
-"E1339: Cannot add a textprop with text after using a textprop with a "
-"negative id"
+"E1339: Cannot add a textprop with text after using a textprop with a negative "
+"id"
msgstr ""
"E1339: Çàïðåùåíà âñòàâêà âèðòóàëüíîãî òåêñòà ïîñëå ïðèìåíåíèÿ îòðèöàòåëüíîãî "
"çíà÷åíèÿ ÈÄ"
@@ -12056,11 +11968,10 @@ msgstr ""
# :!~ Restorer
msgid ""
-"E1368: Static must be followed by \"var\" or \"def\" or \"final\" or "
-"\"const\""
+"E1368: Static must be followed by \"var\" or \"def\" or \"final\" or \"const\""
msgstr ""
-"E1368: Ïîñëå êëþ÷åâîãî ñëîâà \"static\" òðåáóåòñÿ êîìàíäà :var èëè :def, "
-"ëèáî êëþ÷åâîå ñëîâî \"final\" èëè \"const\""
+"E1368: Ïîñëå êëþ÷åâîãî ñëîâà \"static\" òðåáóåòñÿ êîìàíäà :var èëè :def, ëèáî "
+"êëþ÷åâîå ñëîâî \"final\" èëè \"const\""
# :!~ Restorer
#, c-format
@@ -12079,8 +11990,7 @@ msgstr "E1371: Ïîñëå êëþ÷åâîãî ñëîâà \"abstract\" òðåáóåòñÿ êîìàíäà :def"
#, c-format
msgid "E1372: Abstract method \"%s\" cannot be defined in a concrete class"
msgstr ""
-"E1372: Íå äîïóñêàåòñÿ îïðåäåëåíèå â ðåàëüíîì êëàññå àáñòðàêòíîãî ìåòîäà "
-"\"%s\""
+"E1372: Íå äîïóñêàåòñÿ îïðåäåëåíèå â ðåàëüíîì êëàññå àáñòðàêòíîãî ìåòîäà \"%s\""
# :!~ Restorer
#, c-format
@@ -12129,8 +12039,8 @@ msgstr "E1381: Ê èíòåðôåéñó íåïðèìåíèìî êëþ÷åâîå ñëîâî \"implements\""
#, c-format
msgid "E1382: Variable \"%s\": type mismatch, expected %s but got %s"
msgstr ""
-"E1382: Íåñîîòâåòñòâóþùèé òèï äàííûõ ïåðåìåííîé \"%s\". Îæèäàëñÿ %s, à "
-"ïîëó÷åí %s"
+"E1382: Íåñîîòâåòñòâóþùèé òèï äàííûõ ïåðåìåííîé \"%s\". Îæèäàëñÿ %s, à ïîëó÷åí "
+"%s"
# :!~ Restorer
#, c-format
@@ -12268,8 +12178,8 @@ msgstr "E1408: Èíòåðôåéñû íå ïîääåðæèâàþò ôèíàëèçèðîâàííûå ïåðåìåííûå"
#, c-format
msgid "E1409: Cannot change read-only variable \"%s\" in class \"%s\""
msgstr ""
-"E1409: Íå äîïóñêàåòñÿ èçìåíåíèå äîñòóïíîé òîëüêî äëÿ ÷òåíèÿ ïåðåìåííîé "
-"\"%s\" êëàññà \"%s\""
+"E1409: Íå äîïóñêàåòñÿ èçìåíåíèå äîñòóïíîé òîëüêî äëÿ ÷òåíèÿ ïåðåìåííîé \"%s\" "
+"êëàññà \"%s\""
# :!~ Restorer
msgid "E1410: Const variable not supported in an interface"
@@ -12385,8 +12295,7 @@ msgstr ""
#, c-format
msgid "E1503: Positional argument %d out of bounds: %s"
msgstr ""
-"E1503: Ñïåöèôèêàòîð ïîçèöèè íîìåð %d íå ñîîòâåòñòâóåò êîëè÷åñòâó àðãóìåíòîâ "
-"%s"
+"E1503: Ñïåöèôèêàòîð ïîçèöèè íîìåð %d íå ñîîòâåòñòâóåò êîëè÷åñòâó àðãóìåíòîâ %s"
# :!~ Restorer
#, c-format
@@ -12413,8 +12322,7 @@ msgstr ""
# :!~ Restorer
msgid "E1509: Error occurred when reading or writing extended attribute"
-msgstr ""
-"E1509: Ïðîèçîøëà îøèáêà ïðè ñ÷èòûâàíèè èëè çàïèñè ðàñøèðåííîãî àòðèáóòà"
+msgstr "E1509: Ïðîèçîøëà îøèáêà ïðè ñ÷èòûâàíèè èëè çàïèñè ðàñøèðåííîãî àòðèáóòà"
# :!~ Restorer
#, c-format
@@ -12635,8 +12543,8 @@ msgstr "èíäåêñ ñïèñêà âûõîäèò çà ãðàíèöû äèàïàçîíà"
#, c-format
msgid "internal error: failed to get Vim list item %d"
msgstr ""
-"âíóòðåííÿÿ îøèáêà. Íå óäàëîñü ïîëó÷èòü èç îáúåêòà Vim.List ýëåìåíò ñ "
-"èíäåêñîì %d"
+"âíóòðåííÿÿ îøèáêà. Íå óäàëîñü ïîëó÷èòü èç îáúåêòà Vim.List ýëåìåíò ñ èíäåêñîì "
+"%d"
# :!~ Restorer
msgid "slice step cannot be zero"
@@ -12923,8 +12831,7 @@ msgid "(global or local to buffer)"
msgstr "(îáëàñòü äåéñòâèÿ: îáùèé èëè òîëüêî äëÿ áóôåðà)"
# :!~ Restorer
-msgid ""
-"\" Each \"set\" line shows the current value of an option (on the left)."
+msgid "\" Each \"set\" line shows the current value of an option (on the left)."
msgstr ""
"\"  ñòðîêàõ, íà÷èíàþùèõñÿ ñî ñëîâà «set», ïîêàçàíî òåêóùåå çíà÷åíèå "
"ïàðàìåòðîâ"
@@ -12938,16 +12845,13 @@ msgstr ""
# :!~ Restorer
msgid "\" A boolean option will be toggled."
msgstr ""
-"\" äëÿ ïàðàìåòðîâ-ïåðåêëþ÷àòåëåé áóäåò èçìåíåíî çíà÷åíèå íà "
-"ïðîòèâîïîëîæíîå;"
+"\" äëÿ ïàðàìåòðîâ-ïåðåêëþ÷àòåëåé áóäåò èçìåíåíî çíà÷åíèå íà ïðîòèâîïîëîæíîå;"
# :!~ Restorer
msgid ""
-"\" For other options you can edit the value before hitting "
-"<Enter>."
+"\" For other options you can edit the value before hitting <Enter>."
msgstr ""
-"\" äëÿ äðóãèõ ïàðàìåòðîâ íåîáõîäèìî ïåðåä ýòèì îòðåäàêòèðîâàòü èõ "
-"çíà÷åíèÿ"
+"\" äëÿ äðóãèõ ïàðàìåòðîâ íåîáõîäèìî ïåðåä ýòèì îòðåäàêòèðîâàòü èõ çíà÷åíèÿ"
# :!~ Restorer
msgid "\" Hit <Enter> on a help line to open a help window on this option."
@@ -13739,8 +13643,7 @@ msgstr ""
# :!~ Restorer
msgid ""
-"\"last\", \"buffer\" or \"current\": which directory used for the file "
-"browser"
+"\"last\", \"buffer\" or \"current\": which directory used for the file browser"
msgstr ""
"êàòàëîã, èñïîëüçóåìûé äëÿ îêîí îòêðûòèÿ è ñîõðàíåíèÿ ôàéëîâ\n"
"Âîçìîæíûå çíà÷åíèÿ: \"last\", \"buffer\" èëè \"current\""
diff --git a/src/po/ru.po b/src/po/ru.po
index 13589d0..a679b4f 100644
--- a/src/po/ru.po
+++ b/src/po/ru.po
@@ -2039,7 +2039,7 @@ msgid " Omni completion (^O^N^P)"
msgstr " ПодÑтановка по контекÑту CTRL+O и CTRL+N или CTRL+P"
# :!~ Restorer
-msgid " Spelling suggestion (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
msgstr " ПодÑтановка вариантов напиÑÐ°Ð½Ð¸Ñ CTRL+S и CTRL+N или CTRL+P"
# :!~ Restorer
diff --git a/src/po/sk.cp1250.po b/src/po/sk.cp1250.po
index 36fd347..8521351 100644
--- a/src/po/sk.cp1250.po
+++ b/src/po/sk.cp1250.po
@@ -15,7 +15,7 @@ msgstr ""
"Last-Translator: Lubomir Host <rajo@platon.sk>\n"
"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=cp1250\n"
+"Content-Type: text/plain; charset=CP1250\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Vim 7.x\n"
diff --git a/src/po/sr.po b/src/po/sr.po
index 6372f92..3b76e3c 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-04-25 12:55+0400\n"
-"PO-Revision-Date: 2024-04-25 13:09+0400\n"
+"POT-Creation-Date: 2024-07-19 10:23+0400\n"
+"PO-Revision-Date: 2024-07-19 10:39+0400\n"
"Last-Translator: Ivan Pešić <ivan.pesic@gmail.com>\n"
"Language-Team: Serbian\n"
"Language: sr\n"
@@ -447,10 +447,6 @@ msgstr "катакана"
msgid "Bopomofo"
msgstr "бопомофо"
-msgid "Not enough memory to set references, garbage collection aborted!"
-msgstr ""
-"Ðема довољно меморије за поÑтављање референци, прекинуто је Ñкупљање отпада"
-
msgid ""
"\n"
"\tLast set from "
@@ -879,6 +875,10 @@ msgstr[0] "+-%s%3ld линија: "
msgstr[1] "+-%s%3ld линије: "
msgstr[2] "+-%s%3ld линија: "
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr ""
+"Ðема довољно меморије за поÑтављање референци, прекинуто је Ñкупљање отпада"
+
msgid "No match at cursor, finding next"
msgstr "Ðема подударања на меÑту курÑора, тражи Ñе даље"
@@ -1262,15 +1262,6 @@ msgstr "linenr је ван опÑега"
msgid "not allowed in the Vim sandbox"
msgstr "није дозвољено унутар Vim sandbox"
-#, c-format
-msgid "E370: Could not load library %s"
-msgstr "E370: Библиотека %s није могла да Ñе учита"
-
-msgid "Sorry, this command is disabled: the Perl library could not be loaded."
-msgstr ""
-"Жао нам је, ова команда је онемогућена: Perl библиотека није могла да Ñе "
-"учита."
-
msgid "invalid buffer number"
msgstr "неиÑправан број бафера"
@@ -1372,8 +1363,8 @@ msgstr " КориÑнички дефиниÑано довршавање (^U^N^P)
msgid " Omni completion (^O^N^P)"
msgstr " Omni довршавање (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " ПравопиÑни предлог (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " ПравопиÑни предлог (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Довршавање локалне кључне речи (^N^P)"
@@ -3886,6 +3877,15 @@ msgstr "УпиÑивање viminfo фајла „%sâ€"
msgid "Already only one window"
msgstr "Већ поÑтоји Ñамо један прозор"
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Библиотека %s није могла да Ñе учита"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"Жао нам је, ова команда је онемогућена: Perl библиотека није могла да Ñе "
+"учита."
+
msgid "Edit with Vim using &tabpages"
msgstr "Уређуј програмом Vim у новој &картици"
@@ -5939,9 +5939,6 @@ msgstr "E612: ДефиниÑано је превише знакова"
msgid "E613: Unknown printer font: %s"
msgstr "E613: Ðепознат фонт штампача: %s"
-msgid "E614: Class required"
-msgstr "E614: Потребна је клаÑа"
-
#, c-format
msgid "E616: Object required for argument %d"
msgstr "E616: За аргумент %d је потребан објекат"
@@ -8421,21 +8418,12 @@ msgstr "E1317: ÐеиÑправна декларација променљиве
msgid "E1318: Not a valid command in a class: %s"
msgstr "E1318: Команда не важи у клаÑи: %s"
-msgid "E1319: Using a Class as a Number"
-msgstr "E1319: КлаÑа Ñе кориÑти као Број"
-
msgid "E1320: Using an Object as a Number"
msgstr "E1320: Објекат Ñе кориÑти као Број"
-msgid "E1321: Using a Class as a Float"
-msgstr "E1321: КлаÑа Ñе кориÑти као Покретни"
-
msgid "E1322: Using an Object as a Float"
msgstr "E1322: Објекат Ñе кориÑти као Покретни"
-msgid "E1323: Using a Class as a String"
-msgstr "E1323: КлаÑа Ñе кориÑти као Стринг"
-
msgid "E1324: Using an Object as a String"
msgstr "E1324: Објекат Ñе кориÑти као Стринг"
@@ -8703,10 +8691,6 @@ msgid "E1394: Type name must start with an uppercase letter: %s"
msgstr "E1394: Име типа мора да почне великим Ñловом: %s"
#, c-format
-msgid "E1395: Type alias \"%s\" cannot be modified"
-msgstr "E1395: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†не може да Ñе измени"
-
-#, c-format
msgid "E1396: Type alias \"%s\" already exists"
msgstr "E1396: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†већ поÑтоји"
@@ -8720,18 +8704,6 @@ msgid "E1399: Type can only be used in a script"
msgstr "E1399: Тип може да Ñе употреби Ñамо у Ñкрипти"
#, c-format
-msgid "E1400: Using type alias \"%s\" as a Number"
-msgstr "E1400: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†Ñе кориÑти као Број"
-
-#, c-format
-msgid "E1401: Using type alias \"%s\" as a Float"
-msgstr "E1401: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†Ñе кориÑти као Покретни"
-
-#, c-format
-msgid "E1402: Using type alias \"%s\" as a String"
-msgstr "E1402: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†Ñе кориÑти као Стринг"
-
-#, c-format
msgid "E1403: Type alias \"%s\" cannot be used as a value"
msgstr "E1403: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†не може да Ñе кориÑти као вредноÑÑ‚"
@@ -8742,9 +8714,6 @@ msgstr "E1404: Abstract не може да Ñе кориÑти у интерфе
msgid "E1405: Class \"%s\" cannot be used as a value"
msgstr "E1405: КлаÑа „%s†не може да Ñе кориÑти као вредноÑÑ‚"
-msgid "E1406: Cannot use a Class as a variable or value"
-msgstr "E1406: КлаÑа не може да Ñе кориÑти као променљива или вредноÑÑ‚"
-
msgid "E1407: Cannot use a Typealias as a variable or value"
msgstr "E1407: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° не може да Ñе кориÑти као променљива или вредноÑÑ‚"
@@ -9701,6 +9670,9 @@ msgstr "вишеÑтруке картице"
msgid "0, 1 or 2; when to use a tab pages line"
msgstr "0, 1 или 2; када Ñе кориÑти линија Ñа картицама"
+msgid "behaviour when closing tab pages: left, uselast or empty"
+msgstr "понашање приликом затварања картице: left, uselast или празно"
+
msgid "maximum number of tab pages to open for -p and \"tab all\""
msgstr "макÑимални број картица које Ñе отварају за -p и „tab allâ€"
diff --git a/src/po/sv.po b/src/po/sv.po
index 629a22c..d5296db 100644
--- a/src/po/sv.po
+++ b/src/po/sv.po
@@ -261,8 +261,8 @@ msgstr " Användardefinierad komplettering (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omnikomplettering (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Stavningsförslag (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Stavningsförslag (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Lokal nyckelordskomplettering (^N^P)"
diff --git a/src/po/tojavascript.vim b/src/po/tojavascript.vim
index 8b0dd73..4671a47 100644
--- a/src/po/tojavascript.vim
+++ b/src/po/tojavascript.vim
@@ -5,15 +5,20 @@
set shortmess+=A
-for name in argv()[1:]
- exe 'edit ' .. fnameescape(name)
+let s:namenum = 0
+let s:fls = []
+for s:name in argv()[1:]
+ exe 'edit ' .. fnameescape(s:name)
" Strip comments, also after :set commands.
g/^\s*"/s/.*//
g/^\s*set .*"/s/.*//
" Write as .js file, xgettext recognizes them
- exe 'w! ' .. fnamemodify(name, ":t:r") .. ".js"
+ let s:fl = fnamemodify(s:name, ":t:r") .. s:namenum .. ".js"
+ exe 'w! ' .. s:fl
+ call add(s:fls, s:fl)
+ let s:namenum += 1
endfor
-
+call writefile(s:fls, "vim_to_js")
quit
diff --git a/src/po/tr.po b/src/po/tr.po
index 4cff7b3..1150d60 100644
--- a/src/po/tr.po
+++ b/src/po/tr.po
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim Turkish Localization Project\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-12-17 12:57+0300\n"
-"PO-Revision-Date: 2023-12-17 17:00+0300\n"
+"POT-Creation-Date: 2024-06-18 13:41+0300\n"
+"PO-Revision-Date: 2024-06-18 17:00+0300\n"
"Last-Translator: Emir SARI <emir_sari@icloud.com>\n"
"Language-Team: Turkish <https://github.com/bitigchi/vim>\n"
"Language: tr\n"
@@ -173,6 +173,9 @@ msgstr " (dosya %d/%d)"
msgid " (file (%d) of %d)"
msgstr " (dosya (%d)/%d)"
+msgid "[Command Line]"
+msgstr "[Komut Satırı]"
+
msgid "[Prompt]"
msgstr "[Ä°stem]"
@@ -444,9 +447,6 @@ msgstr "Katakana"
msgid "Bopomofo"
msgstr "Bopomofo"
-msgid "Not enough memory to set references, garbage collection aborted!"
-msgstr "Referansları ayarlamak için yetersiz bellek, atık toplama durduruldu"
-
msgid ""
"\n"
"\tLast set from "
@@ -697,9 +697,6 @@ msgstr "Hata"
msgid "Interrupt"
msgstr "Yarıda Kesilme"
-msgid "[Command Line]"
-msgstr "[Komut Satırı]"
-
msgid "is a directory"
msgstr "bir dizin"
@@ -868,6 +865,9 @@ msgid_plural "+-%s%3ld lines: "
msgstr[0] "+-%s%3ld satır: "
msgstr[1] "+-%s%3ld satır: "
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr "Referansları ayarlamak için yetersiz bellek, atık toplama durduruldu"
+
msgid "No match at cursor, finding next"
msgstr "İmleç konumunda eşleşme bulunamadı, sonraki bulunuyor"
@@ -1348,8 +1348,8 @@ msgstr " Kullanıcı tanımlı tamamlamalar (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Omni tamamlaması (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Yazım önerisi (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Yazım önerisi (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Dahili anahtar sözcük tamamlaması (^N^P)"
@@ -1427,6 +1427,9 @@ msgstr "mapnew() argümanı"
msgid "filter() argument"
msgstr "filter() argümanı"
+msgid "foreach() argument"
+msgstr "foreach() argümanı"
+
msgid "extendnew() argument"
msgstr "extendnew() argümanı"
@@ -2473,6 +2476,9 @@ msgstr "%s, %s üzerinde"
msgid "Printing '%s'"
msgstr "'%s' yazdırılıyor"
+#~ msgid "DefaultFontNameForWindows"
+#~ msgstr ""
+
#, c-format
msgid "Opening the X display took %ld msec"
msgstr "X ekranını açma %ld milisaniye sürdü"
@@ -3414,8 +3420,8 @@ msgid "%s returning %s"
msgstr "%s, %s döndürüyor"
#, c-format
-msgid "Function %s does not need compiling"
-msgstr "%s iÅŸlevini derlemeye gerek yok "
+msgid "Function %s%s%s does not need compiling"
+msgstr "%s%s%s iÅŸlevini derlemeye gerek yok "
#, c-format
msgid "%s (%s, compiled %s)"
@@ -3574,6 +3580,10 @@ msgstr " kullanıcı 2. vimrc dosyası: \""
msgid " 3rd user vimrc file: \""
msgstr " kullanıcı 3. vimrc dosyası: \""
+msgid " 4th user vimrc file: \""
+msgstr " kullanıcı 4. vimrc dosyası: \""
+
+
msgid " user exrc file: \""
msgstr " kullanıcı exrc dosyası: \""
@@ -4181,6 +4191,10 @@ msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :loadkeymap kaynak alınmayan bir dosyada kullanılıyor"
#, c-format
+msgid "E106: Unsupported diff output format: %s"
+msgstr "E106: Desteklenmeyen diff çıktısı biçimi: %s"
+
+#, c-format
msgid "E107: Missing parentheses: %s"
msgstr "E107: Ayraç eksik: %s"
@@ -4509,8 +4523,8 @@ msgstr "E196: Bu sürümde ikili harfler bulunmamaktadır"
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: \"%s\" diline ayarlanamıyor"
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: Etkin pencere veya arabellek silinmiÅŸ"
+msgid "E199: Active window or buffer changed or deleted"
+msgstr "E199: Etkin pencere veya arabellek deÄŸiÅŸtirilmiÅŸ veya silinmiÅŸ"
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: *ReadPre otokomutları dosyayı okunamaz hale getirdi"
@@ -6771,6 +6785,10 @@ msgstr ""
msgid "E876: (NFA regexp) Not enough space to store the whole NFA"
msgstr "E876: (BSO düzenli ifadesi) Tüm BSO'yu depolamak için yeterli alan yok"
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %d"
+msgstr "E877: (BSO düzenli ifadesi) Geçersiz karakter sınıfı: %d"
+
msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!"
msgstr "E878: (BSO düzenli ifadesi) Dal gezinmesi için bellek ayrılamadı!"
@@ -8383,13 +8401,14 @@ msgid "E1330: Invalid type for object variable: %s"
msgstr "E1330: Nesne değişkeni için geçersiz tür: %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 sonrası \"var\", \"static\", \"final\" veya \"const\" "
+msgstr ""
+"E1331: public sonrası \"var\", \"static\", \"final\" veya \"const\" "
"gelmelidir"
#, c-format
-msgid "E1332: Public variable name cannot start with underscore: %s"
+msgid "E1332: public variable name cannot start with underscore: %s"
msgstr "E1332: Genel değişken adı bir alt çizgiyle başlayamaz: %s"
#, c-format
@@ -8512,8 +8531,8 @@ msgstr "E1367: \"%2$s\" arayüzünün \"%1$s\" değişkeninin erişim düzeyi fa
msgid ""
"E1368: Static must be followed by \"var\" or \"def\" or \"final\" or "
"\"const\""
-msgstr "E1368: Static sonrası \"var\", \"def\", \"final\" veya \"const\" "
-"gelmelidir"
+msgstr ""
+"E1368: Static sonrası \"var\", \"def\", \"final\" veya \"const\" gelmelidir"
#, c-format
msgid "E1369: Duplicate variable: %s"
@@ -8535,18 +8554,21 @@ msgstr "E1373: Soyut yöntem \"%s\" gerçeklenmemiş"
#, c-format
msgid "E1374: Class variable \"%s\" accessible only inside class \"%s\""
-msgstr "E1374: Sınıf değişkeni \"%s\", yalnızca \"%s\" sınıfının içinde "
+msgstr ""
+"E1374: Sınıf değişkeni \"%s\", yalnızca \"%s\" sınıfının içinde "
"eriÅŸilebilirdir"
#, c-format
msgid "E1375: Class variable \"%s\" accessible only using class \"%s\""
-msgstr "E1375: Sınıf değişkeni \"%s\", yalnızca \"%s\" sınıfı kullanılarak "
+msgstr ""
+"E1375: Sınıf değişkeni \"%s\", yalnızca \"%s\" sınıfı kullanılarak "
"eriÅŸilebilirdir"
#, c-format
msgid "E1376: Object variable \"%s\" accessible only using class \"%s\" object"
-msgstr "E1376: Nesne değişkeni \"%s\", yalnızca sınıf \"%s\" nesnesi "
-"kullanılarak erişilebilirdir"
+msgstr ""
+"E1376: Nesne değişkeni \"%s\", yalnızca sınıf \"%s\" nesnesi kullanılarak "
+"eriÅŸilebilirdir"
#, c-format
msgid "E1377: Access level of method \"%s\" is different in class \"%s\""
@@ -8576,23 +8598,25 @@ msgstr ""
#, c-format
msgid "E1384: Class method \"%s\" accessible only inside class \"%s\""
-msgstr "E1384: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfının içinde "
-"eriÅŸilebilirdir"
+msgstr ""
+"E1384: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfının içinde erişilebilirdir"
#, c-format
msgid "E1385: Class method \"%s\" accessible only using class \"%s\""
-msgstr "E1385: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfı kullanılarak "
+msgstr ""
+"E1385: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfı kullanılarak "
"eriÅŸilebilirdir"
#, c-format
msgid "E1386: Object method \"%s\" accessible only using class \"%s\" object"
-msgstr "E1386: Nesne yöntemi \"%s\", yalnızca sınıf \"%s\" nesnesi "
-"kullanılarak erişilebilirdir"
+msgstr ""
+"E1386: Nesne yöntemi \"%s\", yalnızca sınıf \"%s\" nesnesi kullanılarak "
+"eriÅŸilebilirdir"
-msgid "E1387: Public variable not supported in an interface"
+msgid "E1387: public variable not supported in an interface"
msgstr "E1387: Bir arayüzde genel değişken desteklenmiyor"
-msgid "E1388: Public keyword not supported for a method"
+msgid "E1388: public keyword not supported for a method"
msgstr "E1388: Bir yöntem için genel anahtar sözcük desteklenmiyor"
msgid "E1389: Missing name after implements"
@@ -8607,12 +8631,14 @@ msgstr ""
#, c-format
msgid "E1391: Cannot (un)lock variable \"%s\" in class \"%s\""
-msgstr "E1391: \"%2$s\" sınıfındaki \"%1$s\" değişkeni kilitlenemiyor/açılamıyor"
+msgstr ""
+"E1391: \"%2$s\" sınıfındaki \"%1$s\" değişkeni kilitlenemiyor/açılamıyor"
#, c-format
msgid "E1392: Cannot (un)lock class variable \"%s\" in class \"%s\""
-msgstr "E1392: \"%2$s\" sınıfındaki \"%1$s\" sınıf değişkeni "
-"kilitlenemiyor/açılamıyor"
+msgstr ""
+"E1392: \"%2$s\" sınıfındaki \"%1$s\" sınıf değişkeni kilitlenemiyor/"
+"açılamıyor"
msgid "E1393: Type can only be defined in Vim9 script"
msgstr "E1393: Tür, yalnızca Vim9 betiğinde tanımlanabilir"
@@ -8672,13 +8698,83 @@ msgstr "E1408: Final değişkeni bir arayüzde desteklenmiyor"
#, c-format
msgid "E1409: Cannot change read-only variable \"%s\" in class \"%s\""
-msgstr "E1409: \"%2$s\" sınıfındaki \"%1$s\" saltokunur değişken "
-"deÄŸiÅŸtirilemiyor"
+msgstr ""
+"E1409: \"%2$s\" sınıfındaki \"%1$s\" saltokunur değişken değiştirilemiyor"
msgid "E1410: Const variable not supported in an interface"
msgstr "E1410: Bir arayüzde bir bir Const değişken desteklenmiyor"
#, c-format
+msgid "E1411: Missing dot after object \"%s\""
+msgstr "E1411: \"%s\" nesnesi sonrası nokta eksik"
+
+#, c-format
+msgid "E1412: Builtin object method \"%s\" not supported"
+msgstr "E1412: Yerleşik nesne yöntemi \"%s\" desteklenmiyor"
+
+msgid "E1413: Builtin class method not supported"
+msgstr "E1413: Yerleşik sınıf yöntemi desteklenmiyor"
+
+msgid "E1414: Enum can only be defined in Vim9 script"
+msgstr "E1414: Enümerasyon, yalnızca Vim9 betiğinde kullanılabilir"
+
+#, c-format
+msgid "E1415: Enum name must start with an uppercase letter: %s"
+msgstr "E1415: Enümerasyon adı bir BÜYÜK harfle başlamalıdır: %s"
+
+msgid "E1416: Enum cannot extend a class or enum"
+msgstr "E1416: Enümerasyon, bir sınıfı veya enümerasyonu genişletemez"
+
+msgid "E1417: Abstract cannot be used in an Enum"
+msgstr "E1417: Abstract yalnızca bir enümerasyonda kullanılabilir"
+
+#, c-format
+msgid "E1418: Invalid enum value declaration: %s"
+msgstr "E1418: Geçersiz enümerasyon değeri beyanı: %s"
+
+#, c-format
+msgid "E1419: Not a valid command in an Enum: %s"
+msgstr "E1419: Bir enümerasyonda geçerli olmayan bir komut: %s"
+
+msgid "E1420: Missing :endenum"
+msgstr "E1420: :endenum eksik"
+
+#, c-format
+msgid "E1421: Enum \"%s\" cannot be used as a value"
+msgstr "E1421: \"%s\" enümerasyonu yalnızca bir değer olarak kullanılabilir"
+
+#, c-format
+msgid "E1422: Enum value \"%s\" not found in enum \"%s\""
+msgstr "E1422: \"%2$s\" enümerasyonunda \"%1$s\" değeri bulunamadı"
+
+#, c-format
+msgid "E1423: Enum value \"%s.%s\" cannot be modified"
+msgstr "E1423: Enümerasyon değeri \"%s.%s\" değiştirilemiyor"
+
+#, c-format
+msgid "E1424: Using an Enum \"%s\" as a Number"
+msgstr "E1424: Enümerasyon \"%s\", sayı olarak kullanılıyor"
+
+#, c-format
+msgid "E1425: Using an Enum \"%s\" as a String"
+msgstr "E1425: Enümerasyon \"%s\", dizi olarak kullanılıyor"
+
+#, c-format
+msgid "E1426: Enum \"%s\" ordinal value cannot be modified"
+msgstr "E1426: Enümerasyon sıralı değeri \"%s\" değiştirilemiyor"
+
+#, c-format
+msgid "E1427: Enum \"%s\" name cannot be modified"
+msgstr "E1427: Enümerasyon adı \"%s\" değiştirilemiyor"
+
+#, c-format
+msgid "E1428: Duplicate enum value: %s"
+msgstr "E1428: Yinelenen enümerasyon değeri: %s"
+
+msgid "E1429: Class can only be used in a script"
+msgstr "E1429: Sınıf yalnızca bir betikte kullanılabilir"
+
+#, c-format
msgid "E1500: Cannot mix positional and non-positional arguments: %s"
msgstr "E1500: Konumsal ve konumsal olmayan argümanlar karıştırılamıyor: %s"
@@ -8724,6 +8820,17 @@ msgstr "E1509: Genişletilmiş öznitelik okunurken veya yazılırken hata oluş
msgid "E1510: Value too large: %s"
msgstr "E1510: Değer pek büyük: %s"
+#, c-format
+msgid "E1511: Wrong number of characters for field \"%s\""
+msgstr "E1511: \"%s\" alanı için yanlış karakter sayısı"
+
+#, c-format
+msgid "E1512: Wrong character width for field \"%s\""
+msgstr "E1512: \"%s\" alanı için yanlış karakter genişliği"
+
+msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled"
+msgstr "E1513: Arabellek deÄŸiÅŸtirilemiyor. 'winfixbuf' etkinleÅŸtirilmiÅŸ"
+
msgid "--No lines in buffer--"
msgstr "--Arabellek içinde satır yok--"
@@ -9442,6 +9549,9 @@ msgstr "geçerli pencere için kullanılan en az satır sayısı"
msgid "minimal number of lines used for any window"
msgstr "herhangi bir pencere için kullanılan en az satır sayısı"
+msgid "keep window focused on a single buffer"
+msgstr "pencereyi tek bir arabelleğe odaklı tut"
+
msgid "keep the height of the window"
msgstr "pencerenin yüksekliğini tut"
diff --git a/src/po/uk.cp1251.po b/src/po/uk.cp1251.po
index 40d87f5..1a14b2a 100644
--- a/src/po/uk.cp1251.po
+++ b/src/po/uk.cp1251.po
@@ -1386,8 +1386,8 @@ msgstr " Êîðèñòóâàöüêå äîïîâíåííÿ (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Êì³òëèâå äîïîâíåííÿ (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Îðôîãðàô³÷íà ï³äêàçêà (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Îðôîãðàô³÷íà ï³äêàçêà (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Äîïîâíåííÿ ì³ñöåâèõ êëþ÷îâèõ ñë³â (^N^P)"
diff --git a/src/po/uk.po b/src/po/uk.po
index 273f833..d756d45 100644
--- a/src/po/uk.po
+++ b/src/po/uk.po
@@ -1386,8 +1386,8 @@ msgstr " КориÑтувацьке Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " Кмітливе Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Орфографічна підказка (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Орфографічна підказка (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¼Ñ–Ñцевих ключових Ñлів (^N^P)"
diff --git a/src/po/zh_CN.UTF-8.po b/src/po/zh_CN.UTF-8.po
index e604188..f368f6f 100644
--- a/src/po/zh_CN.UTF-8.po
+++ b/src/po/zh_CN.UTF-8.po
@@ -1291,8 +1291,8 @@ msgstr " 用户自定义补全 (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " 全能补全 (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " 拼写建议 (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " 拼写建议 (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " 关键字局部补全 (^N^P)"
diff --git a/src/po/zh_CN.cp936.po b/src/po/zh_CN.cp936.po
index ef3dfa8..89b4bfc 100644
--- a/src/po/zh_CN.cp936.po
+++ b/src/po/zh_CN.cp936.po
@@ -23,7 +23,7 @@ msgstr ""
"Language-Team: Simplified Chinese\n"
"Language: \n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=gbk\n"
+"Content-Type: text/plain; charset=GBK\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1291,8 +1291,8 @@ msgstr " Óû§×Ô¶¨Ò岹ȫ (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " È«Äܲ¹È« (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " ƴд½¨Òé (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " ƴд½¨Òé (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " ¹Ø¼ü×Ö¾Ö²¿²¹È« (^N^P)"
diff --git a/src/po/zh_CN.po b/src/po/zh_CN.po
index 4e34616..8e4571d 100644
--- a/src/po/zh_CN.po
+++ b/src/po/zh_CN.po
@@ -23,7 +23,7 @@ msgstr ""
"Language-Team: Simplified Chinese\n"
"Language: \n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=gb2312\n"
+"Content-Type: text/plain; charset=GB2312\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1291,8 +1291,8 @@ msgstr " Óû§×Ô¶¨Ò岹ȫ (^U^N^P)"
msgid " Omni completion (^O^N^P)"
msgstr " È«Äܲ¹È« (^O^N^P)"
-msgid " Spelling suggestion (s^N^P)"
-msgstr " ƴд½¨Òé (s^N^P)"
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " ƴд½¨Òé (^S^N^P)"
msgid " Keyword Local completion (^N^P)"
msgstr " ¹Ø¼ü×Ö¾Ö²¿²¹È« (^N^P)"
diff --git a/src/po/zh_TW.po b/src/po/zh_TW.po
index 2cedfd4..e37f90d 100644
--- a/src/po/zh_TW.po
+++ b/src/po/zh_TW.po
@@ -51,7 +51,7 @@ msgstr ""
"Language-Team: Hung-Te Lin <piaip@csie.ntu.edu.tw>, Cecil Sheng "
"<b7506022@csie.ntu.edu.tw>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=big5\n"
+"Content-Type: text/plain; charset=BIG5\n"
"Content-Transfer-Encoding: 8-bit\n"
msgid "E82: Cannot allocate any buffer, exiting..."
diff --git a/src/popupmenu.c b/src/popupmenu.c
index 6e9d826..da8241b 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -425,7 +425,7 @@ pum_under_menu(int row, int col, int only_redrawing)
* Returns attributes for every cell, or NULL if all attributes are the same.
*/
static int *
-pum_compute_text_attrs(char_u *text, hlf_T hlf)
+pum_compute_text_attrs(char_u *text, hlf_T hlf, int user_hlattr)
{
int i;
size_t leader_len;
@@ -483,6 +483,9 @@ pum_compute_text_attrs(char_u *text, hlf_T hlf)
else if (matched_start && ptr < text + leader_len)
new_attr = highlight_attr[hlf == HLF_PSI ? HLF_PMSI : HLF_PMNI];
+ if (user_hlattr > 0)
+ new_attr = hl_combine_attr(new_attr, user_hlattr);
+
char_cells = mb_ptr2cells(ptr);
for (i = 0; i < char_cells; i++)
attrs[cell_idx + i] = new_attr;
@@ -527,7 +530,7 @@ pum_screen_puts_with_attrs(
else
#endif
attr = attrs[col - col_start];
- screen_puts_len(ptr, char_len, row, col, attr);
+ screen_puts_len(ptr, char_len, row, col, attr);
col += mb_ptr2cells(ptr);
ptr += char_len;
}
@@ -628,6 +631,10 @@ pum_redraw(void)
{
hlf = hlfs[round];
attr = highlight_attr[hlf];
+ if (pum_array[idx].pum_user_hlattr > 0)
+ attr = hl_combine_attr(attr, pum_array[idx].pum_user_hlattr);
+ if (round == 1 && pum_array[idx].pum_user_kind_hlattr > 0)
+ attr = hl_combine_attr(attr, pum_array[idx].pum_user_kind_hlattr);
width = 0;
s = NULL;
switch (round)
@@ -656,7 +663,8 @@ pum_redraw(void)
if (saved != NUL)
*p = saved;
- attrs = pum_compute_text_attrs(st, hlf);
+ int user_hlattr = pum_array[idx].pum_user_hlattr;
+ attrs = pum_compute_text_attrs(st, hlf, user_hlattr);
#ifdef FEAT_RIGHTLEFT
if (pum_rl)
@@ -1332,9 +1340,10 @@ pum_set_event_info(dict_T *dict)
static void
pum_position_at_mouse(int min_width)
{
- if (Rows - mouse_row > pum_size)
+ if (Rows - mouse_row > pum_size || Rows - mouse_row > mouse_row)
{
- // Enough space below the mouse row.
+ // Enough space below the mouse row,
+ // or there is more space below the mouse row than above.
pum_row = mouse_row + 1;
if (pum_height > Rows - pum_row)
pum_height = Rows - pum_row;
@@ -1633,7 +1642,7 @@ pum_select_mouse_pos(void)
{
int idx = mouse_row - pum_row;
- if (idx < 0 || idx >= pum_size)
+ if (idx < 0 || idx >= pum_height)
pum_selected = -1;
else if (*pum_array[idx].pum_text != NUL)
pum_selected = idx;
diff --git a/src/popupwin.c b/src/popupwin.c
index 38c1c9e..0ff57fb 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -699,8 +699,8 @@ popup_highlight_curline(win_T *wp)
if (syn_name2id((char_u *)linehl) == 0)
linehl = "PmenuSel";
- sign_define_by_name(sign_name, NULL, (char_u *)linehl,
- NULL, NULL, NULL, NULL);
+ sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL,
+ NULL, SIGN_DEF_PRIO);
}
sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name,
@@ -2651,6 +2651,8 @@ f_popup_filter_yesno(typval_T *argvars, typval_T *rettv)
return;
c = *key;
+ if (c == CAR && need_wait_return)
+ return;
if (c == K_SPECIAL && key[1] != NUL)
c = TO_SPECIAL(key[1], key[2]);
@@ -2844,6 +2846,54 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED)
popup_adjust_position(wp);
}
+/*
+ * popup_setbuf({id}, {bufnr})
+ */
+ void
+f_popup_setbuf(typval_T *argvars, typval_T *rettv UNUSED)
+{
+ int id;
+ win_T *wp;
+ buf_T *buf;
+
+ rettv->v_type = VAR_BOOL;
+ rettv->vval.v_number = VVAL_FALSE;
+
+ if (check_for_number_arg(argvars, 0) == FAIL
+ || check_for_buffer_arg(argvars, 1) == FAIL)
+ return;
+
+ id = (int)tv_get_number(&argvars[0]);
+ wp = find_popup_win(id);
+ if (wp == NULL)
+ return;
+
+ buf = tv_get_buf_from_arg(&argvars[1]);
+
+ if (buf == NULL)
+ return;
+#ifdef FEAT_TERMINAL
+ if (buf->b_term != NULL && popup_terminal_exists())
+ {
+ emsg(_(e_cannot_open_second_popup_with_terminal));
+ return;
+ }
+#endif
+
+ if (wp->w_buffer != buf)
+ {
+ wp->w_buffer->b_nwindows--;
+ win_init_popup_win(wp, buf);
+ set_local_options_default(wp, FALSE);
+ swap_exists_action = SEA_READONLY;
+ buffer_ensure_loaded(buf);
+ swap_exists_action = SEA_NONE;
+ redraw_win_later(wp, UPD_NOT_VALID);
+ popup_adjust_position(wp);
+ }
+ rettv->vval.v_number = VVAL_TRUE;
+}
+
static void
popup_free(win_T *wp)
{
diff --git a/src/proto/autocmd.pro b/src/proto/autocmd.pro
index 4a502da..920987a 100644
--- a/src/proto/autocmd.pro
+++ b/src/proto/autocmd.pro
@@ -26,6 +26,7 @@ int has_textchanged(void);
int has_textchangedI(void);
int has_textchangedP(void);
int has_insertcharpre(void);
+int has_keyinputpre(void);
int has_cmdundefined(void);
int has_textyankpost(void);
int has_completechanged(void);
diff --git a/src/proto/dict.pro b/src/proto/dict.pro
index 346e1d5..b1ceecc 100644
--- a/src/proto/dict.pro
+++ b/src/proto/dict.pro
@@ -40,7 +40,7 @@ int eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal);
int eval_lit_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
void dict_extend(dict_T *d1, dict_T *d2, char_u *action, char *func_name);
dictitem_T *dict_lookup(hashitem_T *hi);
-int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive);
+int dict_equal(dict_T *d1, dict_T *d2, int ic);
long dict_count(dict_T *d, typval_T *needle, int ic);
void dict_extend_func(typval_T *argvars, type_T *type, char *func_name, char_u *arg_errmsg, int is_new, typval_T *rettv);
void dict_filter_map(dict_T *d, filtermap_T filtermap, type_T *argtype, char *func_name, char_u *arg_errmsg, typval_T *expr, typval_T *rettv);
diff --git a/src/proto/findfile.pro b/src/proto/findfile.pro
index 9560101..1c28221 100644
--- a/src/proto/findfile.pro
+++ b/src/proto/findfile.pro
@@ -12,7 +12,7 @@ char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum);
char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u *rel_fname, linenr_T *file_lnum);
char_u *find_file_name_in_path(char_u *ptr, int len, int options, long count, char_u *rel_fname);
int vim_ispathlistsep(int c);
-void uniquefy_paths(garray_T *gap, char_u *pattern);
+void uniquefy_paths(garray_T *gap, char_u *pattern, char_u *path_option);
int expand_in_path(garray_T *gap, char_u *pattern, int flags);
void simplify_filename(char_u *filename);
void f_simplify(typval_T *argvars, typval_T *rettv);
diff --git a/src/proto/list.pro b/src/proto/list.pro
index 1659b8f..27bea5e 100644
--- a/src/proto/list.pro
+++ b/src/proto/list.pro
@@ -16,7 +16,7 @@ listitem_T *listitem_alloc(void);
void listitem_free(list_T *l, listitem_T *item);
void listitem_remove(list_T *l, listitem_T *item);
long list_len(list_T *l);
-int list_equal(list_T *l1, list_T *l2, int ic, int recursive);
+int list_equal(list_T *l1, list_T *l2, int ic);
listitem_T *list_find(list_T *l, long n);
long list_find_nr(list_T *l, long idx, int *errorp);
char_u *list_find_str(list_T *l, long idx);
diff --git a/src/proto/mark.pro b/src/proto/mark.pro
index cc45f0d..d398c36 100644
--- a/src/proto/mark.pro
+++ b/src/proto/mark.pro
@@ -28,4 +28,5 @@ void set_last_cursor(win_T *win);
void free_all_marks(void);
xfmark_T *get_namedfm(void);
void f_getmarklist(typval_T *argvars, typval_T *rettv);
+void mark_forget_file(win_T *wp, int fnum);
/* vim: set ft=c : */
diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro
index c57c94c..bb976e3 100644
--- a/src/proto/mbyte.pro
+++ b/src/proto/mbyte.pro
@@ -48,6 +48,7 @@ int utf_islower(int a);
int utf_tolower(int a);
int utf_isupper(int a);
int mb_strnicmp(char_u *s1, char_u *s2, size_t nn);
+int mb_strnicmp2(char_u *s1, char_u *s2, size_t n1, size_t n2);
void show_utf8(void);
int latin_head_off(char_u *base, char_u *p);
int dbcs_screen_head_off(char_u *base, char_u *p);
diff --git a/src/proto/memline.pro b/src/proto/memline.pro
index c5d9b5d..238bcea 100644
--- a/src/proto/memline.pro
+++ b/src/proto/memline.pro
@@ -11,7 +11,7 @@ void ml_close_notmod(void);
void ml_timestamp(buf_T *buf);
void ml_recover(int checkext);
int recover_names(char_u *fname, int do_list, list_T *ret_list, int nr, char_u **fname_out);
-char_u *make_percent_swname(char_u *dir, char_u *name);
+char_u *make_percent_swname(char_u *dir, char_u *dir_end, char_u *name);
void get_b0_dict(char_u *fname, dict_T *d);
void ml_sync_all(int check_file, int check_char);
void ml_preserve(buf_T *buf, int message);
diff --git a/src/proto/option.pro b/src/proto/option.pro
index 69463d4..1659131 100644
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -69,6 +69,7 @@ char *did_set_showtabline(optset_T *args);
char *did_set_smoothscroll(optset_T *args);
char *did_set_spell(optset_T *args);
char *did_set_swapfile(optset_T *args);
+char *did_set_tabclose(optset_T *args);
char *did_set_termguicolors(optset_T *args);
char *did_set_terse(optset_T *args);
char *did_set_textauto(optset_T *args);
diff --git a/src/proto/optionstr.pro b/src/proto/optionstr.pro
index 340ffc4..39c40f3 100644
--- a/src/proto/optionstr.pro
+++ b/src/proto/optionstr.pro
@@ -156,6 +156,7 @@ char *did_set_swapsync(optset_T *args);
int expand_set_swapsync(optexpand_T *args, int *numMatches, char_u ***matches);
char *did_set_switchbuf(optset_T *args);
int expand_set_switchbuf(optexpand_T *args, int *numMatches, char_u ***matches);
+int expand_set_tabclose(optexpand_T *args, int *numMatches, char_u ***matches);
char *did_set_tabline(optset_T *args);
char *did_set_tagcase(optset_T *args);
int expand_set_tagcase(optexpand_T *args, int *numMatches, char_u ***matches);
diff --git a/src/proto/os_mswin.pro b/src/proto/os_mswin.pro
index 4731010..cde9cea 100644
--- a/src/proto/os_mswin.pro
+++ b/src/proto/os_mswin.pro
@@ -11,6 +11,7 @@ int mch_isFullName(char_u *fname);
void slash_adjust(char_u *p);
char_u *resolve_appexeclink(char_u *fname);
int vim_stat(const char *name, stat_T *stp);
+int vim_lstat(const char *name, stat_T *stp);
void mch_settmode(tmode_T tmode);
int mch_get_shellsize(void);
void mch_set_shellsize(void);
@@ -22,6 +23,7 @@ int mch_has_wildcard(char_u *p);
int mch_chdir(char *path);
int mch_icon_load(HANDLE *iconp);
int mch_libcall(char_u *libname, char_u *funcname, char_u *argstring, int argint, char_u **string_result, int *number_result);
+int mch_get_random(char_u *buf, int len);
void DumpPutS(const char *psz);
int mch_get_winpos(int *x, int *y);
void mch_set_winpos(int x, int y);
diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro
index 6e13de6..d9dc8d9 100644
--- a/src/proto/os_unix.pro
+++ b/src/proto/os_unix.pro
@@ -76,6 +76,7 @@ int mch_rename(const char *src, const char *dest);
int gpm_available(void);
int gpm_enabled(void);
int mch_libcall(char_u *libname, char_u *funcname, char_u *argstring, int argint, char_u **string_result, int *number_result);
+int mch_get_random(char_u *buf, int len);
void setup_term_clip(void);
void start_xterm_trace(int button);
void stop_xterm_trace(void);
diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro
index 1ff9950..11679c6 100644
--- a/src/proto/popupwin.pro
+++ b/src/proto/popupwin.pro
@@ -34,6 +34,7 @@ void f_popup_hide(typval_T *argvars, typval_T *rettv);
void popup_show(win_T *wp);
void f_popup_show(typval_T *argvars, typval_T *rettv);
void f_popup_settext(typval_T *argvars, typval_T *rettv);
+void f_popup_setbuf(typval_T *argvars, typval_T *rettv);
int error_if_popup_window(int also_with_term);
int popup_close(int id, int force);
int popup_close_tabpage(tabpage_T *tp, int id, int force);
diff --git a/src/proto/search.pro b/src/proto/search.pro
index 08526c8..8665994 100644
--- a/src/proto/search.pro
+++ b/src/proto/search.pro
@@ -41,6 +41,7 @@ void f_matchfuzzy(typval_T *argvars, typval_T *rettv);
void f_matchfuzzypos(typval_T *argvars, typval_T *rettv);
int fuzzy_match_str(char_u *str, char_u *pat);
garray_T *fuzzy_match_str_with_pos(char_u *str, char_u *pat);
+int search_for_fuzzy_match(buf_T *buf, pos_T *pos, char_u *pattern, int dir, pos_T *start_pos, int *len, char_u **ptr, int whole_line);
void fuzmatch_str_free(fuzmatch_str_T *fuzmatch, int count);
int fuzzymatches_to_strmatches(fuzmatch_str_T *fuzmatch, char_u ***matches, int count, int funcsort);
/* vim: set ft=c : */
diff --git a/src/proto/sign.pro b/src/proto/sign.pro
index a042bad..1cca0a6 100644
--- a/src/proto/sign.pro
+++ b/src/proto/sign.pro
@@ -8,7 +8,7 @@ int buf_findsigntype_id(buf_T *buf, linenr_T lnum, int typenr);
int buf_signcount(buf_T *buf, linenr_T lnum);
void buf_delete_signs(buf_T *buf, char_u *group);
void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after);
-int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl, char_u *numhl);
+int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl, char_u *numhl, int prio);
int sign_exists_by_name(char_u *name);
int sign_undefine_by_name(char_u *name, int give_error);
int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio);
diff --git a/src/proto/tag.pro b/src/proto/tag.pro
index 6de463e..eec7c24 100644
--- a/src/proto/tag.pro
+++ b/src/proto/tag.pro
@@ -14,4 +14,5 @@ int expand_tags(int tagnames, char_u *pat, int *num_file, char_u ***file);
int get_tags(list_T *list, char_u *pat, char_u *buf_fname);
void get_tagstack(win_T *wp, dict_T *retdict);
int set_tagstack(win_T *wp, dict_T *d, int action);
+void tagstack_clear_entry(taggy_T *item);
/* vim: set ft=c : */
diff --git a/src/proto/typval.pro b/src/proto/typval.pro
index b6ea131..1edfeb4 100644
--- a/src/proto/typval.pro
+++ b/src/proto/typval.pro
@@ -68,14 +68,13 @@ int typval_compare(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic);
int typval_compare_list(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res);
int typval_compare_null(typval_T *tv1, typval_T *tv2);
int typval_compare_blob(typval_T *tv1, typval_T *tv2, exprtype_T type, int *res);
-int typval_compare_class(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res);
int typval_compare_object(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res);
int typval_compare_dict(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res);
int typval_compare_func(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res);
int typval_compare_string(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res);
char_u *typval_tostring(typval_T *arg, int quotes);
int tv_islocked(typval_T *tv);
-int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
+int tv_equal(typval_T *tv1, typval_T *tv2, int ic);
int eval_option(char_u **arg, typval_T *rettv, int evaluate);
int eval_number(char_u **arg, typval_T *rettv, int evaluate, int want_string);
int eval_string(char_u **arg, typval_T *rettv, int evaluate, int interpolate);
diff --git a/src/proto/userfunc.pro b/src/proto/userfunc.pro
index 9bb4616..32dac66 100644
--- a/src/proto/userfunc.pro
+++ b/src/proto/userfunc.pro
@@ -39,7 +39,7 @@ int call_callback(callback_T *callback, int len, typval_T *rettv, int argcount,
varnumber_T call_callback_retnr(callback_T *callback, int argcount, typval_T *argvars);
void user_func_error(funcerror_T error, char_u *name, int found_var);
int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in, funcexe_T *funcexe);
-int call_simple_func(char_u *funcname, int len, typval_T *rettv);
+int call_simple_func(char_u *funcname, size_t len, typval_T *rettv);
char_u *printable_func_name(ufunc_T *fp);
char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags);
char_u *trans_function_name_ext(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial, type_T **type, ufunc_T **ufunc);
@@ -95,4 +95,5 @@ int set_ref_in_call_stack(int copyID);
int set_ref_in_functions(int copyID);
int set_ref_in_func_args(int copyID);
int set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID);
+int get_func_arity(char_u *name, int *required, int *optional, int *varargs);
/* vim: set ft=c : */
diff --git a/src/proto/vim9class.pro b/src/proto/vim9class.pro
index 1b5800c..c87fffb 100644
--- a/src/proto/vim9class.pro
+++ b/src/proto/vim9class.pro
@@ -40,6 +40,7 @@ int is_class_name(char_u *name, typval_T *rettv);
void protected_method_access_errmsg(char_u *method_name);
int object_empty(object_T *obj);
int object_len(object_T *obj);
+int object_equal(object_T *o1, object_T *o2, int ic);
char_u *object2string(object_T *obj, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int composite_val);
int class_instance_of(class_T *cl, class_T *other_cl);
void f_instanceof(typval_T *argvars, typval_T *rettv);
diff --git a/src/proto/vim9instr.pro b/src/proto/vim9instr.pro
index 1b2f79c..8ee33b8 100644
--- a/src/proto/vim9instr.pro
+++ b/src/proto/vim9instr.pro
@@ -58,7 +58,7 @@ int check_internal_func_args(cctx_T *cctx, int func_idx, int argcount, int metho
int generate_BCALL(cctx_T *cctx, int func_idx, int argcount, int method_call);
int generate_LISTAPPEND(cctx_T *cctx);
int generate_BLOBAPPEND(cctx_T *cctx);
-int generate_CALL(cctx_T *cctx, ufunc_T *ufunc, class_T *cl, int mi, int pushed_argcount);
+int generate_CALL(cctx_T *cctx, ufunc_T *ufunc, class_T *cl, int mi, int pushed_argcount, int is_super);
int generate_UCALL(cctx_T *cctx, char_u *name, int argcount);
int check_func_args_from_type(cctx_T *cctx, type_T *type, int argcount, int at_top, char_u *name);
int generate_PCALL(cctx_T *cctx, int argcount, char_u *name, type_T *type, int at_top);
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 26c7040..441070e 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -100,4 +100,5 @@ int get_win_number(win_T *wp, win_T *first_win);
int get_tab_number(tabpage_T *tp);
char *check_colorcolumn(win_T *wp);
int get_last_winid(void);
+int win_locked(win_T *wp);
/* vim: set ft=c : */
diff --git a/src/regexp.c b/src/regexp.c
index ff201d9..b020a43 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -1729,7 +1729,9 @@ mb_decompose(int c, int *c1, int *c2, int *c3)
/*
* Compare two strings, ignore case if rex.reg_ic set.
* Return 0 if strings match, non-zero otherwise.
- * Correct the length "*n" when composing characters are ignored.
+ * Correct the length "*n" when composing characters are ignored
+ * or for utf8 when both utf codepoints are considered equal because of
+ * case-folding but have different length (e.g. 's' and 'Å¿')
*/
static int
cstrncmp(char_u *s1, char_u *s2, int *n)
@@ -1738,6 +1740,29 @@ cstrncmp(char_u *s1, char_u *s2, int *n)
if (!rex.reg_ic)
result = STRNCMP(s1, s2, *n);
+ else if (enc_utf8)
+ {
+ char_u *p = s1;
+ int n2 = 0;
+ int n1 = *n;
+ // count the number of characters for byte-length of s1
+ while (n1 > 0 && *p != NUL)
+ {
+ n1 -= mb_ptr2len(s1);
+ MB_PTR_ADV(p);
+ n2++;
+ }
+ // count the number of bytes to advance the same number of chars for s2
+ p = s2;
+ while (n2-- > 0 && *p != NUL)
+ MB_PTR_ADV(p);
+
+ n2 = p - s2;
+
+ result = MB_STRNICMP2(s1, s2, *n, n2);
+ if (result == 0 && n2 < *n)
+ *n = n2;
+ }
else
result = MB_STRNICMP(s1, s2, *n);
@@ -1787,7 +1812,7 @@ cstrncmp(char_u *s1, char_u *s2, int *n)
cstrchr(char_u *s, int c)
{
char_u *p;
- int cc;
+ int cc, lc;
if (!rex.reg_ic || (!enc_utf8 && mb_char2len(c) > 1))
return vim_strchr(s, c);
@@ -1796,26 +1821,35 @@ cstrchr(char_u *s, int c)
// faster (esp. when using MS Visual C++!).
// For UTF-8 need to use folded case.
if (enc_utf8 && c > 0x80)
+ {
cc = utf_fold(c);
+ lc = cc;
+ }
else
- if (MB_ISUPPER(c))
- cc = MB_TOLOWER(c);
- else if (MB_ISLOWER(c))
- cc = MB_TOUPPER(c);
- else
- return vim_strchr(s, c);
+ if (MB_ISUPPER(c))
+ {
+ cc = MB_TOLOWER(c);
+ lc = cc;
+ }
+ else if (MB_ISLOWER(c))
+ {
+ cc = MB_TOUPPER(c);
+ lc = c;
+ }
+ else
+ return vim_strchr(s, c);
if (has_mbyte)
{
for (p = s; *p != NUL; p += (*mb_ptr2len)(p))
{
- if (enc_utf8 && c > 0x80)
+ int uc = utf_ptr2char(p);
+ if (enc_utf8 && (c > 0x80 || uc > 0x80))
{
- int uc = utf_ptr2char(p);
-
// Do not match an illegal byte. E.g. 0xff matches 0xc3 0xbf,
// not 0xff.
- if ((uc < 0x80 || uc != *p) && utf_fold(uc) == cc)
+ // compare with lower case of the character
+ if ((uc < 0x80 || uc != *p) && utf_fold(uc) == lc)
return p;
}
else if (*p == c || *p == cc)
diff --git a/src/regexp_bt.c b/src/regexp_bt.c
index 5452dda..16dac73 100644
--- a/src/regexp_bt.c
+++ b/src/regexp_bt.c
@@ -3823,6 +3823,14 @@ regmatch(
}
}
}
+ else if (enc_utf8)
+ {
+ if (cstrncmp(opnd, rex.input, &len) != 0)
+ {
+ status = RA_NOMATCH;
+ break;
+ }
+ }
else
for (i = 0; i < len; ++i)
if (opnd[i] != rex.input[i])
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
index 4f07a21..6db4134 100644
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -5666,7 +5666,12 @@ find_match_text(colnr_T *startcol, int regstart, char_u *match_text)
for (;;)
{
match = TRUE;
- len2 = MB_CHAR2LEN(regstart); // skip regstart
+ // skip regstart
+ len2 = MB_CHAR2LEN(regstart);
+ if (enc_utf8 && len2 > 1 && MB_CHAR2LEN(PTR2CHAR(rex.line + col)) != len2)
+ // because of case-folding of the previously matched text, we may need
+ // to skip fewer bytes than mb_char2len(regstart)
+ len2 = mb_char2len(utf_fold(regstart));
for (len1 = 0; match_text[len1] != NUL; len1 += MB_CHAR2LEN(c1))
{
c1 = PTR2CHAR(match_text + len1);
@@ -7502,7 +7507,7 @@ nfa_regexec_both(
// If match_text is set it contains the full text that must match.
// Nothing else to try. Doesn't handle combining chars well.
- if (prog->match_text != NULL && !rex.reg_icombine)
+ if (prog->match_text != NULL && *prog->match_text != NUL && !rex.reg_icombine)
{
retval = find_match_text(&col, prog->regstart, prog->match_text);
if (REG_MULTI)
diff --git a/src/search.c b/src/search.c
index 0b39d90..e5936d8 100644
--- a/src/search.c
+++ b/src/search.c
@@ -53,6 +53,7 @@ static int fuzzy_match_str_compare(const void *s1, const void *s2);
static void fuzzy_match_str_sort(fuzmatch_str_T *fm, int sz);
static int fuzzy_match_func_compare(const void *s1, const void *s2);
static void fuzzy_match_func_sort(fuzmatch_str_T *fm, int sz);
+static int fuzzy_match_str_in_line(char_u **ptr, char_u *pat, int *len, pos_T *current_pos);
#define SEARCH_STAT_DEF_TIMEOUT 40L
#define SEARCH_STAT_DEF_MAX_COUNT 99
@@ -1547,6 +1548,7 @@ do_search(
{
vim_free(msgbuf);
msgbuf = r;
+ msgbuflen = STRLEN(msgbuf);
// move reversed text to beginning of buffer
while (*r != NUL && *r == ' ')
r++;
@@ -5106,11 +5108,11 @@ fuzzy_match_str_with_pos(char_u *str UNUSED, char_u *pat UNUSED)
int j = 0;
if (str == NULL || pat == NULL)
- return NULL;
+ return NULL;
match_positions = ALLOC_ONE(garray_T);
if (match_positions == NULL)
- return NULL;
+ return NULL;
ga_init2(match_positions, sizeof(int_u), 10);
if (!fuzzy_match(str, pat, FALSE, &score, matches, MAX_FUZZY_MATCHES)
@@ -5140,6 +5142,172 @@ fuzzy_match_str_with_pos(char_u *str UNUSED, char_u *pat UNUSED)
}
/*
+ * This function searches for a fuzzy match of the pattern `pat` within the
+ * line pointed to by `*ptr`. It splits the line into words, performs fuzzy
+ * matching on each word, and returns the length and position of the first
+ * matched word.
+ */
+ static int
+fuzzy_match_str_in_line(char_u **ptr, char_u *pat, int *len, pos_T *current_pos)
+{
+ char_u *str = *ptr;
+ char_u *strBegin = str;
+ char_u *end = NULL;
+ char_u *start = NULL;
+ int found = FALSE;
+ int result;
+ char save_end;
+
+ if (str == NULL || pat == NULL)
+ return found;
+
+ while (*str != NUL)
+ {
+ // Skip non-word characters
+ start = find_word_start(str);
+ if (*start == NUL)
+ break;
+ end = find_word_end(start);
+
+ // Extract the word from start to end
+ save_end = *end;
+ *end = NUL;
+
+ // Perform fuzzy match
+ result = fuzzy_match_str(start, pat);
+ *end = save_end;
+
+ if (result > 0)
+ {
+ *len = (int)(end - start);
+ current_pos->col += (int)(end - strBegin);
+ found = TRUE;
+ *ptr = start;
+ break;
+ }
+
+ // Move to the end of the current word for the next iteration
+ str = end;
+ // Ensure we continue searching after the current word
+ while (*str != NUL && !vim_iswordp(str))
+ MB_PTR_ADV(str);
+ }
+
+ return found;
+}
+
+/*
+ * Search for the next fuzzy match in the specified buffer.
+ * This function attempts to find the next occurrence of the given pattern
+ * in the buffer, starting from the current position. It handles line wrapping
+ * and direction of search.
+ *
+ * Return TRUE if a match is found, otherwise FALSE.
+ */
+ int
+search_for_fuzzy_match(
+ buf_T *buf,
+ pos_T *pos,
+ char_u *pattern,
+ int dir,
+ pos_T *start_pos,
+ int *len,
+ char_u **ptr,
+ int whole_line)
+{
+ pos_T current_pos = *pos;
+ pos_T circly_end;
+ int found_new_match = FAIL;
+ int looped_around = FALSE;
+
+ if (whole_line)
+ current_pos.lnum += dir;
+
+ if (buf == curbuf)
+ circly_end = *start_pos;
+ else
+ {
+ circly_end.lnum = buf->b_ml.ml_line_count;
+ circly_end.col = 0;
+ circly_end.coladd = 0;
+ }
+
+ do {
+
+ // Check if looped around and back to start position
+ if (looped_around && EQUAL_POS(current_pos, circly_end))
+ break;
+
+ // Ensure current_pos is valid
+ if (current_pos.lnum >= 1 && current_pos.lnum <= buf->b_ml.ml_line_count)
+ {
+ // Get the current line buffer
+ *ptr = ml_get_buf(buf, current_pos.lnum, FALSE);
+ // If ptr is end of line is reached, move to next line
+ // or previous line based on direction
+ if (**ptr != NUL)
+ {
+ if (!whole_line)
+ {
+ *ptr += current_pos.col;
+ // Try to find a fuzzy match in the current line starting from current position
+ found_new_match = fuzzy_match_str_in_line(ptr, pattern, len, &current_pos);
+ if (found_new_match)
+ {
+ *pos = current_pos;
+ break;
+ }
+ else if (looped_around && current_pos.lnum == circly_end.lnum)
+ break;
+ }
+ else
+ {
+ if (fuzzy_match_str(*ptr, pattern) > 0)
+ {
+ found_new_match = TRUE;
+ *pos = current_pos;
+ *len = (int)STRLEN(*ptr);
+ break;
+ }
+ }
+ }
+ }
+
+ // Move to the next line or previous line based on direction
+ if (dir == FORWARD)
+ {
+ if (++current_pos.lnum > buf->b_ml.ml_line_count)
+ {
+ if (p_ws)
+ {
+ current_pos.lnum = 1;
+ looped_around = TRUE;
+ }
+ else
+ break;
+ }
+ }
+ else
+ {
+ if (--current_pos.lnum < 1)
+ {
+ if (p_ws)
+ {
+ current_pos.lnum = buf->b_ml.ml_line_count;
+ looped_around = TRUE;
+ }
+ else
+ break;
+
+ }
+ }
+ current_pos.col = 0;
+ } while (TRUE);
+
+ return found_new_match;
+}
+
+/*
* Free an array of fuzzy string matches "fuzmatch[count]".
*/
void
diff --git a/src/sign.c b/src/sign.c
index 8aa043b..b1f496c 100644
--- a/src/sign.c
+++ b/src/sign.c
@@ -34,6 +34,7 @@ struct sign
int sn_text_hl; // highlight ID for text
int sn_cul_hl; // highlight ID for text on current line when 'cursorline' is set
int sn_num_hl; // highlight ID for line number
+ int sn_priority; // default priority of this sign, -1 means SIGN_DEF_PRIO
};
static sign_T *first_sign = NULL;
@@ -1047,7 +1048,8 @@ sign_define_by_name(
char_u *text,
char_u *texthl,
char_u *culhl,
- char_u *numhl)
+ char_u *numhl,
+ int prio)
{
sign_T *sp_prev;
sign_T *sp;
@@ -1083,6 +1085,8 @@ sign_define_by_name(
if (text != NULL && (sign_define_init_text(sp, text) == FAIL))
return FAIL;
+ sp->sn_priority = prio;
+
if (linehl != NULL)
{
if (*linehl == NUL)
@@ -1206,6 +1210,10 @@ sign_place(
if (*sign_id == 0)
*sign_id = sign_group_get_next_signid(buf, sign_group);
+ // Use the default priority value for this sign.
+ if (prio == -1)
+ prio = (sp->sn_priority != -1) ? sp->sn_priority : SIGN_DEF_PRIO;
+
if (lnum > 0)
// ":sign place {id} line={lnum} name={name} file={fname}":
// place a sign
@@ -1338,6 +1346,7 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
char_u *texthl = NULL;
char_u *culhl = NULL;
char_u *numhl = NULL;
+ int prio = -1;
int failed = FALSE;
// set values for a defined sign.
@@ -1377,6 +1386,11 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
arg += 6;
numhl = vim_strnsave(arg, p - arg);
}
+ else if (STRNCMP(arg, "priority=", 9) == 0)
+ {
+ arg += 9;
+ prio = atoi((char *)arg);
+ }
else
{
semsg(_(e_invalid_argument_str), arg);
@@ -1386,7 +1400,7 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
}
if (!failed)
- sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, numhl);
+ sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, numhl, prio);
vim_free(icon);
vim_free(text);
@@ -1721,7 +1735,7 @@ ex_sign(exarg_T *eap)
linenr_T lnum = -1;
char_u *sign_name = NULL;
char_u *group = NULL;
- int prio = SIGN_DEF_PRIO;
+ int prio = -1;
// Parse command line arguments
if (parse_sign_cmd_args(idx, arg, &sign_name, &id, &group, &prio,
@@ -1750,6 +1764,8 @@ sign_getinfo(sign_T *sp, dict_T *retdict)
dict_add_string(retdict, "icon", sp->sn_icon);
if (sp->sn_text != NULL)
dict_add_string(retdict, "text", sp->sn_text);
+ if (sp->sn_priority > 0)
+ dict_add_number(retdict, "priority", sp->sn_priority);
if (sp->sn_line_hl > 0)
{
p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE);
@@ -1913,6 +1929,7 @@ sign_gui_started(void)
sign_list_defined(sign_T *sp)
{
char_u *p;
+ char lbuf[MSG_BUF_LEN];
smsg("sign %s", sp->sn_name);
if (sp->sn_icon != NULL)
@@ -1931,6 +1948,11 @@ sign_list_defined(sign_T *sp)
msg_puts(" text=");
msg_outtrans(sp->sn_text);
}
+ if (sp->sn_priority > 0)
+ {
+ vim_snprintf(lbuf, MSG_BUF_LEN, " priority=%d", sp->sn_priority);
+ msg_puts(lbuf);
+ }
if (sp->sn_line_hl > 0)
{
msg_puts(" linehl=");
@@ -2088,7 +2110,8 @@ get_sign_name(expand_T *xp UNUSED, int idx)
{
char *define_arg[] =
{
- "culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=", NULL
+ "culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=", "priority=",
+ NULL
};
return (char_u *)define_arg[idx];
}
@@ -2261,6 +2284,7 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict)
char_u *texthl = NULL;
char_u *culhl = NULL;
char_u *numhl = NULL;
+ int prio = -1;
int retval = -1;
if (name_arg == NULL)
@@ -2281,9 +2305,10 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict)
texthl = dict_get_string(dict, "texthl", TRUE);
culhl = dict_get_string(dict, "culhl", TRUE);
numhl = dict_get_string(dict, "numhl", TRUE);
+ prio = dict_get_number_def(dict, "priority", -1);
}
- if (sign_define_by_name(name, icon, linehl, text, texthl, culhl, numhl) == OK)
+ if (sign_define_by_name(name, icon, linehl, text, texthl, culhl, numhl, prio) == OK)
retval = 0;
cleanup:
@@ -2511,7 +2536,7 @@ sign_place_from_dict(
buf_T *buf = NULL;
dictitem_T *di;
linenr_T lnum = 0;
- int prio = SIGN_DEF_PRIO;
+ int prio = -1;
int notanum = FALSE;
int ret_sign_id = -1;
diff --git a/src/spellfile.c b/src/spellfile.c
index 51261ab..0b9536d 100644
--- a/src/spellfile.c
+++ b/src/spellfile.c
@@ -6434,7 +6434,13 @@ init_spellfile(void)
l = (int)STRLEN(buf);
vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
if (filewritable(buf) != 2)
- vim_mkdir(buf, 0755);
+ {
+ if (vim_mkdir(buf, 0755) != 0)
+ {
+ vim_free(buf);
+ return;
+ }
+ }
l = (int)STRLEN(buf);
vim_snprintf((char *)buf + l, MAXPATHL - l,
diff --git a/src/strings.c b/src/strings.c
index 6b2ff0a..b8ea00b 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -1037,7 +1037,7 @@ string_reduce(
* Implementation of "byteidx()" and "byteidxcomp()" functions
*/
static void
-byteidx_common(typval_T *argvars, typval_T *rettv, int comp UNUSED)
+byteidx_common(typval_T *argvars, typval_T *rettv, int comp)
{
rettv->vval.v_number = -1;
@@ -2497,7 +2497,8 @@ format_overflow_error(const char *pstart)
get_unsigned_int(
const char *pstart,
const char **p,
- unsigned int *uj)
+ unsigned int *uj,
+ int overflow_err)
{
*uj = **p - '0';
++*p;
@@ -2510,8 +2511,13 @@ get_unsigned_int(
if (*uj > MAX_ALLOWED_STRING_WIDTH)
{
- format_overflow_error(pstart);
- return FAIL;
+ if (overflow_err)
+ {
+ format_overflow_error(pstart);
+ return FAIL;
+ }
+ else
+ *uj = MAX_ALLOWED_STRING_WIDTH;
}
return OK;
@@ -2584,7 +2590,7 @@ parse_fmt_types(
// Positional argument
unsigned int uj;
- if (get_unsigned_int(pstart, &p, &uj) == FAIL)
+ if (get_unsigned_int(pstart, &p, &uj, tvs != NULL) == FAIL)
goto error;
pos_arg = uj;
@@ -2625,7 +2631,7 @@ parse_fmt_types(
// Positional argument field width
unsigned int uj;
- if (get_unsigned_int(arg + 1, &p, &uj) == FAIL)
+ if (get_unsigned_int(arg + 1, &p, &uj, tvs != NULL) == FAIL)
goto error;
if (*p != '$')
@@ -2656,7 +2662,7 @@ parse_fmt_types(
const char *digstart = p;
unsigned int uj;
- if (get_unsigned_int(digstart, &p, &uj) == FAIL)
+ if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL)
goto error;
if (*p == '$')
@@ -2680,7 +2686,7 @@ parse_fmt_types(
// Parse precision
unsigned int uj;
- if (get_unsigned_int(arg + 1, &p, &uj) == FAIL)
+ if (get_unsigned_int(arg + 1, &p, &uj, tvs != NULL) == FAIL)
goto error;
if (*p == '$')
@@ -2712,7 +2718,7 @@ parse_fmt_types(
const char *digstart = p;
unsigned int uj;
- if (get_unsigned_int(digstart, &p, &uj) == FAIL)
+ if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL)
goto error;
if (*p == '$')
@@ -3025,7 +3031,7 @@ vim_vsnprintf_typval(
const char *digstart = p;
unsigned int uj;
- if (get_unsigned_int(digstart, &p, &uj) == FAIL)
+ if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL)
goto error;
pos_arg = uj;
@@ -3067,7 +3073,7 @@ vim_vsnprintf_typval(
// Positional argument field width
unsigned int uj;
- if (get_unsigned_int(digstart, &p, &uj) == FAIL)
+ if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL)
goto error;
arg_idx = uj;
@@ -3085,8 +3091,13 @@ vim_vsnprintf_typval(
if (j > MAX_ALLOWED_STRING_WIDTH)
{
- format_overflow_error(digstart);
- goto error;
+ if (tvs != NULL)
+ {
+ format_overflow_error(digstart);
+ goto error;
+ }
+ else
+ j = MAX_ALLOWED_STRING_WIDTH;
}
if (j >= 0)
@@ -3104,14 +3115,8 @@ vim_vsnprintf_typval(
const char *digstart = p;
unsigned int uj;
- if (get_unsigned_int(digstart, &p, &uj) == FAIL)
- goto error;
-
- if (uj > MAX_ALLOWED_STRING_WIDTH)
- {
- format_overflow_error(digstart);
+ if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL)
goto error;
- }
min_field_width = uj;
}
@@ -3129,15 +3134,9 @@ vim_vsnprintf_typval(
const char *digstart = p;
unsigned int uj;
- if (get_unsigned_int(digstart, &p, &uj) == FAIL)
+ if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL)
goto error;
- if (uj > MAX_ALLOWED_STRING_WIDTH)
- {
- format_overflow_error(digstart);
- goto error;
- }
-
precision = uj;
}
else if (*p == '*')
@@ -3152,7 +3151,7 @@ vim_vsnprintf_typval(
// positional argument
unsigned int uj;
- if (get_unsigned_int(digstart, &p, &uj) == FAIL)
+ if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL)
goto error;
arg_idx = uj;
@@ -3170,8 +3169,13 @@ vim_vsnprintf_typval(
if (j > MAX_ALLOWED_STRING_WIDTH)
{
- format_overflow_error(digstart);
- goto error;
+ if (tvs != NULL)
+ {
+ format_overflow_error(digstart);
+ goto error;
+ }
+ else
+ j = MAX_ALLOWED_STRING_WIDTH;
}
if (j >= 0)
diff --git a/src/structs.h b/src/structs.h
index 7e21f0f..79f415d 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1309,6 +1309,9 @@ typedef struct mapblock mapblock_T;
struct mapblock
{
mapblock_T *m_next; // next mapblock in list
+ mapblock_T *m_alt; // pointer to mapblock of the same mapping
+ // with an alternative form of m_keys, or NULL
+ // if there is no such mapblock
char_u *m_keys; // mapped from, lhs
char_u *m_str; // mapped to, rhs
char_u *m_orig_str; // rhs as entered by the user
@@ -3782,8 +3785,7 @@ struct window_S
synblock_T *w_s; // for :ownsyntax
#endif
- int w_closing; // window is being closed, don't let
- // autocommands close it too.
+ int w_locked; // don't let autocommands close the window
frame_T *w_frame; // frame containing this window
@@ -4466,12 +4468,14 @@ typedef struct
*/
typedef struct
{
- char_u *pum_text; // main menu text
- char_u *pum_kind; // extra kind text (may be truncated)
- char_u *pum_extra; // extra menu text (may be truncated)
- char_u *pum_info; // extra info
- int pum_score; // fuzzy match score
- int pum_idx; // index of item before sorting by score
+ char_u *pum_text; // main menu text
+ char_u *pum_kind; // extra kind text (may be truncated)
+ char_u *pum_extra; // extra menu text (may be truncated)
+ char_u *pum_info; // extra info
+ int pum_score; // fuzzy match score
+ int pum_idx; // index of item before sorting by score
+ int pum_user_hlattr; // highlight attribute to combine with
+ int pum_user_kind_hlattr; // highlight attribute for kind
} pumitem_T;
/*
@@ -4902,7 +4906,8 @@ typedef enum {
WT_MEMBER,
WT_METHOD, // object method
WT_METHOD_ARG, // object method argument type
- WT_METHOD_RETURN // object method return type
+ WT_METHOD_RETURN, // object method return type
+ WT_CAST, // type cast
} wherekind_T;
// Struct used to pass the location of a type check. Used in error messages to
diff --git a/src/syntax.c b/src/syntax.c
index 48e7152..eec5799 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -15,8 +15,6 @@
#if defined(FEAT_SYN_HL) || defined(PROTO)
-#define SYN_NAMELEN 50 // maximum length of a syntax name
-
// different types of offsets that are possible
#define SPO_MS_OFF 0 // match start offset
#define SPO_ME_OFF 1 // match end offset
@@ -323,6 +321,7 @@ static void limit_pos_zero(lpos_T *pos, lpos_T *limit);
static void syn_add_end_off(lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, int extra);
static void syn_add_start_off(lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, int extra);
static char_u *syn_getcurline(void);
+static colnr_T syn_getcurline_len(void);
static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T *st);
static int check_keyword_id(char_u *line, int startcol, int *endcol, long *flags, short **next_list, stateitem_T *cur_si, int *ccharp);
static void syn_remove_pattern(synblock_T *block, int idx);
@@ -2692,7 +2691,7 @@ update_si_end(
// a "oneline" never continues in the next line
sip->si_ends = TRUE;
sip->si_m_endpos.lnum = current_lnum;
- sip->si_m_endpos.col = (colnr_T)STRLEN(syn_getcurline());
+ sip->si_m_endpos.col = syn_getcurline_len();
}
else
{
@@ -3130,6 +3129,15 @@ syn_getcurline(void)
}
/*
+ * Get length of current line in syntax buffer.
+ */
+ static colnr_T
+syn_getcurline_len(void)
+{
+ return ml_get_buf_len(syn_buf, current_lnum);
+}
+
+/*
* Call vim_regexec() to find a match with "rmp" in "syn_buf".
* Returns TRUE when there is a match.
*/
@@ -3935,13 +3943,7 @@ syn_match_msg(void)
static int last_matchgroup;
-struct name_list
-{
- int flag;
- char *name;
-};
-
-static void syn_list_flags(struct name_list *nl, int flags, int attr);
+static void syn_list_flags(keyvalue_T *nlist, int nr_entries, int flags, int attr);
/*
* List one syntax item, for ":syntax" or "syntax list syntax_name".
@@ -3956,28 +3958,27 @@ syn_list_one(
int idx;
int did_header = FALSE;
synpat_T *spp;
- static struct name_list namelist1[] =
+ static keyvalue_T namelist1[] =
{
- {HL_DISPLAY, "display"},
- {HL_CONTAINED, "contained"},
- {HL_ONELINE, "oneline"},
- {HL_KEEPEND, "keepend"},
- {HL_EXTEND, "extend"},
- {HL_EXCLUDENL, "excludenl"},
- {HL_TRANSP, "transparent"},
- {HL_FOLD, "fold"},
+ KEYVALUE_ENTRY(HL_DISPLAY, "display"),
+ KEYVALUE_ENTRY(HL_CONTAINED, "contained"),
+ KEYVALUE_ENTRY(HL_ONELINE, "oneline"),
+ KEYVALUE_ENTRY(HL_KEEPEND, "keepend"),
+ KEYVALUE_ENTRY(HL_EXTEND, "extend"),
+ KEYVALUE_ENTRY(HL_EXCLUDENL, "excludenl"),
+ KEYVALUE_ENTRY(HL_TRANSP, "transparent"),
+ KEYVALUE_ENTRY(HL_FOLD, "fold")
#ifdef FEAT_CONCEAL
- {HL_CONCEAL, "conceal"},
- {HL_CONCEALENDS, "concealends"},
+ ,
+ KEYVALUE_ENTRY(HL_CONCEAL, "conceal"),
+ KEYVALUE_ENTRY(HL_CONCEALENDS, "concealends")
#endif
- {0, NULL}
};
- static struct name_list namelist2[] =
+ static keyvalue_T namelist2[] =
{
- {HL_SKIPWHITE, "skipwhite"},
- {HL_SKIPNL, "skipnl"},
- {HL_SKIPEMPTY, "skipempty"},
- {0, NULL}
+ KEYVALUE_ENTRY(HL_SKIPWHITE, "skipwhite"),
+ KEYVALUE_ENTRY(HL_SKIPNL, "skipnl"),
+ KEYVALUE_ENTRY(HL_SKIPEMPTY, "skipempty")
};
attr = HL_ATTR(HLF_D); // highlight like directories
@@ -4017,7 +4018,7 @@ syn_list_one(
--idx;
msg_putchar(' ');
}
- syn_list_flags(namelist1, spp->sp_flags, attr);
+ syn_list_flags(namelist1, (int)ARRAY_LENGTH(namelist1), spp->sp_flags, attr);
if (spp->sp_cont_list != NULL)
put_id_list((char_u *)"contains", spp->sp_cont_list, attr);
@@ -4029,7 +4030,7 @@ syn_list_one(
if (spp->sp_next_list != NULL)
{
put_id_list((char_u *)"nextgroup", spp->sp_next_list, attr);
- syn_list_flags(namelist2, spp->sp_flags, attr);
+ syn_list_flags(namelist2, (int)ARRAY_LENGTH(namelist2), spp->sp_flags, attr);
}
if (spp->sp_flags & (HL_SYNC_HERE|HL_SYNC_THERE))
{
@@ -4058,14 +4059,14 @@ syn_list_one(
}
static void
-syn_list_flags(struct name_list *nlist, int flags, int attr)
+syn_list_flags(keyvalue_T *nlist, int nr_entries, int flags, int attr)
{
int i;
- for (i = 0; nlist[i].flag != 0; ++i)
- if (flags & nlist[i].flag)
+ for (i = 0; i < nr_entries; ++i)
+ if (flags & nlist[i].key)
{
- msg_puts_attr(nlist[i].name, attr);
+ msg_puts_attr(nlist[i].value, attr);
msg_putchar(' ');
}
}
@@ -4084,8 +4085,8 @@ syn_list_cluster(int id)
if (msg_col >= endcol) // output at least one space
endcol = msg_col + 1;
- if (Columns <= endcol) // avoid hang for tiny window
- endcol = Columns - 1;
+ if (Columns <= (long)endcol) // avoid hang for tiny window
+ endcol = (int)(Columns - 1);
msg_advance(endcol);
if (SYN_CLSTR(curwin->w_s)[id].scl_list != NULL)
@@ -4393,6 +4394,7 @@ clear_keywtab(hashtab_T *ht)
static void
add_keyword(
char_u *name, // name of keyword
+ size_t namelen, // length of keyword (excluding the NUL)
int id, // group ID for this keyword
int flags, // flags for this keyword
short *cont_in_list, // containedin for this keyword
@@ -4403,15 +4405,22 @@ add_keyword(
hashtab_T *ht;
hashitem_T *hi;
char_u *name_ic;
+ size_t name_iclen;
long_u hash;
char_u name_folded[MAXKEYWLEN + 1];
if (curwin->w_s->b_syn_ic)
- name_ic = str_foldcase(name, (int)STRLEN(name),
+ {
+ name_ic = str_foldcase(name, (int)namelen,
name_folded, MAXKEYWLEN + 1);
+ name_iclen = STRLEN(name_ic);
+ }
else
+ {
name_ic = name;
- kp = alloc(offsetof(keyentry_T, keyword) + STRLEN(name_ic) + 1);
+ name_iclen = namelen;
+ }
+ kp = alloc(offsetof(keyentry_T, keyword) + name_iclen + 1);
if (kp == NULL)
return;
STRCPY(kp->keyword, name_ic);
@@ -4828,19 +4837,26 @@ syn_cmd_keyword(exarg_T *eap, int syncing UNUSED)
if (!eap->skip)
{
+ size_t kwlen = 0;
+
// Adjust flags for use of ":syn include".
syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
/*
* 2: Add an entry for each keyword.
*/
- for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1)
+ for (kw = keyword_copy; --cnt >= 0; kw += kwlen + 1)
{
for (p = vim_strchr(kw, '['); ; )
{
- if (p != NULL)
+ if (p == NULL)
+ kwlen = STRLEN(kw);
+ else
+ {
*p = NUL;
- add_keyword(kw, syn_id, syn_opt_arg.flags,
+ kwlen = (size_t)(p - kw);
+ }
+ add_keyword(kw, kwlen, syn_id, syn_opt_arg.flags,
syn_opt_arg.cont_in_list,
syn_opt_arg.next_list, conceal_char);
if (p == NULL)
@@ -4859,6 +4875,7 @@ syn_cmd_keyword(exarg_T *eap, int syncing UNUSED)
goto error;
}
kw = p + 1; // skip over the "]"
+ kwlen = 1;
break;
}
if (has_mbyte)
@@ -6229,8 +6246,7 @@ static struct subcommand subcommands[] =
{"reset", syn_cmd_reset},
{"spell", syn_cmd_spell},
{"sync", syn_cmd_sync},
- {"", syn_cmd_list},
- {NULL, NULL}
+ {"", syn_cmd_list}
};
/*
@@ -6257,13 +6273,8 @@ ex_syntax(exarg_T *eap)
if (eap->skip) // skip error messages for all subcommands
++emsg_skip;
- for (i = 0; ; ++i)
+ for (i = 0; i < (int)ARRAY_LENGTH(subcommands); ++i)
{
- if (subcommands[i].name == NULL)
- {
- semsg(_(e_invalid_syntax_subcommand_str), subcmd_name);
- break;
- }
if (STRCMP(subcmd_name, (char_u *)subcommands[i].name) == 0)
{
eap->arg = skipwhite(subcmd_end);
@@ -6271,6 +6282,10 @@ ex_syntax(exarg_T *eap)
break;
}
}
+
+ if (i == (int)ARRAY_LENGTH(subcommands))
+ semsg(_(e_invalid_syntax_subcommand_str), subcmd_name);
+
vim_free(subcmd_name);
if (eap->skip)
--emsg_skip;
@@ -6424,6 +6439,8 @@ get_syntax_name(expand_T *xp, int idx)
switch (expand_what)
{
case EXP_SUBCMD:
+ if (idx < 0 || idx >= (int)ARRAY_LENGTH(subcommands))
+ return NULL;
return (char_u *)subcommands[idx].name;
case EXP_CASE:
{
@@ -6697,6 +6714,7 @@ syntime_report(void)
proftime_T tm;
# endif
int len;
+ int patlen;
proftime_T total_total;
int total_count = 0;
garray_T ga;
@@ -6768,8 +6786,9 @@ syntime_report(void)
len = 20; // will wrap anyway
else
len = Columns - 70;
- if (len > (int)STRLEN(p->pattern))
- len = (int)STRLEN(p->pattern);
+ patlen = (int)STRLEN(p->pattern);
+ if (len > patlen)
+ len = patlen;
msg_outtrans_len(p->pattern, len);
msg_puts("\n");
}
diff --git a/src/tag.c b/src/tag.c
index d406fde..f94d3eb 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -144,7 +144,6 @@ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_
#if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
static int add_llist_tags(char_u *tag, int num_matches, char_u **matches);
#endif
-static void tagstack_clear_entry(taggy_T *item);
static char_u *tagmatchname = NULL; // name of last used tag
@@ -311,7 +310,7 @@ do_tag(
#endif
if (postponed_split == 0 && !check_can_set_curbuf_forceit(forceit))
- return FALSE;
+ return FALSE;
if (type == DT_HELP)
{
@@ -3413,6 +3412,11 @@ get_tagfname(
// move the filename one char forward and truncate the
// filepath with a NUL
filename = gettail(buf);
+ if (r_ptr != NULL)
+ {
+ STRMOVE(r_ptr + 1, r_ptr);
+ ++r_ptr;
+ }
STRMOVE(filename + 1, filename);
*filename++ = NUL;
@@ -3709,7 +3713,7 @@ jumpto_tag(
char_u *lbuf;
if (postponed_split == 0 && !check_can_set_curbuf_forceit(forceit))
- return FAIL;
+ return FAIL;
// Make a copy of the line, it can become invalid when an autocommand calls
// back here recursively.
@@ -4233,7 +4237,7 @@ find_extra(char_u **pp)
/*
* Free a single entry in a tag stack
*/
- static void
+ void
tagstack_clear_entry(taggy_T *item)
{
VIM_CLEAR(item->tagname);
diff --git a/src/terminal.c b/src/terminal.c
index 648fc78..073f8dd 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -3451,6 +3451,10 @@ limit_scrollback(term_T *term, garray_T *gap, int update_buffer)
sizeof(sb_line_T) * gap->ga_len);
if (update_buffer)
term->tl_scrollback_scrolled -= todo;
+
+ // make sure cursor is on a valid line
+ if (curbuf == term->tl_buffer)
+ check_cursor();
}
/*
@@ -3643,7 +3647,7 @@ term_after_channel_closed(term_T *term)
if (term->tl_finish == TL_FINISH_CLOSE)
{
aco_save_T aco;
- int do_set_w_closing = term->tl_buffer->b_nwindows == 0;
+ int do_set_w_locked = term->tl_buffer->b_nwindows == 0;
#ifdef FEAT_PROP_POPUP
win_T *pwin = NULL;
@@ -3674,12 +3678,12 @@ term_after_channel_closed(term_T *term)
{
// Avoid closing the window if we temporarily use it.
if (is_aucmd_win(curwin))
- do_set_w_closing = TRUE;
- if (do_set_w_closing)
- curwin->w_closing = TRUE;
+ do_set_w_locked = TRUE;
+ if (do_set_w_locked)
+ curwin->w_locked = TRUE;
do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
- if (do_set_w_closing)
- curwin->w_closing = FALSE;
+ if (do_set_w_locked)
+ curwin->w_locked = FALSE;
aucmd_restbuf(&aco);
}
#ifdef FEAT_PROP_POPUP
@@ -6299,7 +6303,7 @@ f_term_getsize(typval_T *argvars, typval_T *rettv)
* "term_setsize(buf, rows, cols)" function
*/
void
-f_term_setsize(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+f_term_setsize(typval_T *argvars, typval_T *rettv UNUSED)
{
buf_T *buf;
term_T *term;
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index e31d2b5..67ef641 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -20,7 +20,8 @@ SCRIPTS_TINY = \
test24 \
test25 \
test26 \
- test27
+ test27 \
+ test28
SCRIPTS_TINY_OUT = \
test10.out \
@@ -31,7 +32,8 @@ SCRIPTS_TINY_OUT = \
test24.out \
test25.out \
test26.out \
- test27.out
+ test27.out \
+ test28.out
# Tests for Vim9 script.
TEST_VIM9 = \
@@ -161,6 +163,10 @@ NEW_TESTS = \
test_function_lists \
test_ga \
test_getcwd \
+ test_gettext \
+ test_gettext_cp1251 \
+ test_gettext_utf8 \
+ test_gettext_make \
test_getvar \
test_gf \
test_glob2regpat \
@@ -309,6 +315,7 @@ NEW_TESTS = \
test_textobjects \
test_textprop \
test_timers \
+ test_tohtml \
test_true_false \
test_trycatch \
test_undo \
@@ -335,6 +342,7 @@ NEW_TESTS = \
test_writefile \
test_xdg \
test_xxd \
+ test_zip_plugin \
test_alot_latin \
test_alot_utf8 \
test_alot
@@ -420,6 +428,10 @@ NEW_TESTS_RES = \
test_functions.res \
test_function_lists.res \
test_getcwd.res \
+ test_gettext.res \
+ test_gettext_cp1251.res \
+ test_gettext_utf8.res \
+ test_gettext_make.res \
test_getvar.res \
test_gf.res \
test_gn.res \
@@ -550,6 +562,7 @@ NEW_TESTS_RES = \
test_textobjects.res \
test_textprop.res \
test_timers.res \
+ test_tohtml.res \
test_true_false.res \
test_trycatch.res \
test_undo.res \
@@ -571,6 +584,7 @@ NEW_TESTS_RES = \
test_writefile.res \
test_xdg.res \
test_xxd.res \
+ test_zip_plugin.res \
test_alot_latin.res \
test_alot_utf8.res \
test_alot.res
diff --git a/src/testdir/Make_mvc.mak b/src/testdir/Make_mvc.mak
index 318cd4a..1bf9eae 100644
--- a/src/testdir/Make_mvc.mak
+++ b/src/testdir/Make_mvc.mak
@@ -5,9 +5,9 @@
# Testing may be done with a debug build
!IF EXIST(..\\vimd.exe) && !EXIST(..\\vim.exe)
-VIMPROG = ..\\vimd
+VIMPROG = ..\\vimd.exe
!ELSE
-VIMPROG = ..\\vim
+VIMPROG = ..\\vim.exe
!ENDIF
@@ -42,7 +42,7 @@ report:
else ( echo No failures reported > test_result.log )
$(VIMPROG) -u NONE $(COMMON_ARGS) -S summarize.vim messages
-if exist starttime del starttime
- @echo.
+ @echo:
@echo Test results:
@cmd /c type test_result.log
@if exist test.log ( echo TEST FAILURE & exit /b 1 ) \
@@ -56,7 +56,7 @@ $(NEW_TESTS):
-if exist test.log del test.log
-if exist messages del messages
-if exist starttime del starttime
- @$(MAKE) -nologo -f Make_mvc.mak $@.res VIMPROG=$(VIMPROG)
+ @$(MAKE) -nologo -f Make_mvc.mak VIMPROG=$(VIMPROG) $@.res
@type messages
@if exist test.log exit 1
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
index 4e476f9..7a4c4c4 100644
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -84,7 +84,7 @@ test_vim9:
RM_ON_RUN = test.out X* viminfo
RM_ON_START = test.ok benchmark.out
-RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in
+RUN_VIMPROG = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in
# 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.
@@ -114,7 +114,7 @@ tinytests: $(SCRIPTS_TINY_OUT)
@# 200 msec is sufficient, but only modern sleep supports a fraction of
@# a second, fall back to a second if it fails.
@-/bin/sh -c "sleep .2 > /dev/null 2>&1 || sleep 1"
- $(RUN_VIM) $*.in $(REDIR_TEST_TO_NULL)
+ $(RUN_VIMPROG) $*.in $(REDIR_TEST_TO_NULL)
@# Check if the test.out file matches test.ok.
@/bin/sh -c "if test -f test.out; then \
diff --git a/src/testdir/README.txt b/src/testdir/README.txt
index f72bdbf..203c324 100644
--- a/src/testdir/README.txt
+++ b/src/testdir/README.txt
@@ -97,8 +97,7 @@ tests are successful, then this file will be an empty file.
- To execute only specific test functions, add a second argument:
- $ ../vim -u NONE -S runtest.vim test_channel.vim open_delay
-
+ $ ../vim -u NONE -S runtest.vim test_channel.vim open_delay
- To run all the tests:
@@ -119,3 +118,83 @@ tests are successful, then this file will be an empty file.
- To cleanup the temporary files after running the tests:
$ make clean
+
+
+VIEWING GENERATED SCREENDUMPS (local):
+
+You may also wish to look at the whole batch of failed screendumps after
+running "make". Source the "viewdumps.vim" script for this task:
+
+ $ ../vim -u NONE -S viewdumps.vim \
+ [dumps/Test_xxd_*.dump ...]
+
+By default, all screendumps found in the "failed" directory will be added to
+the argument list and then the first one will be loaded. Loaded screendumps
+that bear filenames of screendumps found in the "dumps" directory will be
+rendering the contents of any such pair of files and the difference between
+them (:help term_dumpdiff()); otherwise, they will be rendering own contents
+(:help term_dumpload()). Remember to execute :edit when occasionally you see
+raw file contents instead of rendered.
+
+At any time, you can add, list, and abandon other screendumps:
+
+ :$argedit dumps/Test_spell_*.dump
+ :args
+ :qall
+
+The listing of argument commands can be found under :help buffer-list.
+
+
+VIEWING GENERATED SCREENDUMPS (from a CI-uploaded artifact):
+
+After you have downloaded an artifact archive containing failed screendumps
+and extracted its files in a temporary directory, you need to set up a "dumps"
+directory by creating a symlink:
+
+ $ cd /path/to/fork
+ $ ln -s $(pwd)/src/testdir/dumps /tmp/src/testdir/dumps
+
+You can now examine the extracted screendumps:
+
+ $ ./src/vim -u NONE -S src/testdir/viewdumps.vim \
+ /tmp/src/testdir/failed/*.dump
+
+
+VIEWING GENERATED SCREENDUMPS (submitted for a pull request):
+
+First, you need to check out the topic branch with the proposed changes and
+write down a difference list between the HEAD commit (index) and its parent
+commit with respect to the changed "dumps" filenames:
+
+ $ cd /path/to/fork
+ $ git switch prs/1234
+ $ git diff-index --relative=src/testdir/dumps/ \
+ --name-only prs/1234~1 > /tmp/filelist
+
+Then, you need to check out the master branch, change the current working
+directory to reconcile relative filepaths written in the filenames list,
+possibly create an empty "failed" directory, copy in this directory the old
+"dumps" files, whose names are on the same list, and follow it by checking out
+the topic branch:
+
+ $ git switch master
+ $ cd src/testdir/dumps
+ $ test -d ../failed || mkdir ../failed
+ $ cp -t ../failed $(cat /tmp/filelist)
+ $ git switch prs/1234
+
+Make note of any missing new screendumps. Please remember about the
+introduced INVERTED relation between "dumps" and "failed", i.e. the files to
+be committed are in "dumps" already and their old versions are in "failed".
+Therefore, you need to copy the missing new screendumps from "dumps" to
+"failed":
+
+ $ cp -t ../failed foo_10.dump foo_11.dump foo_12.dump
+
+After you have changed the current working directory to its parent directory,
+you can now examine the screendumps from the "failed" directory (note that new
+screendumps will be shown with no difference between their versions):
+
+ $ cd ..
+ $ ../vim -u NONE -S viewdumps.vim
+
diff --git a/src/testdir/commondumps.vim b/src/testdir/commondumps.vim
new file mode 100644
index 0000000..ed70280
--- /dev/null
+++ b/src/testdir/commondumps.vim
@@ -0,0 +1,76 @@
+vim9script
+
+# (Script-local.)
+#
+# Render a loaded screendump file or the difference of a loaded screendump
+# file and its namesake file from the "dumps" directory.
+def Render()
+ const failed_fname: string = bufname()
+ try
+ setlocal suffixesadd=.dump
+ const dumps_fname: string = findfile(
+ fnamemodify(failed_fname, ':p:t'),
+ fnamemodify(failed_fname, ':p:h:h') .. '/dumps')
+ if filereadable(dumps_fname)
+ term_dumpdiff(failed_fname, dumps_fname)
+ else
+ term_dumpload(failed_fname)
+ endif
+ finally
+ exec 'bwipeout ' .. failed_fname
+ endtry
+enddef
+
+# Search for the "failed" directory in the passed _subtreedirname_ directories
+# (usually "\<src\>" or "\<syntax\>") and, if found, select its passed _count_
+# occurence, add all its "*.dump" files to the argument list and list them;
+# also define a BufRead autocommand that would invoke "Render()" for every
+# "*.dump" file.
+def g:Init(subtreedirname: string, count: number)
+ # Support sourcing this script from any directory in the direct path that
+ # leads to the project's root directory.
+ const failed_path: string = finddir('failed', getcwd() .. '/**', -1)
+ ->filter(((cwdpath: string, parentdirname: string) =>
+ (_: number, dirpath: string) =>
+ cwdpath =~ parentdirname || dirpath =~ parentdirname)(
+ getcwd(),
+ subtreedirname))
+ ->get(count, '') .. '/'
+ var error: string = null_string
+
+ if failed_path == '/'
+ error = 'No such directory: "failed"'
+ else
+ const failed_fnames: string = failed_path .. readdir(failed_path,
+ (fname: string) => fname =~ '^.\+\.dump$')
+ ->join(' ' .. failed_path)
+
+ if failed_fnames =~ 'failed/$'
+ error = 'No such file: "*.dump"'
+ else
+ exec ':0argedit ' .. failed_fnames
+ buffers
+ endif
+ endif
+
+ autocmd_add([{
+ replace: true,
+ group: 'viewdumps',
+ event: 'BufRead',
+ pattern: '*.dump',
+ cmd: 'Render()',
+ }])
+
+ # Unconditionally help, in case a list of filenames is passed to the
+ # command, the first terminal window with its BufRead event.
+ silent doautocmd viewdumps BufRead
+
+ if error != null_string
+ # Instead of sleeping, fill half a window with blanks and prompt
+ # hit-enter.
+ echom error .. repeat("\x20",
+ (winwidth(0) * (winheight(0) / 2) - strlen(error)))
+ endif
+enddef
+
+# vim:fdm=syntax:sw=2:ts=8:noet:nolist:nosta:
diff --git a/src/testdir/crash/dialog_changed_uaf b/src/testdir/crash/dialog_changed_uaf
new file mode 100644
index 0000000..e37d18d
--- /dev/null
+++ b/src/testdir/crash/dialog_changed_uaf
Binary files differ
diff --git a/src/testdir/crash/double_free b/src/testdir/crash/double_free
new file mode 100644
index 0000000..895c4a0
--- /dev/null
+++ b/src/testdir/crash/double_free
Binary files differ
diff --git a/src/testdir/crash/heap_overflow3 b/src/testdir/crash/heap_overflow3
new file mode 100644
index 0000000..c40adbe
--- /dev/null
+++ b/src/testdir/crash/heap_overflow3
Binary files differ
diff --git a/src/testdir/crash/nullpointer b/src/testdir/crash/nullpointer
new file mode 100644
index 0000000..c8ff3a4
--- /dev/null
+++ b/src/testdir/crash/nullpointer
Binary files differ
diff --git a/src/testdir/crash/reverse_text_overflow b/src/testdir/crash/reverse_text_overflow
new file mode 100644
index 0000000..dfbfe2c
--- /dev/null
+++ b/src/testdir/crash/reverse_text_overflow
Binary files differ
diff --git a/src/testdir/dumps/Test_breakindent_with_double_width_wrap_1.dump b/src/testdir/dumps/Test_breakindent_with_double_width_wrap_1.dump
new file mode 100644
index 0000000..7b761bc
--- /dev/null
+++ b/src/testdir/dumps/Test_breakindent_with_double_width_wrap_1.dump
@@ -0,0 +1,6 @@
+| +0&#ffffff0@7|a@40|>+0#4040ff13&
+| +0#0000000&@7>å£*&@2| +&@35
+|~+0#4040ff13&| @48
+|~| @48
+|~| @48
+| +0#0000000&@31|1|,|4|3|-|5|9| @6|A|l@1|
diff --git a/src/testdir/dumps/Test_cmdwin_no_terminal.dump b/src/testdir/dumps/Test_cmdwin_no_terminal.dump
index 97d8147..6de9879 100644
--- a/src/testdir/dumps/Test_cmdwin_no_terminal.dump
+++ b/src/testdir/dumps/Test_cmdwin_no_terminal.dump
@@ -1,6 +1,6 @@
| +0&#ffffff0@74
|[+1&&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1
-|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|c+0#e000e06&|m|d|h|e|i|g|h|t|=+0#0000000&|2| @58
+|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|c+0#e000e06&|m|d|h|e|i|g|h|t|=+0#af5f00255&|2+0#0000000&| @58
|:+0#4040ff13&> +0#0000000&@73
|~+0#4040ff13&| @73
|~| @73
diff --git a/src/testdir/dumps/Test_matchparen_mbyte_1.dump b/src/testdir/dumps/Test_matchparen_mbyte_1.dump
new file mode 100644
index 0000000..f5df150
--- /dev/null
+++ b/src/testdir/dumps/Test_matchparen_mbyte_1.dump
@@ -0,0 +1,10 @@
+>a+0&#ffffff0@7|(*&| +&@64
+|b@3|)*&|c+&@1| @66
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_matchparen_mbyte_2.dump b/src/testdir/dumps/Test_matchparen_mbyte_2.dump
new file mode 100644
index 0000000..0e4e6e8
--- /dev/null
+++ b/src/testdir/dumps/Test_matchparen_mbyte_2.dump
@@ -0,0 +1,10 @@
+|a+0&#ffffff0@7>(*0&#40ffff15| +0&#ffffff0@64
+|b@3|)*0&#40ffff15|c+0&#ffffff0@1| @66
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|,|9| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_matchparen_mbyte_3.dump b/src/testdir/dumps/Test_matchparen_mbyte_3.dump
new file mode 100644
index 0000000..85c462a
--- /dev/null
+++ b/src/testdir/dumps/Test_matchparen_mbyte_3.dump
@@ -0,0 +1,10 @@
+|a+0&#ffffff0@7|(*&| +&@64
+|b@3|)*&|c+&>c| @66
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|2|,|9|-|8| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_matchparen_mbyte_4.dump b/src/testdir/dumps/Test_matchparen_mbyte_4.dump
new file mode 100644
index 0000000..45f5d08
--- /dev/null
+++ b/src/testdir/dumps/Test_matchparen_mbyte_4.dump
@@ -0,0 +1,10 @@
+|a+0&#ffffff0@7|(*0&#40ffff15| +0&#ffffff0@64
+|b@3>)*0&#40ffff15|c+0&#ffffff0@1| @66
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|2|,|5| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_matchparen_mbyte_5.dump b/src/testdir/dumps/Test_matchparen_mbyte_5.dump
new file mode 100644
index 0000000..45c3bfa
--- /dev/null
+++ b/src/testdir/dumps/Test_matchparen_mbyte_5.dump
@@ -0,0 +1,10 @@
+|a+0&#ffffff0@7|(*&| +&@64
+>b@3|)*&|c+&@1| @66
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|2|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_matchparen_mbyte_6.dump b/src/testdir/dumps/Test_matchparen_mbyte_6.dump
new file mode 100644
index 0000000..8064a98
--- /dev/null
+++ b/src/testdir/dumps/Test_matchparen_mbyte_6.dump
@@ -0,0 +1,10 @@
+|a+0&#ffffff0@7|(*0&#40ffff15> +0&#ffffff0@64
+|b@3|)*0&#40ffff15|c+0&#ffffff0@1| @66
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|1|2|-|1@1| @6|A|l@1|
diff --git a/src/testdir/dumps/Test_matchparen_mbyte_7.dump b/src/testdir/dumps/Test_matchparen_mbyte_7.dump
new file mode 100644
index 0000000..4d8c647
--- /dev/null
+++ b/src/testdir/dumps/Test_matchparen_mbyte_7.dump
@@ -0,0 +1,10 @@
+|a+0&#ffffff0@7|(*&| +&@64
+|b@3|)*&|c+&@1> @66
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|2|,|1|0|-|9| @7|A|l@1|
diff --git a/src/testdir/dumps/Test_matchparen_mbyte_8.dump b/src/testdir/dumps/Test_matchparen_mbyte_8.dump
new file mode 100644
index 0000000..c3699fd
--- /dev/null
+++ b/src/testdir/dumps/Test_matchparen_mbyte_8.dump
@@ -0,0 +1,10 @@
+|a+0&#ffffff0@7|(*0&#40ffff15| +0&#ffffff0@64
+|b@3|)*0&#40ffff15> +0&#ffffff0@68
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|2|,|8|-|7| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_setbuf_01.dump b/src/testdir/dumps/Test_popup_setbuf_01.dump
new file mode 100644
index 0000000..14359ba
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_setbuf_01.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_setbuf_02.dump b/src/testdir/dumps/Test_popup_setbuf_02.dump
new file mode 100644
index 0000000..5feb982
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_setbuf_02.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|s|e|t|b|u|f|(|p|,| |'|f|o@1|b|a|r|.|t|x|t|'|)| @21|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_setbuf_03.dump b/src/testdir/dumps/Test_popup_setbuf_03.dump
new file mode 100644
index 0000000..2c49576
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_setbuf_03.dump
@@ -0,0 +1,10 @@
+|~+0#4040ff13#ffffff0| @73
+|~| @73
+|~| @73
+|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|E+0#ffffff16#e000002|1|2@1|0|:| |S|t|r|i|n|g| |o|r| |N|u|m|b|e|r| |r|e|q|u|i|r|e|d| |f|o|r| |a|r|g|u|m|e|n|t| |2| +0#0000000#ffffff0@27
+|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35
diff --git a/src/testdir/dumps/Test_popup_setbuf_04.dump b/src/testdir/dumps/Test_popup_setbuf_04.dump
new file mode 100644
index 0000000..937fa7c
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_setbuf_04.dump
@@ -0,0 +1,10 @@
+>*+0#ffffff16#ffd7ff255|h+0#e000002&|e|l|p|.|t|x|t|*+0#ffffff16&| +0#0000001&@5|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000001&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @11| +0#0000000#0000001
+| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@23|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @29| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@72|k| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@5|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e|y|s|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @1| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255|l| @71| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@19|"|j|"| |t|o| |g|o| |d|o|w|n|,| |"|k|"| |t|o| |g|o| |u|p|,| |"|l|"| |t|o| |g|o| |r|i|g|h|t|.| @6|j| +0#0000000#a8a8a8255
+|C+0#0000001#ffd7ff255|l|o|s|e| |t|h|i|s| |w|i|n|d|o|w|:| @1|U|s|e| |"|:|q|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&|.| @37| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@2|G|e|t| |o|u|t| |o|f| |V|i|m|:| @1|U|s|e| |"|:|q|a|!|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&| |(|c|a|r|e|f|u|l|,| |a|l@1| |c|h|a|n|g|e|s| |a|r|e| |l|o|s|t|!|)|.| @2| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255
diff --git a/src/testdir/dumps/Test_popup_setbuf_05.dump b/src/testdir/dumps/Test_popup_setbuf_05.dump
new file mode 100644
index 0000000..a13dfe3
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_setbuf_05.dump
@@ -0,0 +1,10 @@
+>h+0#e000002#ffffff0|e|l|p|.|t|x|t| +0#0000000&@7|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000000&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @12
+@75
+@24|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @30
+@73|k|
+@6|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e| +0#0000001#ffd7ff255|s+0#0000000#ffffff0|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @2
+|l| @73
+|h+3&&|e|l|p|.|t|x|t| |[|H|e|l|p|]|[|R|O|]| @37|1|,|1| @11|T|o|p
+| +0&&@74
+|[+1&&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1
+| +0&&@74
diff --git a/src/testdir/dumps/Test_popup_setbuf_06.dump b/src/testdir/dumps/Test_popup_setbuf_06.dump
new file mode 100644
index 0000000..937fa7c
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_setbuf_06.dump
@@ -0,0 +1,10 @@
+>*+0#ffffff16#ffd7ff255|h+0#e000002&|e|l|p|.|t|x|t|*+0#ffffff16&| +0#0000001&@5|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000001&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @11| +0#0000000#0000001
+| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@23|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @29| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@72|k| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@5|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e|y|s|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @1| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255|l| @71| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@19|"|j|"| |t|o| |g|o| |d|o|w|n|,| |"|k|"| |t|o| |g|o| |u|p|,| |"|l|"| |t|o| |g|o| |r|i|g|h|t|.| @6|j| +0#0000000#a8a8a8255
+|C+0#0000001#ffd7ff255|l|o|s|e| |t|h|i|s| |w|i|n|d|o|w|:| @1|U|s|e| |"|:|q|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&|.| @37| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@2|G|e|t| |o|u|t| |o|f| |V|i|m|:| @1|U|s|e| |"|:|q|a|!|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&| |(|c|a|r|e|f|u|l|,| |a|l@1| |c|h|a|n|g|e|s| |a|r|e| |l|o|s|t|!|)|.| @2| +0#0000000#a8a8a8255
+| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255
diff --git a/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_2.dump b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_2.dump
new file mode 100644
index 0000000..6022a16
--- /dev/null
+++ b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_2.dump
@@ -0,0 +1,3 @@
+|a+0&#ffffff0@39|b+0#e000e06&@8|>+0#4040ff13&
+>å£*0#0000000&|1+&|2|3|4|5| @42
+@32|1|,|4|1|-|5|1| @6|A|l@1|
diff --git a/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_3.dump b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_3.dump
new file mode 100644
index 0000000..c033399
--- /dev/null
+++ b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_3.dump
@@ -0,0 +1,3 @@
+|a+0&#ffffff0@39|b+0#e000e06&@8|>+0#4040ff13&
+|+@2>å£*0#0000000&|1+&|2|3|4|5| @39
+|:|s|e|t| |s|h|o|w|b|r|e|a|k|=|+@2| @13|1|,|4|1|-|5|4| @6|A|l@1|
diff --git a/src/testdir/dumps/Test_pum_highlights_10.dump b/src/testdir/dumps/Test_pum_highlights_10.dump
new file mode 100644
index 0000000..790b028
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_10.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0|h|e|l@1|o| |h|e|l|i|o| |h|e|r|o| |h|e|l@1|o> @51
+|~+0#4040ff13&| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|r|o| @10| +0#4040ff13#ffffff0@41
+|~| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|l|i|o| @9| +0#4040ff13#ffffff0@41
+|~| @15| +0#0000001#e0e0e08|h+0#00e0e07&|e+0#0000001&|l@1|o| @9| +0#4040ff13#ffffff0@41
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@27
diff --git a/src/testdir/dumps/Test_pum_highlights_11.dump b/src/testdir/dumps/Test_pum_highlights_11.dump
new file mode 100644
index 0000000..ef75a89
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_11.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0|h|e|l@1|o| |h|e|l|i|o| |h|e|r|o| |h|e|l|i|o> @51
+|~+0#4040ff13&| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|r|o| @10| +0#4040ff13#ffffff0@41
+|~| @15| +0#0000001#e0e0e08|h+0#00e0e07&|e+0#0000001&|l|i|o| @9| +0#4040ff13#ffffff0@41
+|~| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|l@1|o| @9| +0#4040ff13#ffffff0@41
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |2| |o|f| |3| +0#0000000&@27
diff --git a/src/testdir/dumps/Test_pum_highlights_12.dump b/src/testdir/dumps/Test_pum_highlights_12.dump
new file mode 100644
index 0000000..a0d2b49
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_12.dump
@@ -0,0 +1,20 @@
+|a+0&#ffffff0|w|o|r|d|1> @68
+|a+0#ff404010#e0e0e08|w|o|r|d|1| |W| |e|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@52
+|a+0#0000001#ffd7ff255|w|o|r|d|2| |W| |e|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@52
+|你*0#ff404010#ffd7ff255|好| +&@2|W| |e|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@52
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@26
diff --git a/src/testdir/dumps/Test_pum_highlights_13.dump b/src/testdir/dumps/Test_pum_highlights_13.dump
new file mode 100644
index 0000000..34fde12
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_13.dump
@@ -0,0 +1,20 @@
+|a+0&#ffffff0|w|o|r|d|1> @68
+|a+8#ff404010#e0e0e08|w|o+0&&|r|d|1| |W| |e|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@52
+|a+8#0000e05#ffd7ff255|w|o+0#0000001&|r|d|2| |W| |e|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@52
+|你*0#ff404010#ffd7ff255|好| +&@2|W| |e|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@52
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@26
diff --git a/src/testdir/dumps/Test_pum_highlights_14.dump b/src/testdir/dumps/Test_pum_highlights_14.dump
new file mode 100644
index 0000000..f35b4cb
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_14.dump
@@ -0,0 +1,20 @@
+|a+0&#ffffff0|w|o|r|d|2> @68
+|a+8#ff404010#ffd7ff255|w|o+0&&|r|d|1| |W| |e|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@52
+|a+8#00e0e07#e0e0e08|w|o+0#0000001&|r|d|2| |W| |e|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@52
+|你*0#ff404010#ffd7ff255|好| +&@2|W| |e|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@52
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |2| |o|f| |3| +0#0000000&@26
diff --git a/src/testdir/dumps/Test_pum_highlights_15.dump b/src/testdir/dumps/Test_pum_highlights_15.dump
new file mode 100644
index 0000000..e923b43
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_15.dump
@@ -0,0 +1,20 @@
+|/+0&#ffffff0|n|o|n|_|e|x|i|t|_|f|o|l|d|e|r> @58
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |F|i|l|e| |n|a|m|e| |c|o|m|p|l|e|t|i|o|n| |(|^|F|^|N|^|P|)| |P+0#ffffff16#e000002|a|t@1|e|r|n| |n|o|t| |f|o|u|n|d| +0#0000000#ffffff0@24
diff --git a/src/testdir/dumps/Test_pum_highlights_16.dump b/src/testdir/dumps/Test_pum_highlights_16.dump
new file mode 100644
index 0000000..fe2b68d
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_16.dump
@@ -0,0 +1,20 @@
+|a+0&#ffffff0|w|o|r|d|1> @68
+|a+0#ff404010#e0e0e08|w|o|r|d|1| |v+0#ffff4012&|a|r|i|a|b|l|e| |e+0#ff404010&|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@45
+|a+0#0000001#ffd7ff255|w|o|r|d|2| |f+0#4040ff13&|u|n|c|t|i|o|n| |e+0#0000001&|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@45
+|你*0#0000001#ffd7ff255|好| +&@2|c+0#40ff4011&|l|a|s@1| @3|e+0#0000001&|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@45
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@26
diff --git a/src/testdir/dumps/Test_wildmenu_pum_11.dump b/src/testdir/dumps/Test_wildmenu_pum_11.dump
index 4697c8a..a0ffc74 100644
--- a/src/testdir/dumps/Test_wildmenu_pum_11.dump
+++ b/src/testdir/dumps/Test_wildmenu_pum_11.dump
@@ -1,10 +1,10 @@
| +0&#ffffff0@74
|~+0#4040ff13&| @73
-|~| @73
|~| @10| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@46
+|~| @10| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@46
|:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=> @55
diff --git a/src/testdir/dumps/Test_wildmenu_pum_12.dump b/src/testdir/dumps/Test_wildmenu_pum_12.dump
index d93631d..12842c4 100644
--- a/src/testdir/dumps/Test_wildmenu_pum_12.dump
+++ b/src/testdir/dumps/Test_wildmenu_pum_12.dump
@@ -1,10 +1,10 @@
| +0&#ffffff0@74
|~+0#4040ff13&| @73
-|~| @73
|~| @17| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@39
+|~| @17| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@39
|:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=| |c|u|l|h|l|=> @48
diff --git a/src/testdir/dumps/Test_wildmenu_pum_13.dump b/src/testdir/dumps/Test_wildmenu_pum_13.dump
index b2b1424..94a8ccc 100644
--- a/src/testdir/dumps/Test_wildmenu_pum_13.dump
+++ b/src/testdir/dumps/Test_wildmenu_pum_13.dump
@@ -1,10 +1,10 @@
| +0&#ffffff0@74
|~+0#4040ff13&| @73
-|~| @73
|~| @24| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@32
+|~| @24| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@32
|:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=| |c|u|l|h|l|=| |c|u|l|h|l|=> @41
diff --git a/src/testdir/dumps/Test_wildmenu_pum_22.dump b/src/testdir/dumps/Test_wildmenu_pum_22.dump
index 3fd00ad..e774d5d 100644
--- a/src/testdir/dumps/Test_wildmenu_pum_22.dump
+++ b/src/testdir/dumps/Test_wildmenu_pum_22.dump
@@ -1,7 +1,7 @@
| +0&#ffffff0@74
|[+1&&|N|o| |N|a|m|e|]| @65
-|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#0000000&|l|o|n|g|e|s|t|,+0#af5f00255&|f+0#0000000&|u|l@1| @48
-|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#0000000&|f|u|l@1| @56
+|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#af5f00255&|l+0#0000000&|o|n|g|e|s|t|,+0#e000e06&|f+0#0000000&|u|l@1| @48
+|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#af5f00255&|f+0#0000000&|u|l@1| @56
|:+0#4040ff13&|s+0#af5f00255&|i|g|n| +0#0000000&|d|e|f|i|n|e| @62
|:+0#4040ff13&|s+0#af5f00255&|i|g|n| +0#0000000&|d|e|f|i|n|e> @62
|~+0#4040ff13&| @73
diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim
index 8cca2b9..7674714 100644
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -144,6 +144,7 @@ let test_values = {
\ 'splitkeep': [['cursor', 'screen', 'topline'], ['xxx']],
\ 'swapsync': [['', 'sync', 'fsync'], ['xxx']],
\ 'switchbuf': [['', 'useopen', 'split,newtab'], ['xxx']],
+ \ 'tabclose': [['', 'left', 'left,uselast'], ['xxx']],
\ 'tagcase': [['smart', 'match'], ['', 'xxx', 'smart,match']],
\ 'term': [[], []],
\ 'termguicolors': [[], []],
diff --git a/src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo b/src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo
new file mode 100644
index 0000000..300eba2
--- /dev/null
+++ b/src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo
Binary files differ
diff --git a/src/testdir/samples/Test_tohtml_basic.c.html b/src/testdir/samples/Test_tohtml_basic.c.html
new file mode 100644
index 0000000..d9467b5
--- /dev/null
+++ b/src/testdir/samples/Test_tohtml_basic.c.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>/home/jiangyinzuo/vim/src/testdir/Test_tohtml_basic.c.html</title>
+<meta name="Generator" content="Vim/9.1">
+<meta name="plugin-version" content="vim9.0_v2">
+<meta name="syntax" content="none">
+<meta name="settings" content="use_css,no_foldcolumn,pre_wrap,prevent_copy=,use_input_for_pc=none">
+<meta name="colorscheme" content="none">
+<style>
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-color: #ffffff; }
+body { font-family: monospace; color: #000000; background-color: #ffffff; }
+* { font-size: 1em; }
+-->
+</style>
+</head>
+<body>
+<pre id='vimCodeElement'>
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+
+int isprime(int n)
+{
+ if (n &lt;= 1)
+ return 0;
+
+ for (int i = 2; i &lt;= n / 2; i++)
+ if (n % i == 0)
+ return 0;
+
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ int n = 7;
+
+ printf(&quot;%d is %s prime\n&quot;, n, isprime(n) ? &quot;a&quot; : &quot;not a&quot;);
+
+ return 0;
+}
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/src/testdir/samples/Test_tohtml_basic_no_css.c.html b/src/testdir/samples/Test_tohtml_basic_no_css.c.html
new file mode 100644
index 0000000..fcbcf5c
--- /dev/null
+++ b/src/testdir/samples/Test_tohtml_basic_no_css.c.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>/home/jiangyinzuo/vim/src/testdir/Test_tohtml_basic_no_css.c.html</title>
+<meta name="Generator" content="Vim/9.1">
+<meta name="plugin-version" content="vim9.0_v2">
+<meta name="syntax" content="none">
+<meta name="settings" content="no_pre,no_foldcolumn,expand_tabs,prevent_copy=,use_input_for_pc=none">
+<meta name="colorscheme" content="none">
+</head>
+<body bgcolor="#ffffff" text="#000000">
+<font face="monospace">
+#include &lt;stdio.h&gt;<br>
+#include &lt;stdlib.h&gt;<br>
+<br>
+int isprime(int n)<br>
+{<br>
+&nbsp;&nbsp;if (n &lt;= 1)<br>
+&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br>
+<br>
+&nbsp;&nbsp;for (int i = 2; i &lt;= n / 2; i++)<br>
+&nbsp;&nbsp;&nbsp;&nbsp;if (n % i == 0)<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br>
+<br>
+&nbsp;&nbsp;return 1;<br>
+}<br>
+<br>
+int main(int argc, char *argv[])<br>
+{<br>
+&nbsp;&nbsp;int n = 7;<br>
+<br>
+&nbsp;&nbsp;printf(&quot;%d is %s prime\n&quot;, n, isprime(n) ? &quot;a&quot; : &quot;not a&quot;);<br>
+<br>
+&nbsp;&nbsp;return 0;<br>
+}<br>
+</font>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/src/testdir/samples/test.zip b/src/testdir/samples/test.zip
new file mode 100644
index 0000000..6d34ac6
--- /dev/null
+++ b/src/testdir/samples/test.zip
Binary files differ
diff --git a/src/testdir/samples/testa.zip b/src/testdir/samples/testa.zip
new file mode 100644
index 0000000..10b0346
--- /dev/null
+++ b/src/testdir/samples/testa.zip
Binary files differ
diff --git a/src/testdir/test28.in b/src/testdir/test28.in
new file mode 100644
index 0000000..3d5289d
--- /dev/null
+++ b/src/testdir/test28.in
@@ -0,0 +1,13 @@
+Test for using CTRL-A/CTRL-X in tiny mode
+
+STARTTEST
+/12352
+/12354
+:/^STARTHERE/+,$w! test.out
+:qa!
+ENDTEST
+
+STARTHERE
+12352
+
+12354
diff --git a/src/testdir/test28.ok b/src/testdir/test28.ok
new file mode 100644
index 0000000..085c133
--- /dev/null
+++ b/src/testdir/test28.ok
@@ -0,0 +1,3 @@
+12353
+
+12353
diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim
index edc8b77..8d81a82 100644
--- a/src/testdir/test_arglist.vim
+++ b/src/testdir/test_arglist.vim
@@ -359,6 +359,7 @@ func Test_argv()
call assert_equal('', argv(1, 100))
call assert_equal([], argv(-1, 100))
call assert_equal('', argv(10, -1))
+ %argdelete
endfunc
" Test for the :argedit command
@@ -744,4 +745,26 @@ func Test_all_command()
%bw!
endfunc
+" Test for deleting buffer when creating an arglist. This was accessing freed
+" memory
+func Test_crash_arglist_uaf()
+ "%argdelete
+ new one
+ au BufAdd XUAFlocal :bw
+ "call assert_fails(':arglocal XUAFlocal', 'E163:')
+ arglocal XUAFlocal
+ au! BufAdd
+ bw! XUAFlocal
+
+ au BufAdd XUAFlocal2 :bw
+ new two
+ new three
+ arglocal
+ argadd XUAFlocal2 Xfoobar
+ bw! XUAFlocal2
+ bw! two
+
+ au! BufAdd
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_assert.vim b/src/testdir/test_assert.vim
index d143f19..15b18a4 100644
--- a/src/testdir/test_assert.vim
+++ b/src/testdir/test_assert.vim
@@ -48,10 +48,19 @@ func Test_assert_equal()
call assert_match("Expected 'bar' but got 'foo'", v:errors[0])
call remove(v:errors, 0)
+ let s = 'αβγ'
+ call assert_equal(1, assert_equal('δεζ', s))
+ call assert_match("Expected 'δεζ' but got 'αβγ'", v:errors[0])
+ call remove(v:errors, 0)
+
call assert_equal('XxxxxxxxxxxxxxxxxxxxxxX', 'XyyyyyyyyyyyyyyyyyyyyyyyyyX')
call assert_match("Expected 'X\\\\\\[x occurs 21 times]X' but got 'X\\\\\\[y occurs 25 times]X'", v:errors[0])
call remove(v:errors, 0)
+ call assert_equal('ΩωωωωωωωωωωωωωωωωωωωωωΩ', 'ΩψψψψψψψψψψψψψψψψψψψψψψψψψΩ')
+ call assert_match("Expected 'Ω\\\\\\[ω occurs 21 times]Ω' but got 'Ω\\\\\\[ψ occurs 25 times]Ω'", v:errors[0])
+ call remove(v:errors, 0)
+
" special characters are escaped
call assert_equal("\b\e\f\n\t\r\\\x01\x7f", 'x')
call assert_match('Expected ''\\b\\e\\f\\n\\t\\r\\\\\\x01\\x7f'' but got ''x''', v:errors[0])
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index c9f257a..5a91351 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -14,6 +14,13 @@ func s:cleanup_buffers() abort
endfor
endfunc
+func CleanUpTestAuGroup()
+ augroup testing
+ au!
+ augroup END
+ augroup! testing
+endfunc
+
func Test_vim_did_enter()
call assert_false(v:vim_did_enter)
@@ -269,6 +276,7 @@ endfunc
func Test_win_tab_autocmd()
let g:record = []
+ defer CleanUpTestAuGroup()
augroup testing
au WinNewPre * call add(g:record, 'WinNewPre')
au WinNew * call add(g:record, 'WinNew')
@@ -288,7 +296,7 @@ func Test_win_tab_autocmd()
call assert_equal([
\ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter',
- \ 'WinLeave', 'TabLeave', 'WinNewPre', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
+ \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
\ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter',
\ 'WinLeave', 'WinClosed', 'WinEnter'
\ ], g:record)
@@ -299,7 +307,7 @@ func Test_win_tab_autocmd()
bwipe somefile
call assert_equal([
- \ 'WinLeave', 'TabLeave', 'WinNewPre', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
+ \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
\ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
\ 'WinClosed', 'TabClosed'
\ ], g:record)
@@ -316,9 +324,6 @@ func Test_win_tab_autocmd()
\ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter'
\ ], g:record)
- augroup testing
- au!
- augroup END
unlet g:record
endfunc
@@ -330,17 +335,15 @@ func Test_WinNewPre()
au WinNewPre * call add(g:layouts_pre, winlayout())
au WinNew * call add(g:layouts_post, winlayout())
augroup END
+ defer CleanUpTestAuGroup()
split
call assert_notequal(g:layouts_pre[0], g:layouts_post[0])
split
call assert_equal(g:layouts_pre[1], g:layouts_post[0])
call assert_notequal(g:layouts_pre[1], g:layouts_post[1])
+ " not triggered for tabnew
tabnew
- call assert_notequal(g:layouts_pre[2], g:layouts_post[1])
- call assert_notequal(g:layouts_pre[2], g:layouts_post[2])
- augroup testing
- au!
- augroup END
+ call assert_equal(2, len(g:layouts_pre))
unlet g:layouts_pre
unlet g:layouts_post
@@ -383,9 +386,6 @@ func Test_WinNewPre()
let g:caught += 1
endtry
call assert_equal(4, g:caught)
- augroup testing
- au!
- augroup END
unlet g:caught
endfunc
@@ -2096,6 +2096,38 @@ func Test_Cmdline()
au! CmdlineEnter
au! CmdlineLeave
let &shellslash = save_shellslash
+
+ au! CursorMovedC : let g:pos += [getcmdpos()]
+ let g:pos = []
+ call feedkeys(":foo bar baz\<C-W>\<C-W>\<C-W>\<Esc>", 'xt')
+ call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9, 5, 1], g:pos)
+ let g:pos = []
+ call feedkeys(":hello\<C-B>\<Esc>", 'xt')
+ call assert_equal([2, 3, 4, 5, 6, 1], g:pos)
+ let g:pos = []
+ call feedkeys(":hello\<C-U>\<Esc>", 'xt')
+ call assert_equal([2, 3, 4, 5, 6, 1], g:pos)
+ let g:pos = []
+ call feedkeys(":hello\<Left>\<C-R>=''\<CR>\<Left>\<Right>\<Esc>", 'xt')
+ call assert_equal([2, 3, 4, 5, 6, 5, 4, 5], g:pos)
+ let g:pos = []
+ call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Esc>", 'xt')
+ call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3], g:pos)
+ let g:pos = []
+ call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Left>\<Esc>", 'xt')
+ call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3, 2], g:pos)
+ au! CursorMovedC
+
+ " setcmdpos() is no-op inside an autocommand
+ au! CursorMovedC : let g:pos += [getcmdpos()] | call setcmdpos(1)
+ let g:pos = []
+ call feedkeys(":hello\<Left>\<Left>\<Esc>", 'xt')
+ call assert_equal([2, 3, 4, 5, 6, 5, 4], g:pos)
+ au! CursorMovedC
+
+ unlet g:entered
+ unlet g:left
+ unlet g:pos
endfunc
" Test for BufWritePre autocommand that deletes or unloads the buffer.
@@ -2775,7 +2807,8 @@ endfunc
func Test_autocmd_nested()
let g:did_nested = 0
- augroup Testing
+ defer CleanUpTestAuGroup()
+ augroup testing
au WinNew * edit somefile
au BufNew * let g:did_nested = 1
augroup END
@@ -2785,7 +2818,7 @@ func Test_autocmd_nested()
bwipe! somefile
" old nested argument still works
- augroup Testing
+ augroup testing
au!
au WinNew * nested edit somefile
au BufNew * let g:did_nested = 1
@@ -4720,4 +4753,115 @@ func Test_BufEnter_botline()
set hidden&vim
endfunc
+func Test_KeyInputPre()
+ " Consume previous keys
+ call feedkeys('', 'ntx')
+
+ " KeyInputPre can record input keys.
+ let s:keys = []
+ au KeyInputPre n call add(s:keys, v:char)
+
+ call feedkeys('jkjkjjj', 'ntx')
+ call assert_equal(
+ \ ['j', 'k', 'j', 'k', 'j', 'j', 'j'],
+ \ s:keys)
+
+ unlet s:keys
+ au! KeyInputPre
+
+ " KeyInputPre can handle multibyte.
+ let s:keys = []
+ au KeyInputPre * call add(s:keys, v:char)
+ edit Xxx1
+
+ call feedkeys("iã‚\<ESC>", 'ntx')
+ call assert_equal(['i', "ã‚", "\<ESC>"], s:keys)
+
+ bwipe! Xxx1
+ unlet s:keys
+ au! KeyInputPre
+
+ " KeyInputPre can change input keys.
+ au KeyInputPre i if v:char ==# 'a' | let v:char = 'b' | endif
+ edit Xxx1
+
+ call feedkeys("iaabb\<ESC>", 'ntx')
+ call assert_equal(getline('.'), 'bbbb')
+
+ bwipe! Xxx1
+ au! KeyInputPre
+
+ " KeyInputPre returns multiple characters.
+ au KeyInputPre i if v:char ==# 'a' | let v:char = 'cccc' | endif
+ edit Xxx1
+
+ call feedkeys("iaabb\<ESC>", 'ntx')
+ call assert_equal(getline('.'), 'ccbb')
+
+ bwipe! Xxx1
+ au! KeyInputPre
+
+ " KeyInputPre can use special keys.
+ au KeyInputPre i if v:char ==# 'a' | let v:char = "\<Ignore>" | endif
+ edit Xxx1
+
+ call feedkeys("iaabb\<ESC>", 'ntx')
+ call assert_equal(getline('.'), 'bb')
+
+ bwipe! Xxx1
+ au! KeyInputPre
+
+ " Test for v:event.typed
+ au KeyInputPre n call assert_true(v:event.typed)
+ call feedkeys('j', 'ntx')
+
+ au! KeyInputPre
+
+ au KeyInputPre n call assert_false(v:event.typed)
+ call feedkeys('j', 'nx')
+
+ au! KeyInputPre
+
+ " Test for v:event.typedchar
+ nnoremap j k
+ au KeyInputPre n
+ \ call assert_equal(v:event.typedchar, 'j')
+ \ | call assert_equal(v:char, 'k')
+ call feedkeys('j', 'tx')
+
+ au! KeyInputPre
+endfunc
+
+" those commands caused null pointer access, see #15464
+func Test_WinNewPre_crash()
+ defer CleanUpTestAuGroup()
+ let _cmdheight=&cmdheight
+ augroup testing
+ au!
+ autocmd WinNewPre * redraw
+ augroup END
+ tabnew
+ tabclose
+ augroup testing
+ au!
+ autocmd WinNewPre * wincmd t
+ augroup END
+ tabnew
+ tabclose
+ augroup testing
+ au!
+ autocmd WinNewPre * wincmd b
+ augroup END
+ tabnew
+ tabclose
+ augroup testing
+ au!
+ autocmd WinNewPre * set cmdheight+=1
+ augroup END
+ tabnew
+ tabclose
+ let &cmdheight=_cmdheight
+endfunc
+
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_breakindent.vim b/src/testdir/test_breakindent.vim
index 96d91c9..b306c02 100644
--- a/src/testdir/test_breakindent.vim
+++ b/src/testdir/test_breakindent.vim
@@ -1165,4 +1165,15 @@ func Test_breakindent_min_with_signcol()
call s:close_windows()
endfunc
+func Test_breakindent_with_double_width_wrap()
+ 50vnew
+ setlocal tabstop=8 breakindent nolist
+ call setline(1, "\t" .. repeat('a', winwidth(0) - 9) .. 'å£å£å£')
+ normal! $g0
+ call assert_equal(2, winline())
+ call assert_equal(9, wincol())
+
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_buffer.vim b/src/testdir/test_buffer.vim
index de088bd..757ba05 100644
--- a/src/testdir/test_buffer.vim
+++ b/src/testdir/test_buffer.vim
@@ -126,6 +126,52 @@ func Test_buflist_browse()
%bwipe!
endfunc
+" Test for :bnext and :bprev when called from help and non-help buffers.
+func Test_bnext_bprev_help()
+ %bwipe!
+
+ e XHelp1 | set bt=help
+ let b1 = bufnr()
+ e Xbuf1
+ let b2 = bufnr()
+
+ " There's only one buffer of each type.
+ b XHelp1
+ bnext | call assert_equal(b1, bufnr())
+ bprev | call assert_equal(b1, bufnr())
+ b Xbuf1
+ bnext | call assert_equal(b2, bufnr())
+ bprev | call assert_equal(b2, bufnr())
+
+ " Add one more buffer of each type.
+ e XHelp2 | set bt=help
+ let b3 = bufnr()
+ e Xbuf2
+ let b4 = bufnr()
+
+ " Help buffer jumps to help buffer.
+ b XHelp1
+ bnext | call assert_equal(b3, bufnr())
+ bnext | call assert_equal(b1, bufnr())
+ bprev | call assert_equal(b3, bufnr())
+ bprev | call assert_equal(b1, bufnr())
+
+ " Regular buffer jumps to regular buffer.
+ b Xbuf1
+ bnext | call assert_equal(b4, bufnr())
+ bnext | call assert_equal(b2, bufnr())
+ bprev | call assert_equal(b4, bufnr())
+ bprev | call assert_equal(b2, bufnr())
+
+ " :brewind and :blast are not affected by the buffer type.
+ b Xbuf2
+ brewind | call assert_equal(b1, bufnr())
+ b XHelp1
+ blast | call assert_equal(b4, bufnr())
+
+ %bwipe!
+endfunc
+
" Test for :bdelete
func Test_bdelete_cmd()
%bwipe!
diff --git a/src/testdir/test_cd.vim b/src/testdir/test_cd.vim
index 9fb5958..13a3eba 100644
--- a/src/testdir/test_cd.vim
+++ b/src/testdir/test_cd.vim
@@ -200,12 +200,20 @@ endfunc
func Test_cd_completion()
call mkdir('XComplDir1', 'D')
call mkdir('XComplDir2', 'D')
+ call mkdir('sub/XComplDir3', 'pD')
call writefile([], 'XComplFile', 'D')
for cmd in ['cd', 'chdir', 'lcd', 'lchdir', 'tcd', 'tchdir']
call feedkeys(':' .. cmd .. " XCompl\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"' .. cmd .. ' XComplDir1/ XComplDir2/', @:)
endfor
+
+ set cdpath+=sub
+ for cmd in ['cd', 'chdir', 'lcd', 'lchdir', 'tcd', 'tchdir']
+ call feedkeys(':' .. cmd .. " XCompl\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"' .. cmd .. ' XComplDir1/ XComplDir2/ XComplDir3/', @:)
+ endfor
+ set cdpath&
endfunc
func Test_cd_unknown_dir()
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 8b7489e..3f6918a 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -658,7 +658,8 @@ func Test_getcompletion()
unlet g:cmdline_compl_params
" For others test if the name is recognized.
- let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user']
+ let names = ['buffer', 'environment', 'file_in_path', 'dir_in_path', 'mapping', 'tag',
+ \ 'tag_listfiles', 'user']
if has('cmdline_hist')
call add(names, 'history')
endif
@@ -3612,7 +3613,7 @@ func Test_cmdline_complete_bang_cmd_argument()
endfunc
func Call_cmd_funcs()
- return string([getcmdpos(), getcmdscreenpos(), getcmdcompltype()])
+ return [getcmdpos(), getcmdscreenpos(), getcmdcompltype()]
endfunc
func Test_screenpos_and_completion()
@@ -3620,13 +3621,24 @@ func Test_screenpos_and_completion()
call assert_equal(0, getcmdscreenpos())
call assert_equal('', getcmdcompltype())
- cnoremap <expr> <F2> string([getcmdpos(), getcmdscreenpos(), getcmdcompltype()])
+ cnoremap <expr> <F2> string(Call_cmd_funcs())
call feedkeys(":let a\<F2>\<C-B>\"\<CR>", "xt")
call assert_equal("\"let a[6, 7, 'var']", @:)
call feedkeys(":quit \<F2>\<C-B>\"\<CR>", "xt")
call assert_equal("\"quit [6, 7, '']", @:)
call feedkeys(":nosuchcommand \<F2>\<C-B>\"\<CR>", "xt")
call assert_equal("\"nosuchcommand [15, 16, '']", @:)
+
+ " Check that getcmdcompltype() doesn't interfere with cmdline completion.
+ let g:results = []
+ cnoremap <F2> <Cmd>let g:results += [[getcmdline()] + Call_cmd_funcs()]<CR>
+ call feedkeys(":sign un\<Tab>\<F2>\<Tab>\<F2>\<Tab>\<F2>\<C-C>", "xt")
+ call assert_equal([
+ \ ['sign undefine', 14, 15, 'sign'],
+ \ ['sign unplace', 13, 14, 'sign'],
+ \ ['sign un', 8, 9, 'sign']], g:results)
+
+ unlet g:results
cunmap <F2>
endfunc
@@ -3858,4 +3870,25 @@ func Test_term_option()
let &cpo = _cpo
endfunc
+func Test_ex_command_completion()
+ " required for :*
+ set cpo+=*
+ let list = filter(getcompletion('', 'command'), 'exists(":" . v:val) == 0')
+ " :++ and :-- are only valid in Vim9 Script context, so they can be ignored
+ call assert_equal(['++', '--'], sort(list))
+ call assert_equal(1, exists(':k'))
+ call assert_equal(0, exists(':ke'))
+ call assert_equal(1, exists(':kee'))
+ call assert_equal(1, exists(':keep'))
+ call assert_equal(1, exists(':keepm'))
+ call assert_equal(1, exists(':keepma'))
+ call assert_equal(1, exists(':keepmar'))
+ call assert_equal(1, exists(':keepmark'))
+ call assert_equal(2, exists(':keepmarks'))
+ call assert_equal(2, exists(':keepalt'))
+ call assert_equal(2, exists(':keepjumps'))
+ call assert_equal(2, exists(':keeppatterns'))
+ set cpo-=*
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_codestyle.vim b/src/testdir/test_codestyle.vim
index a455264..83f52ef 100644
--- a/src/testdir/test_codestyle.vim
+++ b/src/testdir/test_codestyle.vim
@@ -28,6 +28,13 @@ def Test_source_files()
g:ignoreSwapExists = 'e'
exe 'edit ' .. fname
+ # Some files are generated files and may contain space errors.
+ if fname =~ 'dlldata.c'
+ || fname =~ 'if_ole.h'
+ || fname =~ 'iid_ole.c'
+ continue
+ endif
+
PerformCheck(fname, ' \t', 'space before Tab', '')
PerformCheck(fname, '\s$', 'trailing white space', '')
@@ -68,7 +75,8 @@ def Test_test_files()
&& fname !~ 'test_listchars.vim'
&& fname !~ 'test_visual.vim'
cursor(1, 1)
- var lnum = search(fname =~ "test_regexp_latin" ? '[^á] \t' : ' \t')
+ var skip = 'getline(".") =~ "codestyle: ignore"'
+ var lnum = search(fname =~ "test_regexp_latin" ? '[^á] \t' : ' \t', 'W', 0, 0, skip)
ReportError('testdir/' .. fname, lnum, 'space before Tab')
endif
@@ -155,4 +163,4 @@ def Test_help_files()
enddef
-" vim: shiftwidth=2 sts=2 expandtab
+" vim: shiftwidth=2 sts=2 expandtab nofoldenable
diff --git a/src/testdir/test_cpoptions.vim b/src/testdir/test_cpoptions.vim
index 6ff8301..7bfbcd1 100644
--- a/src/testdir/test_cpoptions.vim
+++ b/src/testdir/test_cpoptions.vim
@@ -19,7 +19,7 @@ func Test_cpo_a()
set cpo+=a
read XfileCpoA
call assert_equal('XfileCpoA', @#)
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -39,7 +39,7 @@ func Test_cpo_A()
set cpo+=A
write XcpoAfile2
call assert_equal('XcpoAfile2', @#)
- close!
+ bw!
call delete('XcpoAfile2')
let &cpo = save_cpo
endfunc
@@ -81,7 +81,7 @@ func Test_cpo_B()
call assert_equal('abd ', getline(1))
call feedkeys(":imap <buffer> x\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"imap <buffer> x\k', @:)
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -96,7 +96,7 @@ func Test_cpo_c()
set cpo-=c
exe "normal gg/abab\<CR>"
call assert_equal(5, searchcount().total)
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -143,7 +143,7 @@ func Test_cpo_D()
exe "norm! 1gg0f\<c-k>!!"
call assert_equal(1, col('.'))
set cpo-=D
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -183,7 +183,7 @@ func Test_cpo_E()
call assert_beeps('exe "normal v\<C-A>"')
call assert_beeps('exe "normal v\<C-X>"')
set cpo-=E
- close!
+ bw!
endfunc
" Test for the 'f' flag in 'cpo' (read in an empty buffer sets the file name)
@@ -213,7 +213,7 @@ func Test_cpo_F()
set cpo+=F
write XfileCpoF
call assert_equal('XfileCpoF', @%)
- close!
+ bw!
call delete('XfileCpoF')
let &cpo = save_cpo
endfunc
@@ -229,7 +229,7 @@ func Test_cpo_g()
set cpo+=g
edit
call assert_equal(1, line('.'))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -245,7 +245,7 @@ func Test_cpo_H()
call setline(1, ' ')
normal! Ia
call assert_equal(' a ', getline(1))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -264,7 +264,7 @@ func Test_cpo_I()
%d
exe "normal i one\<CR>\<Up>"
call assert_equal('', getline(2))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -295,7 +295,7 @@ func Test_cpo_J()
normal (
call assert_equal(colnr, col('.'))
endfor
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -317,7 +317,7 @@ func Test_cpo_l()
set cpo+=l
exe 'normal gg/[\t]' .. "\<CR>"
call assert_equal([4, 10], [col('.'), virtcol('.')])
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -338,7 +338,7 @@ func Test_cpo_L()
call setline(1, 'abcdefghijklmnopqr')
exe "normal 0gR\<Tab>"
call assert_equal("\<Tab>ijklmnopqr", getline(1))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -376,7 +376,7 @@ func Test_cpo_M()
call cursor(2, 1)
call assert_beeps('normal %')
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -392,7 +392,7 @@ func Test_cpo_n()
set cpo+=n
redraw!
call assert_equal('aaaa', Screenline(2))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -409,7 +409,7 @@ func Test_cpo_o()
exe "normal /one/+2\<CR>"
normal n
call assert_equal(5, line('.'))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -424,7 +424,7 @@ func Test_cpo_O()
set cpo+=O
write
call assert_equal(['one'], readfile('XfileCpoO'))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -462,7 +462,7 @@ func Test_cpo_q()
set cpo+=q
normal gg4J
call assert_equal(4, col('.'))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -483,7 +483,7 @@ func Test_cpo_r()
let @/ = 'three'
normal 2G.
call assert_equal('abc three four', getline(2))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -503,7 +503,7 @@ func Test_cpo_R()
3mark r
%!sort
call assert_equal(0, line("'r"))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -530,8 +530,8 @@ func Test_cpo_S()
wincmd p
call assert_equal(0, &autoindent)
wincmd t
- close!
- close!
+ bw!
+ bw!
let &cpo = save_cpo
endfunc
@@ -550,7 +550,7 @@ func Test_cpo_u()
exe "normal iabc\<C-G>udef\<C-G>ughi"
normal uu
call assert_equal('abcdefghi', getline(1))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -574,7 +574,7 @@ func Test_cpo_w()
call assert_equal('hereZZZare some words', getline('.'))
norm! 1gg2elcWYYY
call assert_equal('hereZZZare someYYYwords', getline('.'))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -611,7 +611,7 @@ func Test_cpo_X()
normal ggRy
normal 4.
call assert_equal('yyyyxxxaaaaa', getline(1))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -630,7 +630,7 @@ func Test_cpo_y()
normal ggyy
normal 2G.
call assert_equal("two\n", @")
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -647,7 +647,7 @@ func Test_cpo_Z()
setlocal readonly
write!
call assert_equal(1, &readonly)
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -700,7 +700,7 @@ func Test_cpo_percent()
call assert_equal(15, col('.'))
normal 22|%
call assert_equal(27, col('.'))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -716,7 +716,7 @@ func Test_cpo_minus()
call assert_beeps('normal 10k')
call assert_equal(3, line('.'))
call assert_fails(10, 'E16:')
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -732,7 +732,7 @@ func Test_cpo_plus()
set cpo+=+
write X2
call assert_equal(0, &modified)
- close!
+ bw!
call delete('X1')
call delete('X2')
let &cpo = save_cpo
@@ -749,7 +749,7 @@ func Test_cpo_star()
set cpo+=*
*a
call assert_equal(1, x)
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -770,7 +770,7 @@ func Test_cpo_gt()
normal gg"Rye
normal "Rye
call assert_equal("\none\none", @r)
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -803,7 +803,7 @@ func Test_cpo_semicolon()
call assert_equal('bbb y', getline(4))
call assert_equal('ccc', getline(5))
call assert_equal('ddd yee y', getline(6))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -828,7 +828,7 @@ func Test_cpo_hash()
call assert_equal(['', 'one', 'two', 'three'], getline(1, '$'))
normal gg2Ozero
call assert_equal(['zero', '', 'one', 'two', 'three'], getline(1, '$'))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -858,7 +858,7 @@ func Test_cpo_backslash()
set cpo+=\
exe 'normal gg/[ \-]' .. "\<CR>n"
call assert_equal(2, col('.'))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -880,7 +880,7 @@ func Test_cpo_brace()
call assert_equal(2, line('.'))
normal G{
call assert_equal(2, line('.'))
- close!
+ bw!
let &cpo = save_cpo
endfunc
@@ -908,8 +908,53 @@ func Test_cpo_dot()
call delete('Xfoo')
set cpo&
- close!
+ bw!
let &cpo = save_cpo
endfunc
+" Test for the 'z' flag in 'cpo' (make cw and dw work similar and avoid
+" inconsistencies, see :h cpo-z)
+func Test_cpo_z()
+ let save_cpo = &cpo
+ new
+ " Test 1: dw behaves differently from cw
+ call setline(1, ['foo bar baz', 'one two three'])
+ call cursor(1, 1)
+ " dw does not delete the whitespace after the word
+ norm! wcwanother
+ set cpo-=z
+ " dw deletes the whitespace after the word
+ call cursor(2, 1)
+ norm! wcwfour
+ call assert_equal(['foo another baz', 'one fourthree'], getline(1, '$'))
+ " Test 2: d{motion} becomes linewise :h d-special
+ %d
+ call setline(1, ['one ', ' bar', ' e ', 'zwei'])
+ call cursor(2, 1)
+ set cpo+=z
+ " delete operation becomes linewise
+ call feedkeys("fbd/e\\zs\<cr>", 'tnx')
+ call assert_equal(['one ', 'zwei'], getline(1, '$'))
+ %d
+ call setline(1, ['one ', ' bar', ' e ', 'zwei'])
+ call cursor(2, 1)
+ call feedkeys("fbd2w", 'tnx')
+ call assert_equal(['one ', 'zwei'], getline(1, '$'))
+
+ " delete operation does not become line wise
+ set cpo-=z
+ call setline(1, ['one ', ' bar', ' e ', 'zwei'])
+ call cursor(2, 1)
+ call feedkeys("fbd/e\\zs\<cr>", 'tnx')
+ call assert_equal(['one ', ' ', 'zwei'], getline(1, '$')) " codestyle: ignore
+ %d
+ call setline(1, ['one ', ' bar', ' e ', 'zwei'])
+ call cursor(2, 1)
+ call feedkeys("fbd2w", 'tnx')
+ call assert_equal(['one ', ' ', 'zwei'], getline(1, '$'))
+
+ " clean up
+ bw!
+ let &cpo = save_cpo
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_crash.vim b/src/testdir/test_crash.vim
index fd786e5..b334876 100644
--- a/src/testdir/test_crash.vim
+++ b/src/testdir/test_crash.vim
@@ -150,6 +150,13 @@ func Test_crash1_2()
\ ' ; echo "crash 4: [OK]" >> '.. result .. "\<cr>")
call TermWait(buf, 150)
+ let file = 'crash/reverse_text_overflow'
+ let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' ; echo "crash 5: [OK]" >> '.. result .. "\<cr>")
+ call TermWait(buf, 150)
+
" clean up
exe buf .. "bw!"
exe "sp " .. result
@@ -158,6 +165,7 @@ func Test_crash1_2()
\ 'crash 2: [OK]',
\ 'crash 3: [OK]',
\ 'crash 4: [OK]',
+ \ 'crash 5: [OK]',
\ ]
call assert_equal(expected, getline(1, '$'))
@@ -190,6 +198,31 @@ func Test_crash1_3()
call term_sendkeys(buf, args)
call TermWait(buf, 150)
+ let file = 'crash/double_free'
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args)
+ call TermWait(buf, 50)
+
+ let file = 'crash/dialog_changed_uaf'
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args)
+ call TermWait(buf, 150)
+
+ let file = 'crash/nullpointer'
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args)
+ call TermWait(buf, 50)
+
+ let file = 'crash/heap_overflow3'
+ let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args)
+ call TermWait(buf, 150)
+
+
" clean up
exe buf .. "bw!"
bw!
@@ -204,4 +237,11 @@ func Test_crash2()
exe buf .. "bw!"
endfunc
+func TearDown()
+ " That file is created at Test_crash1_3() by dialog_changed_uaf
+ " but cleaning up in that test doesn't remove it. Let's try again at
+ " the end of this test script
+ call delete('Untitled')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_eval_stuff.vim b/src/testdir/test_eval_stuff.vim
index a346399..1b17108 100644
--- a/src/testdir/test_eval_stuff.vim
+++ b/src/testdir/test_eval_stuff.vim
@@ -2,6 +2,7 @@
source view_util.vim
source shared.vim
+import './vim9.vim' as v9
function s:foo() abort
try
@@ -126,7 +127,31 @@ func Test_for_invalid()
call assert_fails("for x in 99", 'E1098:')
call assert_fails("for x in function('winnr')", 'E1098:')
call assert_fails("for x in {'a': 9}", 'E1098:')
- call assert_fails("for v:maxcol in range(1)", 'E46:')
+
+ let lines =<< trim END
+ for v:maxcol in range(5)
+ endfor
+ END
+
+ let save_v_maxcol = v:maxcol
+ call v9.CheckLegacyAndVim9Failure(lines, 'E46:')
+ call assert_equal(save_v_maxcol, v:maxcol)
+
+ let lines =<< trim END
+ for g:constvar in range(5)
+ endfor
+ END
+
+ const g:constvar = 10
+ call v9.CheckLegacyAndVim9Failure(lines, 'E741:')
+ call assert_equal(10, g:constvar)
+ unlet g:constvar
+
+ let g:constvar = 10
+ lockvar 0 g:constvar
+ call v9.CheckLegacyAndVim9Failure(lines, 'E1122:')
+ call assert_equal(10, g:constvar)
+ unlet g:constvar
if 0
/1/5/2/s/\n
diff --git a/src/testdir/test_ex_mode.vim b/src/testdir/test_ex_mode.vim
index 59c28f3..aa94935 100644
--- a/src/testdir/test_ex_mode.vim
+++ b/src/testdir/test_ex_mode.vim
@@ -68,7 +68,7 @@ func Test_Ex_substitute()
CheckRunVimInTerminal
let buf = RunVimInTerminal('', {'rows': 6})
- call term_sendkeys(buf, ":call setline(1, ['foo foo', 'foo foo', 'foo foo'])\<CR>")
+ call term_sendkeys(buf, ":call setline(1, repeat(['foo foo'], 4))\<CR>")
call term_sendkeys(buf, ":set number\<CR>")
call term_sendkeys(buf, "gQ")
call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000)
@@ -90,8 +90,14 @@ func Test_Ex_substitute()
" Pressing enter in ex mode should print the current line
call term_sendkeys(buf, "\<CR>")
- call WaitForAssert({-> assert_match(' 3 foo foo',
- \ term_getline(buf, 5))}, 1000)
+ call WaitForAssert({-> assert_match(' 3 foo foo', term_getline(buf, 5))}, 1000)
+ call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000)
+
+ " The printed line should overwrite the colon
+ call term_sendkeys(buf, "\<CR>")
+ call WaitForAssert({-> assert_match(' 3 foo foo', term_getline(buf, 4))}, 1000)
+ call WaitForAssert({-> assert_match(' 4 foo foo', term_getline(buf, 5))}, 1000)
+ call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000)
call term_sendkeys(buf, ":vi\<CR>")
call WaitForAssert({-> assert_match('foo bar', term_getline(buf, 1))}, 1000)
@@ -165,6 +171,37 @@ func Test_Ex_global()
call assert_equal('bax', getline(3))
call assert_equal('bay', getline(5))
bwipe!
+
+ new
+ call setline(1, ['foo', 'bar'])
+ call feedkeys("Qg/./i\\\na\\\n.\\\na\\\nb\\\n.", "xt")
+ call assert_equal(['a', 'b', 'foo', 'a', 'b', 'bar'], getline(1, '$'))
+ bwipe!
+endfunc
+
+func Test_Ex_shell()
+ CheckUnix
+
+ new
+ call feedkeys("Qr !echo foo\\\necho bar\n", 'xt')
+ call assert_equal(['', 'foo', 'bar'], getline(1, '$'))
+ bwipe!
+
+ new
+ call feedkeys("Qr !echo foo\\\\\nbar\n", 'xt')
+ call assert_equal(['', 'foobar'], getline(1, '$'))
+ bwipe!
+
+ new
+ call feedkeys("Qr !echo foo\\ \\\necho bar\n", 'xt')
+ call assert_equal(['', 'foo ', 'bar'], getline(1, '$'))
+ bwipe!
+
+ new
+ call setline(1, ['bar', 'baz'])
+ call feedkeys("Qg/./!echo \\\ns/b/c/", "xt")
+ call assert_equal(['car', 'caz'], getline(1, '$'))
+ bwipe!
endfunc
" Test for pressing Ctrl-C in :append inside a loop in Ex mode
@@ -204,18 +241,11 @@ func Test_Ex_append()
call feedkeys("Qappend!\npqr\nxyz\n.\nvisual\n", 'xt')
call assert_equal(["\t abc", "\t pqr", "\t xyz"], getline(1, '$'))
close!
-endfunc
-" In Ex-mode, backslashes at the end of a command should be halved.
-func Test_Ex_echo_backslash()
- " This test works only when the language is English
- CheckEnglish
- let bsl = '\\\\'
- let bsl2 = '\\\'
- call assert_fails('call feedkeys("Qecho " .. bsl .. "\nvisual\n", "xt")',
- \ 'E15: Invalid expression: "\\"')
- call assert_fails('call feedkeys("Qecho " .. bsl2 .. "\nm\nvisual\n", "xt")',
- \ "E15: Invalid expression: \"\\\nm\"")
+ new
+ call feedkeys("Qappend\na\\\n.", 'xt')
+ call assert_equal(['a\'], getline(1, '$'))
+ close!
endfunc
func Test_ex_mode_errors()
@@ -314,5 +344,47 @@ func Test_empty_command_visual_mode()
call delete('guidialogfile')
endfunc
+" Test using backslash in ex-mode
+func Test_backslash_multiline()
+ new
+ call setline(1, 'enum')
+ call feedkeys('Qg/enum/i\ \ .', "xt")
+ call assert_equal(["", "enum"], getline(1, 2))
+endfunc
+
+" Test using backslash in ex-mode after patch 9.1.0535
+func Test_backslash_multiline2()
+ new
+ call feedkeys('Qa X \\ Y .', "xt")
+ call assert_equal(['X \\', "Y"], getline(1, 2))
+endfunc
+
+" Testing implicit print command
+func Test_implicit_print()
+ new
+ call setline(1, ['one', 'two', 'three'])
+ call feedkeys('Q:let a=execute(":1,2")', 'xt')
+ call feedkeys('Q:let b=execute(":3")', 'xt')
+ call assert_equal('one two', a->split('\n')->join(' '))
+ call assert_equal('three', b->split('\n')->join(' '))
+ bw!
+endfunc
+
+" Test inserting text after the trailing bar
+func Test_insert_after_trailing_bar()
+ new
+ call feedkeys("Qi|\nfoo\n.\na|bar\nbar\n.\nc|baz\n.", "xt")
+ call assert_equal(['', 'foo', 'bar', 'baz'], getline(1, '$'))
+ bwipe!
+endfunc
+
+" Test global insert of a newline without terminating period
+func Test_global_insert_newline()
+ new
+ call setline(1, ['foo'])
+ call feedkeys("Qg/foo/i\\\n", "xt")
+ call assert_equal(['', 'foo'], getline(1, '$'))
+ bwipe!
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_excmd.vim b/src/testdir/test_excmd.vim
index 221ceb0..3b7e489 100644
--- a/src/testdir/test_excmd.vim
+++ b/src/testdir/test_excmd.vim
@@ -703,6 +703,8 @@ func Test_address_line_overflow()
call setline(1, range(100))
call assert_fails('|.44444444444444444444444', 'E1247:')
call assert_fails('|.9223372036854775806', 'E1247:')
+ call assert_fails('.44444444444444444444444d', 'E1247:')
+ call assert_equal(range(100)->map('string(v:val)'), getline(1, '$'))
$
yank 77777777777777777777
diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim
index d0a078f..1e6c39e 100644
--- a/src/testdir/test_filetype.vim
+++ b/src/testdir/test_filetype.vim
@@ -95,6 +95,7 @@ def s:GetFilenameChecks(): dict<list<string>>
aml: ['file.aml'],
ampl: ['file.run'],
ant: ['build.xml'],
+ antlr4: ['parser.g4'],
apache: ['.htaccess', '/etc/httpd/file.conf', '/etc/apache2/sites-2/file.com', '/etc/apache2/some.config', '/etc/apache2/conf.file/conf', '/etc/apache2/mods-some/file', '/etc/apache2/sites-some/file', '/etc/httpd/conf.d/file.config', '/etc/apache2/conf.file/file', '/etc/apache2/file.conf', '/etc/apache2/file.conf-file', '/etc/apache2/mods-file/file', '/etc/apache2/sites-file/file', '/etc/apache2/sites-file/file.com', '/etc/httpd/conf.d/file.conf', '/etc/httpd/conf.d/file.conf-file', 'access.conf', 'access.conf-file', 'any/etc/apache2/conf.file/file', 'any/etc/apache2/file.conf', 'any/etc/apache2/file.conf-file', 'any/etc/apache2/mods-file/file', 'any/etc/apache2/sites-file/file', 'any/etc/apache2/sites-file/file.com', 'any/etc/httpd/conf.d/file.conf', 'any/etc/httpd/conf.d/file.conf-file', 'any/etc/httpd/file.conf', 'apache.conf', 'apache.conf-file', 'apache2.conf', 'apache2.conf-file', 'httpd.conf', 'httpd.conf-file', 'srm.conf', 'srm.conf-file', '/etc/httpd/mods-some/file', '/etc/httpd/sites-some/file', '/etc/httpd/conf.file/conf'],
apachestyle: ['/etc/proftpd/file.config,/etc/proftpd/conf.file/file', '/etc/proftpd/conf.file/file', '/etc/proftpd/file.conf', '/etc/proftpd/file.conf-file', 'any/etc/proftpd/conf.file/file', 'any/etc/proftpd/file.conf', 'any/etc/proftpd/file.conf-file', 'proftpd.conf', 'proftpd.conf-file'],
applescript: ['file.scpt'],
@@ -106,6 +107,7 @@ def s:GetFilenameChecks(): dict<list<string>>
asn: ['file.asn', 'file.asn1'],
asterisk: ['asterisk/file.conf', 'asterisk/file.conf-file', 'some-asterisk/file.conf', 'some-asterisk/file.conf-file'],
astro: ['file.astro'],
+ asy: ['file.asy'],
atlas: ['file.atl', 'file.as'],
authzed: ['schema.zed'],
autohotkey: ['file.ahk'],
@@ -121,7 +123,7 @@ def s:GetFilenameChecks(): dict<list<string>>
beancount: ['file.beancount'],
bib: ['file.bib'],
bicep: ['file.bicep', 'file.bicepparam'],
- bindzone: ['named.root', '/bind/db.file', '/named/db.file', 'any/bind/db.file', 'any/named/db.file'],
+ bindzone: ['named.root', '/bind/db.file', '/named/db.file', 'any/bind/db.file', 'any/named/db.file', 'foobar.zone'],
bitbake: ['file.bb', 'file.bbappend', 'file.bbclass', 'build/conf/local.conf', 'meta/conf/layer.conf', 'build/conf/bbappend.conf', 'meta-layer/conf/distro/foo.conf'],
blade: ['file.blade.php'],
blank: ['file.bl'],
@@ -142,6 +144,7 @@ def s:GetFilenameChecks(): dict<list<string>>
cdl: ['file.cdl'],
cdrdaoconf: ['/etc/cdrdao.conf', '/etc/defaults/cdrdao', '/etc/default/cdrdao', '.cdrdao', 'any/etc/cdrdao.conf', 'any/etc/default/cdrdao', 'any/etc/defaults/cdrdao'],
cdrtoc: ['file.toc'],
+ cedar: ['file.cedar'],
cf: ['file.cfm', 'file.cfi', 'file.cfc'],
cfengine: ['cfengine.conf'],
cfg: ['file.hgrc', 'filehgrc', 'hgrc', 'some-hgrc'],
@@ -160,7 +163,7 @@ def s:GetFilenameChecks(): dict<list<string>>
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'],
+ cobol: ['file.cbl', 'file.cob'],
coco: ['file.atg'],
conaryrecipe: ['file.recipe'],
conf: ['auto.master', 'file.conf', 'texdoc.cnf', '.x11vncrc', '.chktexrc', '.ripgreprc', 'ripgreprc', 'file.ctags', '.mbsyncrc'],
@@ -222,11 +225,11 @@ def s:GetFilenameChecks(): dict<list<string>>
'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'],
+ dracula: ['file.drac', 'file.drc', 'file.lvs', 'file.lpe', 'drac.file'],
dtd: ['file.dtd'],
dtrace: ['/usr/lib/dtrace/io.d'],
dts: ['file.dts', 'file.dtsi', 'file.dtso', 'file.its', 'file.keymap'],
- dune: ['jbuild', 'dune', 'dune-project', 'dune-workspace'],
+ dune: ['jbuild', 'dune', 'dune-project', 'dune-workspace', 'dune-file'],
dylan: ['file.dylan'],
dylanintr: ['file.intr'],
dylanlid: ['file.lid'],
@@ -256,6 +259,7 @@ def s:GetFilenameChecks(): dict<list<string>>
factor: ['file.factor'],
falcon: ['file.fal'],
fan: ['file.fan', 'file.fwt'],
+ faust: ['file.dsp', 'file.lib'],
fennel: ['file.fnl'],
fetchmail: ['.fetchmailrc'],
fgl: ['file.4gl', 'file.4gh', 'file.m4gl'],
@@ -285,17 +289,18 @@ def s:GetFilenameChecks(): dict<list<string>>
gitattributes: ['file.git/info/attributes', '.gitattributes', '/.config/git/attributes', '/etc/gitattributes', '/usr/local/etc/gitattributes', 'some.git/info/attributes'] + WhenConfigHome('$XDG_CONFIG_HOME/git/attributes'),
gitcommit: ['COMMIT_EDITMSG', 'MERGE_MSG', 'TAG_EDITMSG', 'NOTES_EDITMSG', 'EDIT_DESCRIPTION'],
gitconfig: ['file.git/config', 'file.git/config.worktree', 'file.git/worktrees/x/config.worktree', '.gitconfig', '.gitmodules', 'file.git/modules//config', '/.config/git/config', '/etc/gitconfig', '/usr/local/etc/gitconfig', '/etc/gitconfig.d/file', 'any/etc/gitconfig.d/file', '/.gitconfig.d/file', 'any/.config/git/config', 'any/.gitconfig.d/file', 'some.git/config', 'some.git/modules/any/config'] + WhenConfigHome('$XDG_CONFIG_HOME/git/config'),
- gitignore: ['file.git/info/exclude', '.gitignore', '/.config/git/ignore', 'some.git/info/exclude'] + WhenConfigHome('$XDG_CONFIG_HOME/git/ignore'),
+ gitignore: ['file.git/info/exclude', '.gitignore', '/.config/git/ignore', 'some.git/info/exclude'] + WhenConfigHome('$XDG_CONFIG_HOME/git/ignore') + ['.prettierignore'],
gitolite: ['gitolite.conf', '/gitolite-admin/conf/file', 'any/gitolite-admin/conf/file'],
gitrebase: ['git-rebase-todo'],
gitsendemail: ['.gitsendemail.msg.xxxxxx'],
gkrellmrc: ['gkrellmrc', 'gkrellmrc_x'],
gleam: ['file.gleam'],
- glsl: ['file.glsl'],
+ glsl: ['file.glsl', 'file.vert', 'file.tesc', 'file.tese', 'file.geom', 'file.frag', 'file.comp', 'file.rgen', 'file.rmiss', 'file.rchit', 'file.rahit', 'file.rint', 'file.rcall'],
gn: ['file.gn', 'file.gni'],
gnash: ['gnashrc', '.gnashrc', 'gnashpluginrc', '.gnashpluginrc'],
gnuplot: ['file.gpi', '.gnuplot', 'file.gnuplot', '.gnuplot_history'],
go: ['file.go'],
+ goaccess: ['goaccess.conf'],
gomod: ['go.mod'],
gosum: ['go.sum', 'go.work.sum'],
gowork: ['go.work'],
@@ -332,6 +337,7 @@ def s:GetFilenameChecks(): dict<list<string>>
hoon: ['file.hoon'],
hostconf: ['/etc/host.conf', 'any/etc/host.conf'],
hostsaccess: ['/etc/hosts.allow', '/etc/hosts.deny', 'any/etc/hosts.allow', 'any/etc/hosts.deny'],
+ # file.component.html should be HTML, not Angular, see #13594
html: ['file.html', 'file.htm', 'file.cshtml', 'file.component.html'],
htmlm4: ['file.html.m4'],
httest: ['file.htt', 'file.htb'],
@@ -364,7 +370,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', 'file.jupyterlab-settings', '.prettierrc', '.firebaserc', '.stylelintrc', '.lintstagedrc', 'file.slnf', 'file.sublime-project', 'file.sublime-settings', 'file.sublime-workspace', 'file.bd', 'file.bda', 'file.xci', 'flake.lock'],
+ json: ['file.json', 'file.jsonp', 'file.json-patch', 'file.geojson', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', 'file.jupyterlab-settings',
+ '.prettierrc', '.firebaserc', '.stylelintrc', '.lintstagedrc', 'file.slnf', 'file.sublime-project', 'file.sublime-settings', 'file.sublime-workspace',
+ 'file.bd', 'file.bda', 'file.xci', 'flake.lock', 'pack.mcmeta', 'deno.lock'],
json5: ['file.json5'],
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'],
@@ -383,6 +391,7 @@ def s:GetFilenameChecks(): dict<list<string>>
lace: ['file.ace', 'file.ACE'],
latte: ['file.latte', 'file.lte'],
ld: ['file.ld', 'any/usr/lib/aarch64-xilinx-linux/ldscripts/aarch64elf32b.x'],
+ ldapconf: ['ldap.conf', '.ldaprc', 'ldaprc'],
ldif: ['file.ldif'],
lean: ['file.lean'],
ledger: ['file.ldg', 'file.ledger', 'file.journal'],
@@ -420,18 +429,19 @@ def s:GetFilenameChecks(): dict<list<string>>
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'],
- make: ['file.mk', 'file.mak', 'file.dsp', 'makefile', 'Makefile', 'makefile-file', 'Makefile-file', 'some-makefile', 'some-Makefile', 'Kbuild'],
+ make: ['file.mk', 'file.mak', 'makefile', 'Makefile', 'makefile-file', 'Makefile-file', 'some-makefile', 'some-Makefile', 'Kbuild'],
mallard: ['file.page'],
man: ['file.man'],
manconf: ['/etc/man.conf', 'man.config', 'any/etc/man.conf'],
map: ['file.map'],
maple: ['file.mv', 'file.mpl', 'file.mws'],
markdown: ['file.markdown', 'file.mdown', 'file.mkd', 'file.mkdn', 'file.mdwn', 'file.md'],
- mason: ['file.mason', 'file.mhtml', 'file.comp'],
+ mason: ['file.mason', 'file.mhtml'],
master: ['file.mas', 'file.master'],
matlab: ['file.m'],
maxima: ['file.demo', 'file.dmt', 'file.dm1', 'file.dm2', 'file.dm3',
'file.wxm', 'maxima-init.mac'],
+ mediawiki: ['file.mw', 'file.wiki'],
mel: ['file.mel'],
mermaid: ['file.mmd', 'file.mmdc', 'file.mermaid'],
meson: ['meson.build', 'meson.options', 'meson_options.txt'],
@@ -466,7 +476,7 @@ def s:GetFilenameChecks(): dict<list<string>>
mgp: ['file.mgp'],
mib: ['file.mib', 'file.my'],
mix: ['file.mix', 'file.mixal'],
- mma: ['file.nb'],
+ mma: ['file.nb', 'file.wl'],
mmp: ['file.mmp'],
modconf: ['/etc/modules.conf', '/etc/modules', '/etc/conf.modules', '/etc/modprobe.file', 'any/etc/conf.modules', 'any/etc/modprobe.file', 'any/etc/modules', 'any/etc/modules.conf'],
modula3: ['file.m3', 'file.mg', 'file.i3', 'file.ig', 'file.lm3'],
@@ -522,7 +532,7 @@ def s:GetFilenameChecks(): dict<list<string>>
odin: ['file.odin'],
omnimark: ['file.xom', 'file.xin'],
ondir: ['.ondirrc'],
- opam: ['opam', 'file.opam', 'file.opam.template'],
+ opam: ['opam', 'file.opam', 'file.opam.template', 'opam.locked', 'file.opam.locked'],
openroad: ['file.or'],
openscad: ['file.scad'],
openvpn: ['file.ovpn', '/etc/openvpn/client/client.conf', '/usr/share/openvpn/examples/server.conf'],
@@ -645,7 +655,8 @@ def s:GetFilenameChecks(): dict<list<string>>
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', 'file.mdd', 'file.cygport'],
+ 'user-dirs.defaults', 'user-dirs.dirs', 'makepkg.conf', '.makepkg.conf', 'file.mdd', 'file.cygport', '.env', '.envrc', 'devscripts.conf',
+ '.devscripts'],
sieve: ['file.siv', 'file.sieve'],
sil: ['file.sil'],
simula: ['file.sim'],
@@ -759,7 +770,7 @@ def s:GetFilenameChecks(): dict<list<string>>
teraterm: ['file.ttl'],
terminfo: ['file.ti'],
'terraform-vars': ['file.tfvars'],
- 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.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'],
+ 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.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', 'file.pdf_tex'],
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'],
@@ -854,6 +865,8 @@ def s:GetFilenameChecks(): dict<list<string>>
z8a: ['file.z8a'],
zathurarc: ['zathurarc'],
zig: ['file.zig', 'build.zig.zon'],
+ ziggy: ['file.ziggy'],
+ ziggy_schema: ['file.ziggy-schema'],
zimbu: ['file.zu'],
zimbutempl: ['file.zut'],
zserio: ['file.zs'],
@@ -1043,7 +1056,8 @@ func Test_emptybuf_ftdetect()
call assert_equal('', &filetype)
filetype detect
call assert_equal('sh', &filetype)
- close!
+ " close the swapfile
+ bw!
endfunc
" Test for ':filetype indent on' and ':filetype indent off' commands
@@ -1567,6 +1581,73 @@ func Test_hook_file()
filetype off
endfunc
+func Test_html_file()
+ filetype on
+
+ " HTML Angular
+ let content = ['@for (item of items; track item.name) {', ' <li> {{ item.name }}</li>', '} @empty {', ' <li> There are no items.</li>', '}']
+ call writefile(content, 'Xfile.html', 'D')
+ split Xfile.html
+ call assert_equal('htmlangular', &filetype)
+ bwipe!
+
+ " Django Template
+ let content = ['{% if foobar %}',
+ \ ' <ul>',
+ \ ' {% for question in list %}',
+ \ ' <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>',
+ \ ' {% endfor %}',
+ \ ' </ul>',
+ \ '{% else %}',
+ \ ' <p>No polls are available.</p>',
+ \ '{% endif %}']
+ call writefile(content, 'Xfile.html', 'D')
+ split Xfile.html
+ call assert_equal('htmldjango', &filetype)
+ bwipe!
+
+ " Super html layout
+ let content = ['<extend template="base.shtml">',
+ \ '<title id="title" var="$page.title"></title>',
+ \ '<head id="head"></head>',
+ \ '<div id="content">',
+ \ '</div>']
+ call writefile(content, 'Xfile.shtml', 'D')
+ split Xfile.shtml
+ call assert_equal('superhtml', &filetype)
+ bwipe!
+
+ " Super html template
+ let content = ['<!DOCTYPE html>',
+ \ '<html>',
+ \ ' <head id="head">',
+ \ ' <title id="title">',
+ \ ' <super>',
+ \ ' suffix',
+ \ ' </title>',
+ \ ' <super>',
+ \ ' </head>',
+ \ ' <body>',
+ \ ' <div id="content">',
+ \ ' <super>',
+ \ ' </div>',
+ \ ' </body>',
+ \ '</html>']
+ call writefile(content, 'Xfile.shtml', 'D')
+ split Xfile.shtml
+ call assert_equal('superhtml', &filetype)
+ bwipe!
+
+ " regular HTML
+ let content = ['<!DOCTYPE html>', '<html>', ' <head>Foobar</head>', ' <body>Content', ' </body>', '</html>']
+ call writefile(content, 'Xfile.html', 'D')
+ split Xfile.html
+ call assert_equal('html', &filetype)
+ bwipe!
+
+ filetype off
+endfunc
+
func Test_m_file()
filetype on
@@ -2401,6 +2482,32 @@ func Test_typ_file()
filetype off
endfunc
+func Test_dsp_file()
+ filetype on
+
+ " Microsoft Developer Studio Project file
+
+ call writefile(['# Microsoft Developer Studio Project File'], 'Xfile.dsp', 'D')
+ split Xfile.dsp
+ call assert_equal('make', &filetype)
+ bwipe!
+
+ let g:filetype_dsp = 'make'
+ split test.dsp
+ call assert_equal('make', &filetype)
+ bwipe!
+ unlet g:filetype_dsp
+
+ " Faust
+
+ call writefile(['this is a fallback'], 'Xfile.dsp')
+ split Xfile.dsp
+ call assert_equal('faust', &filetype)
+ bwipe!
+
+ filetype off
+endfunc
+
func Test_vba_file()
filetype on
@@ -2509,4 +2616,86 @@ func Test_uci_file()
filetype off
endfunc
+func Test_pro_file()
+ filetype on
+
+ "Prolog
+ call writefile([':-module(test/1,'], 'Xfile.pro', 'D')
+ split Xfile.pro
+ call assert_equal('prolog', &filetype)
+ bwipe!
+
+ call writefile(['% comment'], 'Xfile.pro', 'D')
+ split Xfile.pro
+ call assert_equal('prolog', &filetype)
+ bwipe!
+
+ call writefile(['/* multiline comment'], 'Xfile.pro', 'D')
+ split Xfile.pro
+ call assert_equal('prolog', &filetype)
+ bwipe!
+
+ call writefile(['rule(test, 1.7).'], 'Xfile.pro', 'D')
+ split Xfile.pro
+ call assert_equal('prolog', &filetype)
+ bwipe!
+
+ " IDL
+ call writefile(['x = findgen(100)/10'], 'Xfile.pro', 'D')
+ split Xfile.pro
+ call assert_equal('idlang', &filetype)
+
+ filetype off
+endfunc
+
+
+func Test_pl_file()
+ filetype on
+
+ "Prolog
+ call writefile([':-module(test/1,'], 'Xfile.pl', 'D')
+ split Xfile.pl
+ call assert_equal('prolog', &filetype)
+ bwipe!
+
+ call writefile(['% comment'], 'Xfile.pl', 'D')
+ split Xfile.pl
+ call assert_equal('prolog', &filetype)
+ bwipe!
+
+ call writefile(['/* multiline comment'], 'Xfile.pl', 'D')
+ split Xfile.pl
+ call assert_equal('prolog', &filetype)
+ bwipe!
+
+ call writefile(['rule(test, 1.7).'], 'Xfile.pl', 'D')
+ split Xfile.pl
+ call assert_equal('prolog', &filetype)
+ bwipe!
+
+ " Perl
+ call writefile(['%data = (1, 2, 3);'], 'Xfile.pl', 'D')
+ split Xfile.pl
+ call assert_equal('perl', &filetype)
+
+ filetype off
+endfunc
+
+func Test_make_file()
+ filetype on
+
+ " Microsoft Makefile
+ call writefile(['# Makefile for Windows', '!if "$(VIMDLL)" == "yes"'], 'XMakefile.mak', 'D')
+ split XMakefile.mak
+ call assert_equal(1, get(b:, 'make_microsoft', 0))
+ bwipe!
+
+ call writefile(['# get the list of tests', 'include testdir/Make_all.mak'], 'XMakefile.mak', 'D')
+ split XMakefile.mak
+ call assert_equal(0, get(b:, 'make_microsoft', 0))
+ bwipe!
+
+ filetype off
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_findfile.vim b/src/testdir/test_findfile.vim
index 20d5096..a5e18b9 100644
--- a/src/testdir/test_findfile.vim
+++ b/src/testdir/test_findfile.vim
@@ -98,14 +98,48 @@ func Test_findfile()
" Test upwards search with stop-directory.
cd Xdir2
+ let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/Xdir3/', -1)
+ call assert_equal(1, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
+ let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/Xdir3', -1)
+ call assert_equal(1, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
+ let l = findfile('bar', ';../', -1)
+ call assert_equal(1, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
+ let l = findfile('bar', ';..', -1)
+ call assert_equal(1, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
+
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/', -1)
call assert_equal(1, len(l))
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
+ let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2', -1)
+ call assert_equal(1, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
+ let l = findfile('bar', ';../../', -1)
+ call assert_equal(1, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
+ let l = findfile('bar', ';../..', -1)
+ call assert_equal(1, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/', -1)
call assert_equal(2, len(l))
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
call assert_match('.*/Xfinddir1/bar', l[1])
+ let l = findfile('bar', ';' . save_dir . '/Xfinddir1', -1)
+ call assert_equal(2, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
+ call assert_match('.*/Xfinddir1/bar', l[1])
+ let l = findfile('bar', ';../../../', -1)
+ call assert_equal(2, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
+ call assert_match('.*/Xfinddir1/bar', l[1])
+ let l = findfile('bar', ';../../..', -1)
+ call assert_equal(2, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
+ call assert_match('.*/Xfinddir1/bar', l[1])
" Test combined downwards and upwards search from Xdir2/.
cd ../..
@@ -133,6 +167,7 @@ func Test_finddir()
let save_shellslash = &shellslash
let save_dir = getcwd()
set path=,,
+ set shellslash
call CreateFiles()
cd Xfinddir1
diff --git a/src/testdir/test_fnamemodify.vim b/src/testdir/test_fnamemodify.vim
index c19f464..4e61343 100644
--- a/src/testdir/test_fnamemodify.vim
+++ b/src/testdir/test_fnamemodify.vim
@@ -14,6 +14,8 @@ func Test_fnamemodify()
call assert_equal($HOME .. "/foo" , fnamemodify('~/foo', ':p'))
call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/../', ':p'))
call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/..', ':p'))
+ call assert_equal(fnamemodify('.', ':p:h:h') .. '/', fnamemodify('../', ':p'))
+ call assert_equal(fnamemodify('.', ':p:h:h') .. '/', fnamemodify('..', ':p'))
call assert_equal('test.out', fnamemodify('test.out', ':.'))
call assert_equal('a', fnamemodify('../testdir/a', ':.'))
call assert_equal('~/testdir/test.out', fnamemodify('test.out', ':~'))
diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim
index dedc4a2..17487a5 100644
--- a/src/testdir/test_fold.vim
+++ b/src/testdir/test_fold.vim
@@ -1914,4 +1914,39 @@ func Test_foldexpr_end_fold()
bwipe!
endfunc
+" Test moving cursor down to or beyond start of folded end of buffer.
+func Test_cursor_down_fold_eob()
+ call setline(1, range(1, 4))
+ norm Gzf2kj
+ call assert_equal(2, line('.'))
+ norm zojzc
+ call assert_equal(3, line('.'))
+ norm j
+ call assert_equal(3, line('.'))
+ norm k2j
+ call assert_equal(4, line('.'))
+ bwipe!
+endfunc
+
+" issue: #15455
+func Test_cursor_fold_marker_undo()
+ new
+ call setline(1, ['{{{', '', 'This is a Line', '', 'This is a Line', '', '}}}'])
+ let &ul=&ul
+ setl foldmethod=marker
+ call cursor(2, 1)
+ norm! zo1vjdu
+ call assert_equal(1, foldlevel('.'))
+ bwipe!
+ new
+ call setline(1, ['', '{{{', '', 'This is a Line', '', 'This is a Line', '', '}}}'])
+ let &ul=&ul
+ setl foldmethod=marker
+ call cursor(3, 1)
+ norm! zo
+ norm! vjdu
+ call assert_equal(1, foldlevel('.'))
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index acdb954..1021d05 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -923,6 +923,10 @@ func Test_mode()
call feedkeys("gQ\<Insert>\<F2>vi\<CR>", 'xt')
call assert_equal("c-cvr", g:current_modes)
+ " Commandline mode in Visual mode should return "c-c", never "v-v".
+ call feedkeys("v\<Cmd>call input('')\<CR>\<F2>\<CR>\<Esc>", 'xt')
+ call assert_equal("c-c", g:current_modes)
+
" Executing commands in Vim Ex mode should return "cv", never "cvr",
" as Cmdline editing has already ended.
call feedkeys("gQcall Save_mode()\<CR>vi\<CR>", 'xt')
@@ -3822,6 +3826,29 @@ func Test_glob2()
endif
endfunc
+func Test_glob_symlinks()
+ call writefile([], 'Xglob1')
+
+ if has("win32")
+ silent !mklink XglobBad DoesNotExist
+ if v:shell_error
+ throw 'Skipped: cannot create symlinks'
+ endif
+ silent !mklink XglobOk Xglob1
+ else
+ silent !ln -s DoesNotExist XglobBad
+ silent !ln -s Xglob1 XglobOk
+ endif
+
+ " The broken symlink is excluded when alllinks is false.
+ call assert_equal(['Xglob1', 'XglobBad', 'XglobOk'], sort(glob('Xglob*', 0, 1, 1)))
+ call assert_equal(['Xglob1', 'XglobOk'], sort(glob('Xglob*', 0, 1, 0)))
+
+ call delete('Xglob1')
+ call delete('XglobBad')
+ call delete('XglobOk')
+endfunc
+
" Test for browse()
func Test_browse()
CheckFeature browse
@@ -3842,11 +3869,6 @@ func Test_default_arg_value()
call assert_equal('msg', HasDefault())
endfunc
-" Test for gettext()
-func Test_gettext()
- call assert_fails('call gettext(1)', 'E1174:')
-endfunc
-
func Test_builtin_check()
call assert_fails('let g:["trim"] = {x -> " " .. x}', 'E704:')
call assert_fails('let g:.trim = {x -> " " .. x}', 'E704:')
diff --git a/src/testdir/test_gettext.vim b/src/testdir/test_gettext.vim
new file mode 100644
index 0000000..a990121
--- /dev/null
+++ b/src/testdir/test_gettext.vim
@@ -0,0 +1,18 @@
+source check.vim
+
+CheckFeature gettext
+
+" Test for gettext()
+func Test_gettext()
+ call assert_fails('call bindtextdomain("test")', 'E119:')
+ call assert_fails('call bindtextdomain("vim", "test")', 'E475:')
+
+ call assert_fails('call gettext(1)', 'E1174:')
+ call assert_equal('xxxTESTxxx', gettext("xxxTESTxxx"))
+
+ call assert_equal('xxxTESTxxx', gettext("xxxTESTxxx", "vim"))
+ call assert_equal('xxxTESTxxx', gettext("xxxTESTxxx", "__PACKAGE__"))
+ call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__"))
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_gettext_cp1251.vim b/src/testdir/test_gettext_cp1251.vim
new file mode 100644
index 0000000..69d2bbf
--- /dev/null
+++ b/src/testdir/test_gettext_cp1251.vim
@@ -0,0 +1,35 @@
+source check.vim
+" This fail on CI MacOS 14 because bindtextdomain() is not available there
+" (missing library?)
+CheckNotMac
+CheckFeature gettext
+
+" Test for gettext()
+func Test_gettext()
+ set encoding=cp1251
+ call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__"))
+
+ try
+ call assert_true(bindtextdomain("__PACKAGE__", getcwd()))
+
+ try
+ language messages ru_RU
+ call assert_equal('ÎØÈÁÊÀ: ', gettext("ERROR: ", "__PACKAGE__"))
+ catch /^Vim\%((\a\+)\)\=:E197:/
+ throw "Skipped: not possible to set locale to ru (missing?)"
+ endtry
+
+ try
+ language messages en_GB.UTF-8
+ call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__"))
+ catch /^Vim\%((\a\+)\)\=:E197:/
+ throw "Skipped: not possible to set locale to en (missing?)"
+ endtry
+
+ catch /^Vim\%((\a\+)\)\=:E342:/
+ throw "Skipped: out of memory executing bindtextdomain()"
+ endtry
+ set encoding&
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_gettext_make.vim b/src/testdir/test_gettext_make.vim
new file mode 100644
index 0000000..1242fa4
--- /dev/null
+++ b/src/testdir/test_gettext_make.vim
@@ -0,0 +1,72 @@
+source check.vim
+CheckNotMac
+CheckFeature gettext
+
+" Test for package translation Makefile
+func Test_gettext_makefile()
+ cd ../po
+ if has('win32')
+ if getenv('GETTEXT_PATH') == v:null
+ throw 'Skipped: %GETTEXT_PATH% is not set.'
+ endif
+ call system('nmake.exe -f Make_mvc.mak "VIMPROG=' .. getenv('VIMPROG') ..
+ \ '" "GETTEXT_PATH=' .. getenv('GETTEXT_PATH') ..
+ \ '" PLUGPACKAGE=test_gettext
+ \ "PO_PLUG_INPUTLIST=..\testdir\test_gettext_makefile_in1.vim
+ \ ..\testdir\test_gettext_makefile_in2.vim
+ \ ..\testdir\test_gettext_makefile_in3.vim
+ \ ..\testdir\test_gettext_makefile_in4.vim" test_gettext.pot')
+ else
+" Will it work on macOS?
+ call system("make -f Makefile PLUGPACKAGE=test_gettext
+ \ PO_PLUG_INPUTLIST=\"../testdir/test_gettext_makefile_in1.vim
+ \ ../testdir/test_gettext_makefile_in2.vim
+ \ ../testdir/test_gettext_makefile_in3.vim
+ \ ../testdir/test_gettext_makefile_in4.vim\" test_gettext.pot")
+ endif
+ if v:shell_error != 0
+ throw 'Fail to create test_gettext.pot. Error code: ' .. v:shell_error
+ endif
+ let expected =<< trim END
+ # SOME DESCRIPTIVE TITLE.
+ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+ # This file is distributed under the same license as the test_gettext package.
+ # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+ #
+ #, fuzzy
+ msgid ""
+ msgstr ""
+ "Project-Id-Version: test_gettext\n"
+ "Report-Msgid-Bugs-To: \n"
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+ "Language-Team: LANGUAGE <LL@li.org>\n"
+ "Language: \n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=CHARSET\n"
+ "Content-Transfer-Encoding: 8bit\n"
+
+ #: ../testdir/test_gettext_makefile_in1.vim:4 ../testdir/test_gettext_makefile_in1.vim:6
+ #: ../testdir/test_gettext_makefile_in2.vim:5 ../testdir/test_gettext_makefile_in4.vim:4
+ msgid "This is a test"
+ msgstr ""
+
+ #: ../testdir/test_gettext_makefile_in1.vim:5
+ msgid "This is another test"
+ msgstr ""
+
+ #: ../testdir/test_gettext_makefile_in2.vim:4
+ msgid "This is a test from the second file"
+ msgstr ""
+
+ #: ../testdir/test_gettext_makefile_in4.vim:5
+ msgid "This is a fourth test"
+ msgstr ""
+ END
+ let potfile = filter(readfile("test_gettext.pot"), 'v:val !~ "POT-Creation-Date"')
+ call assert_equal(expected, potfile)
+ call delete('test_gettext.pot')
+ cd -
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_gettext_makefile_in1.vim b/src/testdir/test_gettext_makefile_in1.vim
new file mode 100644
index 0000000..cbe1159
--- /dev/null
+++ b/src/testdir/test_gettext_makefile_in1.vim
@@ -0,0 +1,7 @@
+" Test file for gettext() package makefile
+" Last Change: 2024 Jun 01
+
+echo gettext("This is a test", "test_gettext")
+echo gettext("This is another test", "test_gettext")
+echo gettext("This is a test", "test_gettext")
+" vim: ts=8
diff --git a/src/testdir/test_gettext_makefile_in2.vim b/src/testdir/test_gettext_makefile_in2.vim
new file mode 100644
index 0000000..86d3dd9
--- /dev/null
+++ b/src/testdir/test_gettext_makefile_in2.vim
@@ -0,0 +1,6 @@
+" Test file for gettext() package makefile
+" Last Change: 2024 Jun 01
+
+echo gettext("This is a test from the second file", "test_gettext")
+echo gettext("This is a test", "test_gettext")
+" vim: ts=8
diff --git a/src/testdir/test_gettext_makefile_in3.vim b/src/testdir/test_gettext_makefile_in3.vim
new file mode 100644
index 0000000..f4cf93d
--- /dev/null
+++ b/src/testdir/test_gettext_makefile_in3.vim
@@ -0,0 +1,4 @@
+" Test file for gettext() package makefile
+" Last Change: 2024 Jun 01
+
+" vim: ts=8
diff --git a/src/testdir/test_gettext_makefile_in4.vim b/src/testdir/test_gettext_makefile_in4.vim
new file mode 100644
index 0000000..7f9f3f7
--- /dev/null
+++ b/src/testdir/test_gettext_makefile_in4.vim
@@ -0,0 +1,6 @@
+" Test file for gettext() package makefile
+" Last Change: 2024 Jun 01
+
+echo gettext("This is a test", "test_gettext")
+echo gettext("This is a fourth test", "test_gettext")
+" vim: ts=8
diff --git a/src/testdir/test_gettext_utf8.vim b/src/testdir/test_gettext_utf8.vim
new file mode 100644
index 0000000..b96f8ea
--- /dev/null
+++ b/src/testdir/test_gettext_utf8.vim
@@ -0,0 +1,35 @@
+source check.vim
+" This fail on CI MacOS 14 because bindtextdomain() is not available there
+" (missing library?)
+CheckNotMac
+CheckFeature gettext
+
+" Test for gettext()
+func Test_gettext()
+ set encoding=utf-8
+ call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__"))
+
+ try
+ call assert_true(bindtextdomain("__PACKAGE__", getcwd()))
+
+ try
+ language messages ru_RU
+ call assert_equal('ОШИБКÐ: ', gettext("ERROR: ", "__PACKAGE__"))
+ catch /^Vim\%((\a\+)\)\=:E197:/
+ throw "Skipped: not possible to set locale to ru (missing?)"
+ endtry
+
+ try
+ language messages en_GB.UTF-8
+ call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__"))
+ catch /^Vim\%((\a\+)\)\=:E197:/
+ throw "Skipped: not possible to set locale to en (missing?)"
+ endtry
+
+ catch /^Vim\%((\a\+)\)\=:E342:/
+ throw "Skipped: out of memory executing bindtextdomain()"
+ endtry
+ set encoding&
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_getvar.vim b/src/testdir/test_getvar.vim
index 2065186..6efb192 100644
--- a/src/testdir/test_getvar.vim
+++ b/src/testdir/test_getvar.vim
@@ -142,20 +142,28 @@ func Test_get_func()
let l:F = function('tr')
call assert_equal('tr', get(l:F, 'name'))
call assert_equal(l:F, get(l:F, 'func'))
+ call assert_equal({'required': 3, 'optional': 0, 'varargs': v:false},
+ \ get(l:F, 'arity'))
let Fb_func = function('s:FooBar')
call assert_match('<SNR>\d\+_FooBar', get(Fb_func, 'name'))
+ call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false},
+ \ get(Fb_func, 'arity'))
let Fb_ref = funcref('s:FooBar')
call assert_match('<SNR>\d\+_FooBar', get(Fb_ref, 'name'))
+ call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false},
+ \ get(Fb_ref, 'arity'))
call assert_equal({'func has': 'no dict'}, get(l:F, 'dict', {'func has': 'no dict'}))
call assert_equal(0, get(l:F, 'dict'))
call assert_equal([], get(l:F, 'args'))
+
let NF = test_null_function()
call assert_equal('', get(NF, 'name'))
call assert_equal(NF, get(NF, 'func'))
call assert_equal(0, get(NF, 'dict'))
call assert_equal([], get(NF, 'args'))
+ call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false}, get(NF, 'arity'))
endfunc
" get({partial}, {what} [, {default}]) - in test_partial.vim
diff --git a/src/testdir/test_goto.vim b/src/testdir/test_goto.vim
index 357a8d2..b6a6695 100644
--- a/src/testdir/test_goto.vim
+++ b/src/testdir/test_goto.vim
@@ -296,6 +296,7 @@ func Test_gd_string()
return x;
}
[CODE]
+
call XTest_goto_decl('gd', lines, 4, 7)
endfunc
@@ -320,14 +321,16 @@ func Test_set_options_keep_col()
let pos = getcurpos()
normal j
set invhlsearch spell spelllang=en,cjk spelloptions=camel textwidth=80
- set cursorline cursorcolumn cursorlineopt=line colorcolumn=+1
+ set cursorline cursorcolumn cursorlineopt=line colorcolumn=+1 winfixbuf
+ set comments=:# commentstring=#%s define=function
set background=dark
set background=light
normal k
call assert_equal(pos, getcurpos())
bwipe!
set hlsearch& spell& spelllang& spelloptions& textwidth&
- set cursorline& cursorcolumn& cursorlineopt& colorcolumn&
+ set cursorline& cursorcolumn& cursorlineopt& colorcolumn& winfixbuf&
+ set comments& commentstring& define&
set background&
endfunc
diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim
index d53750f..ae65310 100644
--- a/src/testdir/test_gui.vim
+++ b/src/testdir/test_gui.vim
@@ -1708,7 +1708,8 @@ func Test_gui_lowlevel_keyevent()
new
" Test for <Ctrl-A> to <Ctrl-Z> keys
- for kc in range(65, 90)
+ " FIXME: <Ctrl-C> is excluded for now. It makes the test flaky.
+ for kc in range(65, 66) + range(68, 90)
call SendKeys([0x11, kc])
try
let ch = getcharstr()
diff --git a/src/testdir/test_increment.vim b/src/testdir/test_increment.vim
index fdd7c0c..3a5f5ee 100644
--- a/src/testdir/test_increment.vim
+++ b/src/testdir/test_increment.vim
@@ -840,6 +840,44 @@ func Test_increment_unsigned()
set nrformats-=unsigned
endfunc
+" Try incrementing/decrementing a number when nrformats contains blank
+func Test_increment_blank()
+ set nrformats+=blank
+
+ " Signed
+ call setline(1, '0')
+ exec "norm! gg0\<C-X>"
+ call assert_equal('-1', getline(1))
+
+ call setline(1, '3')
+ exec "norm! gg010\<C-X>"
+ call assert_equal('-7', getline(1))
+
+ call setline(1, '-0')
+ exec "norm! gg0\<C-X>"
+ call assert_equal("-1", getline(1))
+
+ " Unsigned
+ " NOTE: 18446744073709551615 == 2^64 - 1
+ call setline(1, 'a-18446744073709551615')
+ exec "norm! gg0\<C-A>"
+ call assert_equal('a-18446744073709551615', getline(1))
+
+ call setline(1, 'a-18446744073709551615')
+ exec "norm! gg0\<C-A>"
+ call assert_equal('a-18446744073709551615', getline(1))
+
+ call setline(1, 'a-18446744073709551614')
+ exec "norm! gg08\<C-A>"
+ call assert_equal('a-18446744073709551615', getline(1))
+
+ call setline(1, 'a-1')
+ exec "norm! gg0\<C-A>"
+ call assert_equal('a-2', getline(1))
+
+ set nrformats-=blank
+endfunc
+
func Test_in_decrement_large_number()
" NOTE: 18446744073709551616 == 2^64
call setline(1, '18446744073709551616')
diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim
index 48589ce..aee3393 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -2586,9 +2586,85 @@ func Test_complete_fuzzy_match()
call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
call assert_equal('hello help hero h', getline('.'))
+ set completeopt-=noinsert
+ call setline(1, ['xyz yxz x'])
+ call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('xyz yxz xyz', getline('.'))
+ " can fuzzy get yxz when use Ctrl-N twice
+ call setline(1, ['xyz yxz x'])
+ call feedkeys("A\<C-X>\<C-N>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('xyz yxz yxz', getline('.'))
+
+ call setline(1, ['你好 你'])
+ call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('你好 你好', getline('.'))
+ call setline(1, ['你的 我的 的'])
+ call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('你的 我的 你的', getline('.'))
+ " can fuzzy get multiple-byte word when use Ctrl-N twice
+ call setline(1, ['你的 我的 的'])
+ call feedkeys("A\<C-X>\<C-N>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('你的 我的 我的', getline('.'))
+
+ " respect wrapscan
+ set nowrapscan
+ call setline(1, ["xyz", "yxz", ""])
+ call cursor(3, 1)
+ call feedkeys("Sy\<C-X>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('y', getline('.'))
+ set wrapscan
+ call feedkeys("Sy\<C-X>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('xyz', getline('.'))
+
+ " fuzzy on file
+ call writefile([''], 'fobar', 'D')
+ call writefile([''], 'foobar', 'D')
+ call setline(1, ['fob'])
+ call cursor(1, 1)
+ call feedkeys("A\<C-X>\<C-f>\<Esc>0", 'tx!')
+ call assert_equal('fobar', getline('.'))
+ call feedkeys("Sfob\<C-X>\<C-f>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('foobar', getline('.'))
+ call feedkeys("S../\<C-X>\<C-f>\<Esc>0", 'tx!')
+ call assert_match('../*', getline('.'))
+ call feedkeys("S../td\<C-X>\<C-f>\<Esc>0", 'tx!')
+ call assert_match('../testdir', getline('.'))
+
+ " can get completion from other buffer
+ set completeopt=fuzzy,menu,menuone
+ vnew
+ call setline(1, ["completeness,", "compatibility", "Composite", "Omnipotent"])
+ wincmd p
+ call feedkeys("Somp\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('completeness', getline('.'))
+ call feedkeys("Somp\<C-N>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('compatibility', getline('.'))
+ call feedkeys("Somp\<C-P>\<Esc>0", 'tx!')
+ call assert_equal('Omnipotent', getline('.'))
+ call feedkeys("Somp\<C-P>\<C-P>\<Esc>0", 'tx!')
+ call assert_equal('Composite', getline('.'))
+ call feedkeys("S omp\<C-N>\<Esc>0", 'tx!')
+ call assert_equal(' completeness', getline('.'))
+
+ " fuzzy on whole line completion
+ call setline(1, ["world is on fire", "no one can save me but you", 'user can execute', ''])
+ call cursor(4, 1)
+ call feedkeys("Swio\<C-X>\<C-L>\<Esc>0", 'tx!')
+ call assert_equal('world is on fire', getline('.'))
+ call feedkeys("Su\<C-X>\<C-L>\<C-P>\<Esc>0", 'tx!')
+ call assert_equal('no one can save me but you', getline('.'))
+
+ " issue #15526
+ set completeopt=fuzzy,menuone,menu,noselect
+ call setline(1, ['Text', 'ToText', ''])
+ call cursor(2, 1)
+ call feedkeys("STe\<C-X>\<C-N>x\<CR>\<Esc>0", 'tx!')
+ call assert_equal('Tex', getline('.'))
+
" clean up
set omnifunc=
bw!
+ bw!
set complete& completeopt&
autocmd! AAAAA_Group
augroup! AAAAA_Group
@@ -2599,6 +2675,38 @@ func Test_complete_fuzzy_match()
unlet g:word
endfunc
+func Test_complete_fuzzy_with_completeslash()
+ CheckMSWindows
+
+ call writefile([''], 'fobar', 'D')
+ let orig_shellslash = &shellslash
+ set cpt&
+ new
+ set completeopt+=fuzzy
+ set noshellslash
+
+ " Test with completeslash unset
+ set completeslash=
+ call setline(1, ['.\fob'])
+ call feedkeys("A\<C-X>\<C-F>\<Esc>0", 'tx!')
+ call assert_equal('.\fobar', getline('.'))
+
+ " Test with completeslash=backslash
+ set completeslash=backslash
+ call feedkeys("S.\\fob\<C-X>\<C-F>\<Esc>0", 'tx!')
+ call assert_equal('.\fobar', getline('.'))
+
+ " Test with completeslash=slash
+ set completeslash=slash
+ call feedkeys("S.\\fob\<C-X>\<C-F>\<Esc>0", 'tx!')
+ call assert_equal('./fobar', getline('.'))
+
+ " Reset and clean up
+ let &shellslash = orig_shellslash
+ set completeslash=
+ %bw!
+endfunc
+
" Check that tie breaking is stable for completeopt+=fuzzy (which should
" behave the same on different platforms).
func Test_complete_fuzzy_match_tie()
@@ -2619,4 +2727,14 @@ func Test_complete_fuzzy_match_tie()
set completeopt&
endfunc
+func Test_complete_backwards_default()
+ new
+ call append(1, ['foobar', 'foobaz'])
+ new
+ call feedkeys("i\<c-p>", 'tx')
+ call assert_equal('foobaz', getline('.'))
+ bw!
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
diff --git a/src/testdir/test_jumplist.vim b/src/testdir/test_jumplist.vim
index 8fbf39f..4b9fcee 100644
--- a/src/testdir/test_jumplist.vim
+++ b/src/testdir/test_jumplist.vim
@@ -59,29 +59,63 @@ func Test_getjumplist()
call assert_equal(4, l[1])
endfunc
-func Test_jumplist_invalid()
+func Test_jumplist_wipe_buf()
new
clearjumps
- " put some randome text
- put ='a'
- let prev = bufnr('%')
+ " Put some random text and fill the jump list.
+ call setline(1, ['foo', 'bar', 'baz'])
+ normal G
+ normal gg
setl nomodified bufhidden=wipe
e XXJumpListBuffer
- let bnr = bufnr('%')
- " 1) empty jumplist
- let expected = [[
- \ {'lnum': 2, 'bufnr': prev, 'col': 0, 'coladd': 0}], 1]
- call assert_equal(expected, getjumplist())
+ " The jump list is empty as the buffer was wiped out.
+ call assert_equal([[], 0], getjumplist())
let jumps = execute(':jumps')
call assert_equal('>', jumps[-1:])
- " now jump back
- exe ":norm! \<c-o>"
- let expected = [[
- \ {'lnum': 2, 'bufnr': prev, 'col': 0, 'coladd': 0},
- \ {'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0}], 0]
- call assert_equal(expected, getjumplist())
- let jumps = execute(':jumps')
- call assert_match('> 0 2 0 -invalid-', jumps)
+
+ " Put some random text and fill the jump list.
+ call setline(1, ['foo', 'bar', 'baz'])
+ setl bufhidden=hide
+
+ " References to wiped buffer are deleted with multiple tabpages.
+ let [w1, t1] = [win_getid(), tabpagenr()]
+ clearjumps
+ normal G
+ normal gg
+ enew
+
+ split XXJumpListBuffer
+ let [w2, t2] = [win_getid(), tabpagenr()]
+ clearjumps
+ normal G
+ normal gg
+ enew
+
+ tabnew XXJumpListBuffer
+ let [w3, t3] = [win_getid(), tabpagenr()]
+ clearjumps
+ normal G
+ normal gg
+ enew
+
+ split XXJumpListBuffer
+ let [w4, t4] = [win_getid(), tabpagenr()]
+ clearjumps
+ normal G
+ normal gg
+ enew
+
+ for [w, t] in [[w1, t1], [w2, t2], [w3, t3], [w4, t4]]
+ call assert_equal(2, len(getjumplist(w, t)[0]))
+ endfor
+
+ bwipe! XXJumpListBuffer
+
+ for [w, t] in [[w1, t1], [w2, t2], [w3, t3], [w4, t4]]
+ call assert_equal(0, len(getjumplist(w, t)[0]))
+ endfor
+
+ %bwipe!
endfunc
" Test for '' mark in an empty buffer
diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim
index 12a6dd4..48217cf 100644
--- a/src/testdir/test_listdict.vim
+++ b/src/testdir/test_listdict.vim
@@ -1147,6 +1147,19 @@ func Test_listdict_compare()
call assert_fails('echo {} =~ {}', 'E736:')
endfunc
+func Test_recursive_listdict_compare()
+ let l1 = [0, 1]
+ let l1[0] = l1
+ let l2 = [0, 1]
+ let l2[0] = l2
+ call assert_true(l1 == l2)
+ let d1 = {0: 0, 1: 1}
+ let d1[0] = d1
+ let d2 = {0: 0, 1: 1}
+ let d2[0] = d2
+ call assert_true(d1 == d2)
+endfunc
+
" compare complex recursively linked list and dict
func Test_listdict_compare_complex()
let lines =<< trim END
@@ -1557,4 +1570,83 @@ func Test_extendnew_leak()
for i in range(100) | silent! call extendnew({}, {}, {}) | endfor
endfunc
+" Test for comparing deeply nested List/Dict values
+func Test_deep_nested_listdict_compare()
+ let lines =<< trim END
+ def GetNestedList(sz: number): list<any>
+ var l: list<any> = []
+ var x: list<any> = l
+ for i in range(sz)
+ var y: list<any> = [1]
+ add(x, y)
+ x = y
+ endfor
+ return l
+ enddef
+
+ VAR l1 = GetNestedList(1000)
+ VAR l2 = GetNestedList(999)
+ call assert_false(l1 == l2)
+
+ #" after 1000 nested items, the lists are considered to be equal
+ VAR l3 = GetNestedList(1001)
+ VAR l4 = GetNestedList(1002)
+ call assert_true(l3 == l4)
+ END
+ call v9.CheckLegacyAndVim9Success(lines)
+
+ let lines =<< trim END
+ def GetNestedDict(sz: number): dict<any>
+ var d: dict<any> = {}
+ var x: dict<any> = d
+ for i in range(sz)
+ var y: dict<any> = {}
+ x['a'] = y
+ x = y
+ endfor
+ return d
+ enddef
+
+ VAR d1 = GetNestedDict(1000)
+ VAR d2 = GetNestedDict(999)
+ call assert_false(d1 == d2)
+
+ #" after 1000 nested items, the Dicts are considered to be equal
+ VAR d3 = GetNestedDict(1001)
+ VAR d4 = GetNestedDict(1002)
+ call assert_true(d3 == d4)
+ END
+ call v9.CheckLegacyAndVim9Success(lines)
+endfunc
+
+" Test for using id()
+def Test_id_with_dict()
+ # demonstate a way that "id(item)" differs from "string(item)"
+ var d1 = {one: 1}
+ var d2 = {one: 1}
+ var d3 = {one: 1}
+ var idDict: dict<any>
+ idDict[id(d1)] = d1
+ idDict[id(d2)] = d2
+ idDict[id(d3)] = d3
+ assert_equal(3, idDict->len())
+
+ var stringDict: dict<any>
+ stringDict[string(d1)] = d1
+ stringDict[string(d2)] = d2
+ stringDict[string(d3)] = d3
+ assert_equal(1, stringDict->len())
+
+ assert_equal('', id(3))
+
+ assert_equal('', id(null))
+ assert_equal('', id(null_blob))
+ assert_equal('', id(null_dict))
+ assert_equal('', id(null_function))
+ assert_equal('', id(null_list))
+ assert_equal('', id(null_partial))
+ assert_equal('', id(null_string))
+ assert_equal('', id(null_channel))
+ assert_equal('', id(null_job))
+enddef
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_listlbr_utf8.vim b/src/testdir/test_listlbr_utf8.vim
index 313ff30..693f201 100644
--- a/src/testdir/test_listlbr_utf8.vim
+++ b/src/testdir/test_listlbr_utf8.vim
@@ -280,6 +280,9 @@ func Test_chinese_char_on_wrap_column()
call s:compare_lines(expect, lines)
call assert_equal(len(expect), winline())
call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
+ norm! g0
+ call assert_equal(len(expect), winline())
+ call assert_equal(1, wincol())
call s:close_windows()
endfunc
@@ -315,6 +318,9 @@ func Test_chinese_char_on_wrap_column_sbr()
call s:compare_lines(expect, lines)
call assert_equal(len(expect), winline())
call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
+ norm! g0
+ call assert_equal(len(expect), winline())
+ call assert_equal(4, wincol())
call s:close_windows()
endfunc
diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim
index 1175310..064f8ac 100644
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -1767,6 +1767,49 @@ func Test_unmap_simplifiable()
unmap <C-I>
endfunc
+" Test that the first byte of rhs is not remapped if rhs starts with lhs.
+func Test_map_rhs_starts_with_lhs()
+ new
+ func MapExpr()
+ return "\<C-R>\<C-P>"
+ endfunc
+
+ for expr in [v:false, v:true]
+ if expr
+ imap <buffer><expr> <C-R> MapExpr()
+ else
+ imap <buffer> <C-R> <C-R><C-P>
+ endif
+
+ for restore in [v:false, v:true]
+ if restore
+ let saved = maparg('<C-R>', 'i', v:false, v:true)
+ iunmap <buffer> <C-R>
+ call mapset(saved)
+ endif
+
+ let @a = 'foo'
+ call assert_nobeep('call feedkeys("S\<C-R>a", "tx")')
+ call assert_equal('foo', getline('.'))
+
+ let @a = 'bar'
+ call assert_nobeep('call feedkeys("S\<*C-R>a", "tx")')
+ call assert_equal('bar', getline('.'))
+ endfor
+ endfor
+
+ " When two mappings are used for <C-I> and <Tab>, remapping should work.
+ imap <buffer> <C-I> <Tab>bar
+ imap <buffer> <Tab> foo
+ call feedkeys("S\<Tab>", 'xt')
+ call assert_equal('foo', getline('.'))
+ call feedkeys("S\<*C-I>", 'xt')
+ call assert_equal('foobar', getline('.'))
+
+ delfunc MapExpr
+ bwipe!
+endfunc
+
func Test_expr_map_escape_special()
nnoremap … <Cmd>let g:got_ellipsis += 1<CR>
func Func()
diff --git a/src/testdir/test_matchparen.vim b/src/testdir/test_matchparen.vim
index 70aa38f..49d3510 100644
--- a/src/testdir/test_matchparen.vim
+++ b/src/testdir/test_matchparen.vim
@@ -108,5 +108,35 @@ func Test_matchparen_pum_clear()
call StopVimInTerminal(buf)
endfunc
+" Test that matchparen works with multibyte chars in 'matchpairs'
+func Test_matchparen_mbyte()
+ CheckScreendump
+
+ let lines =<< trim END
+ source $VIMRUNTIME/plugin/matchparen.vim
+ call setline(1, ['aaaaaaaa(', 'bbbb)cc'])
+ set matchpairs+=(:)
+ END
+
+ call writefile(lines, 'XmatchparenMbyte', 'D')
+ let buf = RunVimInTerminal('-S XmatchparenMbyte', #{rows: 10})
+ call VerifyScreenDump(buf, 'Test_matchparen_mbyte_1', {})
+ call term_sendkeys(buf, "$")
+ call VerifyScreenDump(buf, 'Test_matchparen_mbyte_2', {})
+ call term_sendkeys(buf, "j")
+ call VerifyScreenDump(buf, 'Test_matchparen_mbyte_3', {})
+ call term_sendkeys(buf, "2h")
+ call VerifyScreenDump(buf, 'Test_matchparen_mbyte_4', {})
+ call term_sendkeys(buf, "0")
+ call VerifyScreenDump(buf, 'Test_matchparen_mbyte_5', {})
+ call term_sendkeys(buf, "kA")
+ call VerifyScreenDump(buf, 'Test_matchparen_mbyte_6', {})
+ call term_sendkeys(buf, "\<Down>")
+ call VerifyScreenDump(buf, 'Test_matchparen_mbyte_7', {})
+ call term_sendkeys(buf, "\<C-W>")
+ call VerifyScreenDump(buf, 'Test_matchparen_mbyte_8', {})
+
+ call StopVimInTerminal(buf)
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_menu.vim b/src/testdir/test_menu.vim
index 2229228..40fec40 100644
--- a/src/testdir/test_menu.vim
+++ b/src/testdir/test_menu.vim
@@ -481,13 +481,48 @@ func Test_popup_menu()
unmenu PopUp
endfunc
+func Test_popup_menu_truncated()
+ CheckNotGui
+
+ set mouse=a mousemodel=popup
+ aunmenu PopUp
+ for i in range(2 * &lines)
+ exe $'menu PopUp.{i} <Cmd>let g:res = {i}<CR>'
+ endfor
+
+ func LeftClickExpr(row, col)
+ call test_setmouse(a:row, a:col)
+ return "\<LeftMouse>"
+ endfunc
+
+ " Clicking at the bottom should place popup menu above click position.
+ " <RightRelease> should not select an item immediately.
+ let g:res = -1
+ call test_setmouse(&lines, 1)
+ nnoremap <expr><F2> LeftClickExpr(4, 1)
+ call feedkeys("\<RightMouse>\<RightRelease>\<F2>", 'tx')
+ call assert_equal(3, g:res)
+
+ " Clicking at the top should place popup menu below click position.
+ let g:res = -1
+ call test_setmouse(1, 1)
+ nnoremap <expr><F2> LeftClickExpr(5, 1)
+ call feedkeys("\<RightMouse>\<RightRelease>\<F2>", 'tx')
+ call assert_equal(3, g:res)
+
+ nunmap <F2>
+ delfunc LeftClickExpr
+ unlet g:res
+ aunmenu PopUp
+ set mouse& mousemodel&
+endfunc
+
" Test for MenuPopup autocommand
func Test_autocmd_MenuPopup()
CheckNotGui
- set mouse=a
- set mousemodel=popup
- aunmenu *
+ set mouse=a mousemodel=popup
+ aunmenu PopUp
autocmd MenuPopup * exe printf(
\ 'anoremenu PopUp.Foo <Cmd>let g:res = ["%s", "%s"]<CR>',
\ expand('<afile>'), expand('<amatch>'))
diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim
index 83594d2..398bf29 100644
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -4257,6 +4257,9 @@ func Test_page_cursor_topbot()
call assert_equal(18, line('.'))
exe "norm! \<C-B>\<C-F>"
call assert_equal(9, line('.'))
+ " Not when already at the start of the buffer.
+ exe "norm! ggj\<C-B>"
+ call assert_equal(2, line('.'))
bwipe!
endfunc
diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim
index fbfbaae..94c98fe 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -548,6 +548,9 @@ func Test_set_completion_string_values()
call assert_equal('sync', getcompletion('set swapsync=', 'cmdline')[1])
call assert_equal('usetab', getcompletion('set switchbuf=', 'cmdline')[1])
call assert_equal('ignore', getcompletion('set tagcase=', 'cmdline')[1])
+ if exists('+tabclose')
+ call assert_equal('left uselast', join(sort(getcompletion('set tabclose=', 'cmdline'))), ' ')
+ endif
if exists('+termwintype')
call assert_equal('conpty', getcompletion('set termwintype=', 'cmdline')[1])
endif
@@ -1407,7 +1410,8 @@ func Test_write()
set nowrite
call assert_fails('write Xwrfile', 'E142:')
set write
- close!
+ " close swapfile
+ bw!
endfunc
" Test for 'buftype' option
@@ -1724,7 +1728,7 @@ func Test_VIM_POSIX()
qall
[CODE]
if RunVim([], after, '')
- call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\.;',
+ call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>#{|&/\.;',
\ 'AS'], readfile('X_VIM_POSIX'))
endif
@@ -1734,7 +1738,7 @@ func Test_VIM_POSIX()
qall
[CODE]
if RunVim([], after, '')
- call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;',
+ call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>;',
\ 'S'], readfile('X_VIM_POSIX'))
endif
diff --git a/src/testdir/test_partial.vim b/src/testdir/test_partial.vim
index b5a58f6..acc8b73 100644
--- a/src/testdir/test_partial.vim
+++ b/src/testdir/test_partial.vim
@@ -311,6 +311,11 @@ func Test_auto_partial_rebind()
endfunc
func Test_get_partial_items()
+ func s:Qux(x, y, z=3, w=1, ...)
+ endfunc
+ func s:Qux1(x, y)
+ endfunc
+
let dict = {'name': 'hello'}
let args = ["foo", "bar"]
let Func = function('MyDictFunc')
@@ -331,6 +336,23 @@ func Test_get_partial_items()
let dict = {'partial has': 'no dict'}
call assert_equal(dict, get(P, 'dict', dict))
call assert_equal(0, get(l:P, 'dict'))
+
+ call assert_equal({'required': 2, 'optional': 2, 'varargs': v:true},
+ \ get(funcref('s:Qux', []), 'arity'))
+ call assert_equal({'required': 1, 'optional': 2, 'varargs': v:true},
+ \ get(funcref('s:Qux', [1]), 'arity'))
+ call assert_equal({'required': 0, 'optional': 2, 'varargs': v:true},
+ \ get(funcref('s:Qux', [1, 2]), 'arity'))
+ call assert_equal({'required': 0, 'optional': 1, 'varargs': v:true},
+ \ get(funcref('s:Qux', [1, 2, 3]), 'arity'))
+ call assert_equal({'required': 0, 'optional': 0, 'varargs': v:true},
+ \ get(funcref('s:Qux', [1, 2, 3, 4]), 'arity'))
+ " More args than expected is not an error
+ call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false},
+ \ get(funcref('s:Qux1', [1, 2, 3, 4]), 'arity'))
+
+ delfunc s:Qux
+ delfunc s:Qux1
endfunc
func Test_compare_partials()
diff --git a/src/testdir/test_paste.vim b/src/testdir/test_paste.vim
index d079f48..b35fc81 100644
--- a/src/testdir/test_paste.vim
+++ b/src/testdir/test_paste.vim
@@ -93,7 +93,7 @@ func Test_paste_ex_mode()
call assert_equal("foo\rbar", foo)
" pasting more than 40 bytes
- exe "norm Q\<PasteStart>0000000000000000000000000000000000000000000000000000000000000000000000\<C-C>"
+ exe "norm Q\<PasteStart>s/.*/0000000000000000000000000000000000000000000000000000000000000000/\<C-C>"
endfunc
func Test_paste_onechar()
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
index dd01a57..fe958da 100644
--- a/src/testdir/test_popup.vim
+++ b/src/testdir/test_popup.vim
@@ -1482,8 +1482,101 @@ func Test_pum_highlights_match()
call term_sendkeys(buf, "o\<BS>\<C-R>=Comp()\<CR>")
call VerifyScreenDump(buf, 'Test_pum_highlights_09', {})
+ " issue #15095 wrong select
+ call term_sendkeys(buf, "\<ESC>:set completeopt=fuzzy,menu\<CR>")
+ call TermWait(buf)
+ call term_sendkeys(buf, "S hello helio hero h\<C-X>\<C-P>")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_10', {})
+
+ call term_sendkeys(buf, "\<ESC>S hello helio hero h\<C-X>\<C-P>\<C-P>")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_11', {})
+
+ " issue #15357
+ call term_sendkeys(buf, "\<ESC>S/non_exit_folder\<C-X>\<C-F>")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_15', {})
+
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
+ call TermWait(buf)
+
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_pum_user_hl_group()
+ CheckScreendump
+ let lines =<< trim END
+ func CompleteFunc( findstart, base )
+ if a:findstart
+ return 0
+ endif
+ return {
+ \ 'words': [
+ \ { 'word': 'aword1', 'menu': 'extra text 1', 'kind': 'W', 'hl_group': 'StrikeFake' },
+ \ { 'word': 'aword2', 'menu': 'extra text 2', 'kind': 'W', },
+ \ { 'word': '你好', 'menu': 'extra text 3', 'kind': 'W', 'hl_group': 'StrikeFake' },
+ \]}
+ endfunc
+ set completeopt=menu
+ set completefunc=CompleteFunc
+
+ hi StrikeFake ctermfg=9
+ func HlMatch()
+ hi PmenuMatchSel ctermfg=6 ctermbg=7 cterm=underline
+ hi PmenuMatch ctermfg=4 ctermbg=225 cterm=underline
+ endfunc
+ END
+ call writefile(lines, 'Xscript', 'D')
+ let buf = RunVimInTerminal('-S Xscript', {})
+
+ call TermWait(buf)
+ call term_sendkeys(buf, "Saw\<C-X>\<C-U>")
+ call VerifyScreenDump(buf, 'Test_pum_highlights_12', {})
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
+
+ call TermWait(buf)
+ call term_sendkeys(buf, ":call HlMatch()\<CR>")
+
+ call TermWait(buf)
+ call term_sendkeys(buf, "Saw\<C-X>\<C-U>")
+ call VerifyScreenDump(buf, 'Test_pum_highlights_13', {})
+ call term_sendkeys(buf, "\<C-N>")
+ call VerifyScreenDump(buf, 'Test_pum_highlights_14', {})
call term_sendkeys(buf, "\<C-E>\<Esc>")
+
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_pum_user_kind_hlgroup()
+ CheckScreendump
+ let lines =<< trim END
+ func CompleteFunc( findstart, base )
+ if a:findstart
+ return 0
+ endif
+ return {
+ \ 'words': [
+ \ { 'word': 'aword1', 'menu': 'extra text 1', 'kind': 'variable', 'kind_hlgroup': 'KindVar', 'hl_group': 'StrikeFake' },
+ \ { 'word': 'aword2', 'menu': 'extra text 2', 'kind': 'function', 'kind_hlgroup': 'KindFunc' },
+ \ { 'word': '你好', 'menu': 'extra text 3', 'kind': 'class', 'kind_hlgroup': 'KindClass' },
+ \]}
+ endfunc
+ set completeopt=menu
+ set completefunc=CompleteFunc
+
+ hi StrikeFake ctermfg=9
+ hi KindVar ctermfg=yellow
+ hi KindFunc ctermfg=blue
+ hi KindClass ctermfg=green
+ END
+ call writefile(lines, 'Xscript', 'D')
+ let buf = RunVimInTerminal('-S Xscript', {})
+
call TermWait(buf)
+ call term_sendkeys(buf, "S\<C-X>\<C-U>")
+ call VerifyScreenDump(buf, 'Test_pum_highlights_16', {})
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
call StopVimInTerminal(buf)
endfunc
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index a397f70..64aa654 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -2499,6 +2499,88 @@ func Test_popup_settext_null()
call popup_close(id)
endfunc
+func Test_popup_setbuf()
+ CheckScreendump
+
+ let lines =<< trim END
+ let opts = #{wrap: 0}
+ let p = popup_create('test', opts)
+ let buf = bufnr('%')
+ END
+
+ call writefile(lines, 'XtestPopupSetBuf', 'D')
+ let buf = RunVimInTerminal('-S XtestPopupSetBuf', #{rows: 10})
+ call VerifyScreenDump(buf, 'Test_popup_setbuf_01', {})
+
+ " Setting to an non-existing buffer doesn't do anything
+ call term_sendkeys(buf, ":call popup_setbuf(p, 'foobar.txt')\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_setbuf_02', {})
+
+ " Error
+ call term_sendkeys(buf, ":call popup_setbuf(p, ['a','b','c'])\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_setbuf_03', {})
+
+ " Set to help window
+ call term_sendkeys(buf, ":help\<CR>")
+ call term_sendkeys(buf, ":call popup_setbuf(p, 'help.txt')\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_setbuf_04', {})
+
+ " Setting back to original buffer
+ call term_sendkeys(buf, ":call popup_setbuf(p, buf)\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_setbuf_05', {})
+
+ " use method
+ call term_sendkeys(buf, ":echo p->popup_setbuf('help.txt')\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_setbuf_06', {})
+
+ call term_sendkeys(buf, ":echo p->popup_setbuf(buf)\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_setbuf_05', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_popup_setbuf_terminal()
+ CheckFeature terminal
+
+ " Check Terminal Feature
+ let termbuf = term_start(&shell, #{hidden: 1})
+ " Wait for shell to start
+ call WaitForAssert({-> assert_equal("run", job_status(term_getjob(termbuf)))})
+
+ let popup = popup_create('test', {})
+ call assert_true(popup->popup_setbuf(termbuf))
+ call popup_close(popup)
+
+ let popup1 = popup_create(termbuf, #{minwidth: 40, minheight: 10, border: []})
+
+ let popup = popup_create('test', {})
+ try
+ call assert_fails(call popup_setbuf(popup, termbuf))
+ catch
+ endtry
+ call popup_close(popup)
+ call popup_close(popup1)
+ call assert_equal([], popup_list())
+ " Close the terminal
+ call term_sendkeys(termbuf, "exit\<CR>")
+ " Wait for shell to exit
+ call WaitForAssert({-> assert_equal("dead", job_status(term_getjob(termbuf)))})
+endfunc
+
+func Test_popup_setbuf_null()
+ let id = popup_create('', {})
+ call assert_false(popup_setbuf(id, -1))
+ call popup_close(id)
+
+ let id = popup_create('', {})
+ call assert_true(popup_setbuf(id, test_null_string()))
+ call assert_true(popup_setbuf(id, ''))
+ call popup_close(id)
+
+ call assert_false(popup_setbuf(id, 0))
+endfunc
+
func Test_popup_hidden()
new
diff --git a/src/testdir/test_put.vim b/src/testdir/test_put.vim
index 69c2943..94e4f47 100644
--- a/src/testdir/test_put.vim
+++ b/src/testdir/test_put.vim
@@ -168,10 +168,6 @@ func Test_very_large_count()
endfunc
func Test_very_large_count_64bit()
- if v:sizeoflong < 8
- throw 'Skipped: only works with 64 bit long ints'
- endif
-
new
let @" = repeat('x', 100)
call assert_fails('norm 999999999p', 'E1240:')
@@ -188,10 +184,6 @@ func Test_very_large_count_block()
endfunc
func Test_very_large_count_block_64bit()
- if v:sizeoflong < 8
- throw 'Skipped: only works with 64 bit long ints'
- endif
-
new
call setline(1, repeat('x', 100))
exe "norm \<C-V>$y"
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index 0b61815..47b9b47 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -893,7 +893,7 @@ func Test_helpgrep()
endfunc
def Test_helpgrep_vim9_restore_cpo()
- assert_equal('aABceFs', &cpo)
+ assert_equal('aABceFsz', &cpo)
var rtp_save = &rtp
var dir = 'Xruntime/after'
@@ -905,7 +905,7 @@ def Test_helpgrep_vim9_restore_cpo()
cwindow
silent helpgrep grail
- assert_equal('aABceFs', &cpo)
+ assert_equal('aABceFsz', &cpo)
&rtp = rtp_save
cclose
helpclose
diff --git a/src/testdir/test_regexp_utf8.vim b/src/testdir/test_regexp_utf8.vim
index bc70544..51c0984 100644
--- a/src/testdir/test_regexp_utf8.vim
+++ b/src/testdir/test_regexp_utf8.vim
@@ -587,4 +587,36 @@ func Test_combining_chars_in_collection()
bw!
endfunc
+func Test_search_multibyte_match_ascii()
+ new
+ " Match single 'Å¿' and 's'
+ call setline(1, 'das abc heraus abc Å¿ich abc Å¿ind')
+ for i in range(0, 2)
+ exe "set re="..i
+ let ic_match = matchbufline('%', '\c\%u17f', 1, '$')->mapnew({idx, val -> val.text})
+ let noic_match = matchbufline('%', '\C\%u17f', 1, '$')->mapnew({idx, val -> val.text})
+ call assert_equal(['s', 's', 'Å¿','Å¿'], ic_match, "Ignorecase Regex-engine: " .. &re)
+ call assert_equal(['Å¿','Å¿'], noic_match, "No-Ignorecase Regex-engine: " .. &re)
+ endfor
+ " Match several 'Å¿Å¿' and 'ss'
+ call setline(1, 'das abc herauss abc Å¿Å¿ich abc Å¿ind')
+ for i in range(0, 2)
+ exe "set re="..i
+ let ic_match = matchbufline('%', '\c\%u17f\%u17f', 1, '$')->mapnew({idx, val -> val.text})
+ let noic_match = matchbufline('%', '\C\%u17f\%u17f', 1, '$')->mapnew({idx, val -> val.text})
+ let ic_match2 = matchbufline('%', '\c\%u17f\+', 1, '$')->mapnew({idx, val -> val.text})
+ let noic_match2 = matchbufline('%', '\C\%u17f\+', 1, '$')->mapnew({idx, val -> val.text})
+ let ic_match3 = matchbufline('%', '\c[\u17f]\+', 1, '$')->mapnew({idx, val -> val.text})
+ let noic_match3 = matchbufline('%', '\C[\u17f]\+', 1, '$')->mapnew({idx, val -> val.text})
+
+ call assert_equal(['ss', 'Å¿Å¿'], ic_match, "Ignorecase Regex-engine: " .. &re)
+ call assert_equal(['Å¿Å¿'], noic_match, "No-Ignorecase Regex-engine: " .. &re)
+ call assert_equal(['s', 'ss', 'Å¿Å¿', 'Å¿'], ic_match2, "Ignorecase Regex-engine: " .. &re)
+ call assert_equal(['Å¿Å¿','Å¿'], noic_match2, "No-Ignorecase Regex-engine: " .. &re)
+ call assert_equal(['s', 'ss', 'Å¿Å¿', 'Å¿'], ic_match3, "Ignorecase Collection Regex-engine: " .. &re)
+ call assert_equal(['Å¿Å¿','Å¿'], noic_match3, "No-Ignorecase Collection Regex-engine: " .. &re)
+ endfor
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim
index 1a9f49b..708aca2 100644
--- a/src/testdir/test_search.vim
+++ b/src/testdir/test_search.vim
@@ -1747,6 +1747,37 @@ func Test_search_with_no_last_pat()
call delete('Xresult')
endfunc
+" Test for using the last substitute pattern without last search pattern.
+func Test_search_with_last_substitute_pat()
+ let lines =<< trim [SCRIPT]
+ new
+ set shortmess+=S
+ call setline(1, repeat(['foofoo'], 3))
+ %s/foo/bar/
+ call assert_equal(repeat(['barfoo'], 3), getline(1, '$'))
+
+ call cursor(1, 1)
+ call assert_equal("/foo", execute('call feedkeys("/\r", "tx")', '')->trim())
+ call assert_equal([0, 1, 4, 0], getpos('.'))
+
+ if has('rightleft')
+ set rightleft rightleftcmd=search
+ call cursor(1, 1)
+ call assert_equal("oof/", execute('call feedkeys("/\r", "tx")', '')->trim())
+ call assert_equal([0, 1, 4, 0], getpos('.'))
+ endif
+
+ call writefile(v:errors, 'Xresult')
+ qall!
+ [SCRIPT]
+ call writefile(lines, 'Xscript', 'D')
+
+ if RunVim([], [], '--clean -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+ endif
+ call delete('Xresult')
+endfunc
+
" Test for using tilde (~) atom in search. This should use the last used
" substitute pattern
func Test_search_tilde_pat()
diff --git a/src/testdir/test_selectmode.vim b/src/testdir/test_selectmode.vim
index bf1b52b..63aa0b9 100644
--- a/src/testdir/test_selectmode.vim
+++ b/src/testdir/test_selectmode.vim
@@ -321,4 +321,20 @@ func Test_ins_ctrl_o_in_insert_mode_resets_selectmode()
bwipe!
endfunc
+" Test that an :lmap mapping for a printable keypad key is applied when typing
+" it in Select mode.
+func Test_selectmode_keypad_lmap()
+ new
+ lnoremap <buffer> <kPoint> ???
+ lnoremap <buffer> <kEnter> !!!
+ setlocal iminsert=1
+ call setline(1, 'abcdef')
+ call feedkeys("gH\<kPoint>\<Esc>", 'tx')
+ call assert_equal(['???'], getline(1, '$'))
+ call feedkeys("gH\<kEnter>\<Esc>", 'tx')
+ call assert_equal(['!!!'], getline(1, '$'))
+
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_signs.vim b/src/testdir/test_signs.vim
index 0d76d7a..7f53d62 100644
--- a/src/testdir/test_signs.vim
+++ b/src/testdir/test_signs.vim
@@ -245,7 +245,7 @@ func Test_sign_completion()
call assert_equal('"sign define jump list place undefine unplace', @:)
call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"sign define Sign culhl= icon= linehl= numhl= text= texthl=', @:)
+ call assert_equal('"sign define Sign culhl= icon= linehl= numhl= priority= text= texthl=', @:)
for hl in ['culhl', 'linehl', 'numhl', 'texthl']
call feedkeys(":sign define Sign "..hl.."=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
@@ -1231,6 +1231,25 @@ func Test_sign_priority()
call sign_define("sign1", attr)
call sign_define("sign2", attr)
call sign_define("sign3", attr)
+ let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Search', 'priority': 60}
+ call sign_define("sign4", attr)
+
+ " Test for :sign list
+ let a = execute('sign list')
+ call assert_equal("\nsign sign1 text==> linehl=Search texthl=Search\n" .
+ \ "sign sign2 text==> linehl=Search texthl=Search\n" .
+ \ "sign sign3 text==> linehl=Search texthl=Search\n" .
+ \ "sign sign4 text==> priority=60 linehl=Search texthl=Search", a)
+
+ " Test for sign_getdefined()
+ let s = sign_getdefined()
+ call assert_equal([
+ \ {'name': 'sign1', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'},
+ \ {'name': 'sign2', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'},
+ \ {'name': 'sign3', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'},
+ \ {'name': 'sign4', 'priority': 60, 'texthl': 'Search', 'linehl': 'Search',
+ \ 'text': '=>'}],
+ \ s)
" Place three signs with different priority in the same line
call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D')
@@ -1586,6 +1605,25 @@ func Test_sign_priority()
\ " line=10 id=5 group=g1 name=sign1 priority=20\n", a)
call sign_unplace('*')
+
+ " Test for sign with default priority.
+ call sign_place(1, 'g1', 'sign4', 'Xsign', {'lnum' : 3})
+ sign place 2 line=5 name=sign4 group=g1 file=Xsign
+
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign4', 'lnum' : 3, 'group' : 'g1',
+ \ 'priority' : 60},
+ \ {'id' : 2, 'name' : 'sign4', 'lnum' : 5, 'group' : 'g1',
+ \ 'priority' : 60}],
+ \ s[0].signs)
+
+ let a = execute('sign place group=g1')
+ call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
+ \ " line=3 id=1 group=g1 name=sign4 priority=60\n" .
+ \ " line=5 id=2 group=g1 name=sign4 priority=60\n", a)
+
+ call sign_unplace('*')
call sign_undefine()
enew | only
endfunc
diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim
index 1ddcd83..692e191 100644
--- a/src/testdir/test_spell.vim
+++ b/src/testdir/test_spell.vim
@@ -5,6 +5,7 @@ source check.vim
CheckFeature spell
source screendump.vim
+source view_util.vim
func TearDown()
set nospell
@@ -300,6 +301,20 @@ func Test_compl_with_CTRL_X_CTRL_K_using_spell()
set spell& spelllang& dictionary& ignorecase&
endfunc
+func Test_compl_with_CTRL_X_s()
+ new
+ set spell spelllang=en_us showmode
+ inoremap <buffer><F2> <Cmd>let g:msg = Screenline(&lines)<CR>
+
+ call feedkeys("STheatre\<C-X>s\<F2>\<C-Y>\<Esc>", 'tx')
+ call assert_equal(['Theater'], getline(1, '$'))
+ call assert_match('(^S^N^P)', g:msg)
+
+ bwipe!
+ set spell& spelllang& showmode&
+ unlet g:msg
+endfunc
+
func Test_spellrepall()
new
set spell
diff --git a/src/testdir/test_spellfile.vim b/src/testdir/test_spellfile.vim
index d8d954b..8abb680 100644
--- a/src/testdir/test_spellfile.vim
+++ b/src/testdir/test_spellfile.vim
@@ -845,6 +845,22 @@ func Test_spell_add_word()
%bw!
endfunc
+func Test_spell_add_long_word()
+ set spell spellfile=./Xspellfile.add spelllang=en
+
+ let word = repeat('a', 9000)
+ let v:errmsg = ''
+ " Spell checking doesn't really work for such a long word,
+ " but this should not cause an E1510 error.
+ exe 'spellgood ' .. word
+ call assert_equal('', v:errmsg)
+ call assert_equal([word], readfile('./Xspellfile.add'))
+
+ set spell& spellfile= spelllang& encoding=utf-8
+ call delete('./Xspellfile.add')
+ call delete('./Xspellfile.add.spl')
+endfunc
+
func Test_spellfile_verbose()
call writefile(['1', 'one'], 'XtestVerbose.dic', 'D')
call writefile([], 'XtestVerbose.aff', 'D')
diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim
index afdc104..b25cd60 100644
--- a/src/testdir/test_substitute.vim
+++ b/src/testdir/test_substitute.vim
@@ -806,7 +806,7 @@ func Test_replace_keeppatterns()
a
foobar
-substitute foo asdf
+substitute foo asdf foo
one two
.
@@ -815,21 +815,26 @@ one two
/^substitute
s/foo/bar/
call assert_equal('foo', @/)
- call assert_equal('substitute bar asdf', getline('.'))
+ call assert_equal('substitute bar asdf foo', getline('.'))
/^substitute
keeppatterns s/asdf/xyz/
call assert_equal('^substitute', @/)
- call assert_equal('substitute bar xyz', getline('.'))
+ call assert_equal('substitute bar xyz foo', getline('.'))
+
+ /^substitute
+ &
+ call assert_equal('^substitute', @/)
+ call assert_equal('substitute bar xyz bar', getline('.'))
exe "normal /bar /e\<CR>"
call assert_equal(15, col('.'))
normal -
keeppatterns /xyz
call assert_equal('bar ', @/)
- call assert_equal('substitute bar xyz', getline('.'))
+ call assert_equal('substitute bar xyz bar', getline('.'))
exe "normal 0dn"
- call assert_equal('xyz', getline('.'))
+ call assert_equal('xyz bar', getline('.'))
close!
endfunc
diff --git a/src/testdir/test_tabpage.vim b/src/testdir/test_tabpage.vim
index 3624790..1a40567 100644
--- a/src/testdir/test_tabpage.vim
+++ b/src/testdir/test_tabpage.vim
@@ -965,6 +965,64 @@ func Test_tabpage_alloc_failure()
call assert_equal(1, tabpagenr('$'))
endfunc
+func Test_tabpage_tabclose()
+ " Default behaviour, move to the right.
+ call s:reconstruct_tabpage_for_test(6)
+ norm! 4gt
+ setl tcl=
+ tabclose
+ call assert_equal("n3", bufname())
+
+ " Move to the left.
+ call s:reconstruct_tabpage_for_test(6)
+ norm! 4gt
+ setl tcl=left
+ tabclose
+ call assert_equal("n1", bufname())
+
+ " Move to the last used tab page.
+ call s:reconstruct_tabpage_for_test(6)
+ norm! 5gt
+ norm! 2gt
+ setl tcl=uselast
+ tabclose
+ call assert_equal("n3", bufname())
+
+ " Same, but the last used tab page is invalid. Move to the right.
+ call s:reconstruct_tabpage_for_test(6)
+ norm! 5gt
+ norm! 3gt
+ setl tcl=uselast
+ tabclose 5
+ tabclose!
+ call assert_equal("n2", bufname())
+
+ " Same, but the last used tab page is invalid. Move to the left.
+ call s:reconstruct_tabpage_for_test(6)
+ norm! 5gt
+ norm! 3gt
+ setl tcl=uselast,left
+ tabclose 5
+ tabclose!
+ call assert_equal("n0", bufname())
+
+ " Move left when moving right is not possible.
+ call s:reconstruct_tabpage_for_test(6)
+ setl tcl=
+ norm! 6gt
+ tabclose
+ call assert_equal("n3", bufname())
+
+ " Move right when moving left is not possible.
+ call s:reconstruct_tabpage_for_test(6)
+ setl tcl=left
+ norm! 1gt
+ tabclose
+ call assert_equal("n0", bufname())
+
+ setl tcl&
+endfunc
+
" this was giving ml_get errors
func Test_tabpage_last_line()
enew
diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim
index 432906e..c241937 100644
--- a/src/testdir/test_tagjump.vim
+++ b/src/testdir/test_tagjump.vim
@@ -958,8 +958,63 @@ func Test_tag_stack()
call settagstack(1, {'items' : []})
call assert_fails('pop', 'E73:')
+ " References to wiped buffer are deleted.
+ for i in range(10, 20)
+ edit Xtest
+ exe "tag var" .. i
+ endfor
+ edit Xtest
+
+ let t = gettagstack()
+ call assert_equal(11, t.length)
+ call assert_equal(12, t.curidx)
+
+ bwipe!
+
+ let t = gettagstack()
+ call assert_equal(0, t.length)
+ call assert_equal(1, t.curidx)
+
+ " References to wiped buffer are deleted with multiple tabpages.
+ let w1 = win_getid()
+ call settagstack(1, {'items' : []})
+ for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor
+ enew
+
+ new
+ let w2 = win_getid()
+ call settagstack(1, {'items' : []})
+ for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor
+ enew
+
+ tabnew
+ let w3 = win_getid()
+ call settagstack(1, {'items' : []})
+ for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor
+ enew
+
+ new
+ let w4 = win_getid()
+ call settagstack(1, {'items' : []})
+ for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor
+ enew
+
+ for w in [w1, w2, w3, w4]
+ let t = gettagstack(w)
+ call assert_equal(11, t.length)
+ call assert_equal(12, t.curidx)
+ endfor
+
+ bwipe! Xtest
+
+ for w in [w1, w2, w3, w4]
+ let t = gettagstack(w)
+ call assert_equal(0, t.length)
+ call assert_equal(1, t.curidx)
+ endfor
+
+ %bwipe!
set tags&
- %bwipe
endfunc
" Test for browsing multiple matching tags
diff --git a/src/testdir/test_taglist.vim b/src/testdir/test_taglist.vim
index 2dd2366..c5c7df2 100644
--- a/src/testdir/test_taglist.vim
+++ b/src/testdir/test_taglist.vim
@@ -100,9 +100,9 @@ func Test_tagfiles()
help
let tf = tagfiles()
- " 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
+ " 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?\\?/?'))
@@ -127,6 +127,47 @@ func Test_tagsfile_without_trailing_newline()
set tags&
endfunc
+" Check that specifying a stop directory in 'tags' works properly.
+func Test_tagfiles_stopdir()
+ let save_cwd = getcwd()
+
+ call mkdir('Xtagsdir1/Xtagsdir2/Xtagsdir3', 'pR')
+ call writefile([], 'Xtagsdir1/Xtags', 'D')
+
+ cd Xtagsdir1/
+ let &tags = './Xtags;' .. fnamemodify('..', ':p')
+ call assert_equal(1, len(tagfiles()))
+
+ cd Xtagsdir2/
+ let &tags = './Xtags;' .. fnamemodify('..', ':p')
+ call assert_equal(1, len(tagfiles()))
+
+ cd Xtagsdir3/
+ let &tags = './Xtags;' .. fnamemodify('..', ':p')
+ call assert_equal(0, len(tagfiles()))
+
+ let &tags = './Xtags;../'
+ call assert_equal(0, len(tagfiles()))
+
+ cd ..
+ call assert_equal(1, len(tagfiles()))
+
+ cd ..
+ call assert_equal(1, len(tagfiles()))
+
+ let &tags = './Xtags;..'
+ call assert_equal(1, len(tagfiles()))
+
+ cd Xtagsdir2/
+ call assert_equal(1, len(tagfiles()))
+
+ cd Xtagsdir3/
+ call assert_equal(0, len(tagfiles()))
+
+ set tags&
+ call chdir(save_cwd)
+endfunc
+
" Test for ignoring comments in a tags file
func Test_tagfile_ignore_comments()
call writefile([
diff --git a/src/testdir/test_termcodes.vim b/src/testdir/test_termcodes.vim
index 7e450d9..507753c 100644
--- a/src/testdir/test_termcodes.vim
+++ b/src/testdir/test_termcodes.vim
@@ -2256,6 +2256,17 @@ func Test_modifyOtherKeys_mapped()
iunmap '
iunmap <C-W><C-A>
+
+ " clean buffer
+ %d _
+ imap B b
+ imap BBB blimp
+ let input = repeat(GetEscCodeCSI27('B', 2), 3)
+ call feedkeys("a" .. input .. "\<Esc>", 'Lx!')
+ call assert_equal('blimp', getline(1))
+ " cleanup
+ iunmap BBB
+ iunmap B
set timeoutlen&
endfunc
diff --git a/src/testdir/test_termdebug.vim b/src/testdir/test_termdebug.vim
index a9762df..b5c12ae 100644
--- a/src/testdir/test_termdebug.vim
+++ b/src/testdir/test_termdebug.vim
@@ -63,6 +63,7 @@ func Test_termdebug_basic()
edit XTD_basic.c
Termdebug ./XTD_basic
+ call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))})
call WaitForAssert({-> assert_equal(3, winnr('$'))})
let gdb_buf = winbufnr(1)
wincmd b
@@ -123,13 +124,13 @@ func Test_termdebug_basic()
" 60 is approx spaceBuffer * 3
if winwidth(0) <= 78 + 60
Var
- call assert_equal(winnr(), winnr('$'))
- call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]])
+ call assert_equal(winnr('$'), winnr())
+ call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]], winlayout())
let cn += 1
bw!
Asm
- call assert_equal(winnr(), winnr('$'))
- call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]])
+ call assert_equal(winnr('$'), winnr())
+ call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]], winlayout())
let cn += 1
bw!
endif
@@ -138,16 +139,16 @@ func Test_termdebug_basic()
let winw = winwidth(0)
Var
if winwidth(0) < winw
- call assert_equal(winnr(), winnr('$') - 1)
- call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]])
+ call assert_equal(winnr('$') - 1, winnr())
+ call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]], winlayout())
let cn += 1
bw!
endif
let winw = winwidth(0)
Asm
if winwidth(0) < winw
- call assert_equal(winnr(), winnr('$') - 1)
- call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]])
+ call assert_equal(winnr('$') - 1, winnr())
+ call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]], winlayout())
let cn += 1
bw!
endif
@@ -160,6 +161,19 @@ func Test_termdebug_basic()
call WaitForAssert({-> assert_equal(1, winnr('$'))})
call assert_equal([], sign_getplaced('', #{group: 'TermDebug'})[0].signs)
+ for use_prompt in [v:true, v:false]
+ let g:termdebug_config = {}
+ let g:termdebug_config['use_prompt'] = use_prompt
+ TermdebugCommand ./XTD_basic arg args
+ call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))})
+ call WaitForAssert({-> assert_equal(3, winnr('$'))})
+ wincmd t
+ quit!
+ redraw!
+ call WaitForAssert({-> assert_equal(1, winnr('$'))})
+ unlet g:termdebug_config
+ endfor
+
call s:cleanup_files(bin_name)
%bw!
endfunc
@@ -174,6 +188,7 @@ func Test_termdebug_tbreak()
execute 'edit ' .. src_name
execute 'Termdebug ./' .. bin_name
+ call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))})
call WaitForAssert({-> assert_equal(3, winnr('$'))})
let gdb_buf = winbufnr(1)
wincmd b
@@ -234,6 +249,7 @@ func Test_termdebug_mapping()
call assert_true(maparg('-', 'n', 0, 1)->empty())
call assert_true(maparg('+', 'n', 0, 1)->empty())
Termdebug
+ call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))})
call WaitForAssert({-> assert_equal(3, winnr('$'))})
wincmd b
call assert_false(maparg('K', 'n', 0, 1)->empty())
@@ -256,6 +272,7 @@ func Test_termdebug_mapping()
nnoremap - :echom "-"<cr>
nnoremap + :echom "+"<cr>
Termdebug
+ call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))})
call WaitForAssert({-> assert_equal(3, winnr('$'))})
wincmd b
call assert_false(maparg('K', 'n', 0, 1)->empty())
@@ -278,76 +295,184 @@ func Test_termdebug_mapping()
call assert_equal(':echom "K"<cr>', maparg('K', 'n', 0, 1).rhs)
%bw!
+
+ " -- Test that local-buffer mappings are restored in the correct buffers --
+ " local mappings for foo
+ file foo
nnoremap <buffer> K :echom "bK"<cr>
nnoremap <buffer> - :echom "b-"<cr>
nnoremap <buffer> + :echom "b+"<cr>
+
+ " no mappings for 'bar'
+ enew
+ file bar
+
+ " Start termdebug from foo
+ buffer foo
Termdebug
+ call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))})
call WaitForAssert({-> assert_equal(3, winnr('$'))})
wincmd b
call assert_true(maparg('K', 'n', 0, 1).buffer)
call assert_true(maparg('-', 'n', 0, 1).buffer)
call assert_true(maparg('+', 'n', 0, 1).buffer)
call assert_equal(maparg('K', 'n', 0, 1).rhs, ':echom "bK"<cr>')
+
+ Source
+ buffer bar
+ call assert_false(maparg('K', 'n', 0, 1)->empty())
+ call assert_false(maparg('-', 'n', 0, 1)->empty())
+ call assert_false(maparg('+', 'n', 0, 1)->empty())
+ call assert_true(maparg('K', 'n', 0, 1).buffer->empty())
+ call assert_true(maparg('-', 'n', 0, 1).buffer->empty())
+ call assert_true(maparg('+', 'n', 0, 1).buffer->empty())
wincmd t
quit!
redraw!
call WaitForAssert({-> assert_equal(1, winnr('$'))})
+
+ " Termdebug session ended. Buffer 'bar' shall have no mappings
+ call assert_true(bufname() ==# 'bar')
+ call assert_false(maparg('K', 'n', 0, 1)->empty())
+ call assert_false(maparg('-', 'n', 0, 1)->empty())
+ call assert_false(maparg('+', 'n', 0, 1)->empty())
+ call assert_true(maparg('K', 'n', 0, 1).buffer->empty())
+ call assert_true(maparg('-', 'n', 0, 1).buffer->empty())
+ call assert_true(maparg('+', 'n', 0, 1).buffer->empty())
+
+ " Buffer 'foo' shall have the same mapping as before running the termdebug
+ " session
+ buffer foo
+ call assert_true(bufname() ==# 'foo')
call assert_true(maparg('K', 'n', 0, 1).buffer)
call assert_true(maparg('-', 'n', 0, 1).buffer)
call assert_true(maparg('+', 'n', 0, 1).buffer)
call assert_equal(':echom "bK"<cr>', maparg('K', 'n', 0, 1).rhs)
+ nunmap K
+ nunmap +
+ nunmap -
%bw!
endfunc
-func Test_termdebug_bufnames()
- " Test if user has filename/folders named gdb, Termdebug-gdb-console,
- " etc. in the current directory
+function Test_termdebug_save_restore_variables()
+ " saved mousemodel
+ let &mousemodel=''
+
+ " saved keys
+ nnoremap K :echo "hello world!"<cr>
+ let expected_map_K = maparg('K', 'n', 0 , 1)
+ nnoremap + :echo "hello plus!"<cr>
+ let expected_map_plus = maparg('+', 'n', 0 , 1)
+ let expected_map_minus = {}
+
+ " saved &columns
+ let expected_columns = &columns
+
+ " We want termdebug to overwrite 'K' map but not '+' map.
let g:termdebug_config = {}
- let g:termdebug_config['use_prompt'] = 1
- let filename = 'gdb'
- let replacement_filename = 'Termdebug-gdb-console'
+ let g:termdebug_config['map_K'] = v:true
- call writefile(['This', 'is', 'a', 'test'], filename, 'D')
- " Throw away the file once the test has done.
Termdebug
- " Once termdebug has completed the startup you should have 3 windows on screen
+ call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))})
call WaitForAssert({-> assert_equal(3, winnr('$'))})
- " A file named filename already exists in the working directory,
- " hence you must call the newly created buffer differently
- call WaitForAssert({-> assert_false(bufexists(filename))})
- call WaitForAssert({-> assert_true(bufexists(replacement_filename))})
+ call WaitForAssert({-> assert_match(&mousemodel, 'popup_setpos')})
+ wincmd t
quit!
call WaitForAssert({-> assert_equal(1, winnr('$'))})
- " Check if error message is in :message
- let g:termdebug_config['disasm_window'] = 1
- let filename = 'Termdebug-asm-listing'
- call writefile(['This', 'is', 'a', 'test'], filename, 'D')
- " Check only the head of the error message
- let error_message = "You have a file/folder named '" .. filename .. "'"
- Termdebug
- " Once termdebug has completed the startup you should have 4 windows on screen
- call WaitForAssert({-> assert_equal(4, winnr('$'))})
- call WaitForAssert({-> assert_notequal(-1, stridx(execute('messages'), error_message))})
- quit!
- wincmd b
- wincmd q
- call WaitForAssert({-> assert_equal(1, winnr('$'))})
+ call assert_true(empty(&mousemodel))
+ call assert_true(empty(expected_map_minus))
+ call assert_equal(expected_map_K.rhs, maparg('K', 'n', 0, 1).rhs)
+ call assert_equal(expected_map_plus.rhs, maparg('+', 'n', 0, 1).rhs)
+
+ call assert_equal(expected_columns, &columns)
+
+ nunmap K
+ nunmap +
unlet g:termdebug_config
-endfunc
+endfunction
-function Test_termdebug_save_restore_variables()
- let &mousemodel=''
+function Test_termdebug_sanity_check()
+ " Test if user has filename/folders with wrong names
+ let g:termdebug_config = {}
+ let s:dict = {'disasm_window': 'Termdebug-asm-listing', 'use_prompt': 'gdb', 'variables_window': 'Termdebug-variables-listing'}
+
+ for key in keys(s:dict)
+ let s:filename = s:dict[key]
+ let g:termdebug_config[key] = v:true
+ let s:error_message = "You have a file/folder named '" .. s:filename .. "'"
+
+ " Write dummy file with bad name
+ call writefile(['This', 'is', 'a', 'test'], s:filename, 'D')
+ Termdebug
+ call WaitForAssert({-> assert_true(execute('messages') =~ s:error_message)})
+ call WaitForAssert({-> assert_equal(1, winnr('$'))})
+
+ call delete(s:filename)
+ call remove(g:termdebug_config, key)
+ endfor
+
+ unlet g:termdebug_config
+endfunction
+
+function Test_termdebug_double_termdebug_instances()
+ let s:error_message = 'Terminal debugger already running, cannot run two'
Termdebug
+ call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))})
call WaitForAssert({-> assert_equal(3, winnr('$'))})
- call WaitForAssert({-> assert_match(&mousemodel, 'popup_setpos')})
+ Termdebug
+ call WaitForAssert({-> assert_true(execute('messages') =~ s:error_message)})
wincmd t
quit!
call WaitForAssert({-> assert_equal(1, winnr('$'))})
- call WaitForAssert({-> assert_true(empty(&mousemodel))})
+ :%bw!
endfunction
+function Test_termdebug_config_types()
+ " TODO Remove the deprecated features after 1 Jan 2025.
+ let g:termdebug_config = {}
+ let s:error_message = 'Deprecation Warning:'
+ call assert_true(maparg('K', 'n', 0, 1)->empty())
+
+ for key in ['disasm_window', 'variables_window', 'map_K']
+ for val in [0, 1, v:true, v:false]
+ let g:termdebug_config[key] = val
+ Termdebug
+
+ " Type check: warning is displayed
+ if typename(val) == 'number'
+ call WaitForAssert({-> assert_true(execute('messages') =~ s:error_message)})
+ endif
+
+ " Test on g:termdebug_config keys
+ if val && key != 'map_K'
+ call WaitForAssert({-> assert_equal(4, winnr('$'))})
+ call remove(g:termdebug_config, key)
+ else
+ call WaitForAssert({-> assert_equal(3, winnr('$'))})
+ endif
+
+ " Test on mapping
+ if key == 'map_K'
+ if val
+ call assert_equal(':Evaluate<CR>', maparg('K', 'n', 0, 1).rhs)
+ else
+ call assert_true(maparg('K', 'n', 0, 1)->empty())
+ endif
+ endif
+
+ " Shutoff termdebug
+ wincmd t
+ quit!
+ call WaitForAssert({-> assert_equal(1, winnr('$'))})
+ :%bw!
+
+ endfor
+ endfor
+
+ unlet g:termdebug_config
+endfunction
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_textobjects.vim b/src/testdir/test_textobjects.vim
index d5e772d..2622b06 100644
--- a/src/testdir/test_textobjects.vim
+++ b/src/testdir/test_textobjects.vim
@@ -201,6 +201,18 @@ func Test_string_html_objects()
normal! 2k0vaty
call assert_equal("<div><div\nattr=\"attr\"\n></div></div>", @", e)
+ " tag, that includes a > in some attribute
+ let t = "<div attr=\"attr >> foo >> bar \">Hello</div>"
+ $put =t
+ normal! fHyit
+ call assert_equal("Hello", @", e)
+
+ " tag, that includes a > in some attribute
+ let t = "<div attr='attr >> foo >> bar '>Hello 123</div>"
+ $put =t
+ normal! fHyit
+ call assert_equal("Hello 123", @", e)
+
set quoteescape&
" this was going beyond the end of the line
diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim
index 2bf2834..57277f7 100644
--- a/src/testdir/test_textprop.vim
+++ b/src/testdir/test_textprop.vim
@@ -2901,6 +2901,10 @@ func Test_prop_inserts_text_before_double_width_wrap()
call writefile(lines, 'XscriptPropsBeforeDoubleWidthWrap', 'D')
let buf = RunVimInTerminal('-S XscriptPropsBeforeDoubleWidthWrap', #{rows: 3, cols: 50})
call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_double_width_wrap_1', {})
+ call term_sendkeys(buf, 'g0')
+ call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_double_width_wrap_2', {})
+ call term_sendkeys(buf, ":set showbreak=+++\<CR>")
+ call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_double_width_wrap_3', {})
call StopVimInTerminal(buf)
endfunc
diff --git a/src/testdir/test_tohtml.vim b/src/testdir/test_tohtml.vim
new file mode 100644
index 0000000..a1c8572
--- /dev/null
+++ b/src/testdir/test_tohtml.vim
@@ -0,0 +1,72 @@
+" Tests for Vim :TOhtml
+
+source check.vim
+
+func s:setup_basic(src_name)
+ let lines =<< trim END
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int isprime(int n)
+ {
+ if (n <= 1)
+ return 0;
+
+ for (int i = 2; i <= n / 2; i++)
+ if (n % i == 0)
+ return 0;
+
+ return 1;
+ }
+
+ int main(int argc, char *argv[])
+ {
+ int n = 7;
+
+ printf("%d is %s prime\n", n, isprime(n) ? "a" : "not a");
+
+ return 0;
+ }
+ END
+ call writefile(lines, a:src_name)
+ exe 'edit ' . a:src_name
+ TOhtml
+ write
+endfunc
+
+func s:cleanup_basic(src_name)
+ call delete(a:src_name)
+ call delete(a:src_name . ".html")
+endfunc
+
+source $VIMRUNTIME/plugin/tohtml.vim
+
+func Test_tohtml_basic()
+ let src_name = "Test_tohtml_basic.c"
+ call s:setup_basic(src_name)
+ let expected = readfile("samples/" . src_name . ".html")
+ let actual = readfile(src_name . ".html")
+ call assert_equal(expected[0:3], actual[0:3])
+ " Ignore the title
+ call assert_equal(expected[5:11], actual[5:11])
+ " Ignore pre and body css
+ call assert_equal(expected[14:], actual[14:])
+ call s:cleanup_basic(src_name)
+endfunc
+
+func Test_tohtml_basic_no_css()
+ let g:html_use_css = 0
+ let src_name = "Test_tohtml_basic_no_css.c"
+ call s:setup_basic(src_name)
+ let expected = readfile("samples/" . src_name . ".html")
+ let actual = readfile(src_name . ".html")
+ call assert_equal(expected[0:3], actual[0:3])
+ " Ignore the title
+ call assert_equal(expected[5:10], actual[5:10])
+ " Ignore body's inline css
+ call assert_equal(expected[12:], actual[12:])
+ call s:cleanup_basic(src_name)
+ unlet g:html_use_css
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_usercommands.vim b/src/testdir/test_usercommands.vim
index e161ee6..fe08b95 100644
--- a/src/testdir/test_usercommands.vim
+++ b/src/testdir/test_usercommands.vim
@@ -133,6 +133,10 @@ function Test_cmdmods()
\ 'silent verbose aboveleft belowright botright tab topleft vertical',
\ g:mods)
+ kee keep keepm keepma keepmar keepmarks keepa keepalt keepj keepjumps
+ \ keepp keeppatterns MyCmd
+ call assert_equal('keepalt keepjumps keepmarks keeppatterns', g:mods)
+
let g:mods = ''
command! -nargs=* MyQCmd let g:mods .= '<q-mods> '
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index 6b1a50d..7ed9123 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -497,6 +497,56 @@ def Test_call_call()
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_call_imports()
+ # Use call with an imported function
+ var lines =<< trim END
+ vim9script
+
+ export const foo = 'foo'
+
+ export def Imported()
+ enddef
+
+ var count: number
+ export def ImportedListArg(l: list<number>)
+ count += 1
+ l[0] += count
+ enddef
+ END
+ writefile(lines, 'Test_call_imports_importme', 'D')
+ lines =<< trim END
+ vim9script
+ import './Test_call_imports_importme' as i_imp
+
+ var l = [12]
+ call('i_imp.ImportedListArg', [l])
+ assert_equal(13, l[0])
+ const ImportedListArg = i_imp.ImportedListArg
+ call('ImportedListArg', [l])
+ assert_equal(15, l[0])
+ const Imported = i_imp.Imported
+ call("Imported", [])
+
+ assert_equal('foo', i_imp.foo)
+ const foo = i_imp.foo
+ assert_equal('foo', foo)
+ END
+ v9.CheckSourceScriptSuccess(lines)
+
+ # A few error cases
+ lines =<< trim END
+ vim9script
+ import './Test_call_imports_importme' as i_imp
+ const Imported = i_imp.Imported
+ const foo = i_imp.foo
+
+ assert_fails('call("i_imp.foo", [])', 'E117:') # foo is not a function
+ assert_fails('call("foo", [])', 'E117:') # foo is not a function
+ assert_fails('call("i_xxx.foo", [])', 'E117:') # i_xxx not imported file
+ END
+ v9.CheckSourceScriptSuccess(lines)
+enddef
+
def Test_ch_canread()
if !has('channel')
CheckFeature channel
@@ -1969,6 +2019,17 @@ def Test_getreginfo()
getreginfo('').regcontents->assert_equal(['D1E2F3'])
enddef
+def Test_getregionpos()
+ var lines =<< trim END
+ cursor(1, 1)
+ var pos = getregionpos(getpos('.'), getpos('$'))
+ for p in pos
+ assert_equal(bufnr('%'), p[0][0])
+ endfor
+ END
+ v9.CheckSourceDefSuccess(lines)
+enddef
+
def Test_getregtype()
var lines = ['aaa', 'bbb', 'ccc']
setreg('a', lines)
@@ -3152,6 +3213,11 @@ def Test_popup_settext()
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_setbuf()
+ v9.CheckSourceDefAndScriptFailure(['popup_setbuf([], "abc")'], ['E1013: Argument 1: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 1'])
+ v9.CheckSourceDefAndScriptFailure(['popup_setbuf(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2'])
+enddef
+
def Test_popup_show()
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'])
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index e92fcc5..8791a52 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -661,6 +661,44 @@ def Test_object_not_set()
Func()
END
v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
+
+ # Reference a object variable through a null class object which is stored in a
+ # variable of type "any".
+ lines =<< trim END
+ vim9script
+
+ def Z()
+ var o: any = null_object
+ o.v = 4
+ enddef
+ Z()
+ END
+ v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
+
+ # Do "echom" of a null object variable.
+ lines =<< trim END
+ vim9script
+
+ def X()
+ var x = null_object
+ echom x
+ enddef
+ X()
+ END
+ v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 2)
+
+ # Use a null object variable that vim wants to force to number.
+ lines =<< trim END
+ vim9script
+
+ def X()
+ var o = null_object
+ var l = [ 1, o]
+ sort(l, 'N')
+ enddef
+ X()
+ END
+ v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 3)
enddef
" Null object assignment and comparison
@@ -2246,6 +2284,47 @@ def Test_class_object_to_string()
assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
END
v9.CheckSourceSuccess(lines)
+
+ # check string() with object nesting
+ lines =<< trim END
+ vim9script
+ class C
+ var nest1: C
+ var nest2: C
+ def Init(n1: C, n2: C)
+ this.nest1 = n1
+ this.nest2 = n2
+ enddef
+ endclass
+
+ var o1 = C.new()
+ var o2 = C.new()
+ o1.Init(o1, o2)
+ o2.Init(o2, o1)
+
+ # The following previously put's vim into an infinite loop.
+
+ var expect = "object of C {nest1: object of C {...}, nest2: object of C {nest1: object of C {...}, nest2: object of C {...}}}"
+ assert_equal(expect, string(o1))
+ END
+ v9.CheckSourceSuccess(lines)
+
+ lines =<< trim END
+ vim9script
+
+ class B
+ endclass
+
+ class C
+ var b: B
+ var c: C
+ endclass
+
+ var o1 = C.new(B.new(), C.new(B.new()))
+ var expect = "object of C {b: object of B {}, c: object of C {b: object of B {}, c: object of [unknown]}}"
+ assert_equal(expect, string(o1))
+ END
+ v9.CheckSourceSuccess(lines)
enddef
def Test_interface_basics()
@@ -3173,6 +3252,141 @@ def Test_using_base_class()
v9.CheckSourceSuccess(lines)
enddef
+def Test_super_dispatch()
+ # See #15448 and #15463
+ var lines =<< trim END
+ vim9script
+
+ class A
+ def String(): string
+ return 'A'
+ enddef
+ endclass
+
+ class B extends A
+ def String(): string
+ return super.String()
+ enddef
+ endclass
+
+ class C extends B
+ endclass
+
+ assert_equal('A', C.new().String())
+ END
+ v9.CheckSourceSuccess(lines)
+
+ lines =<< trim END
+ vim9script
+
+ class A
+ def F(): string
+ return 'AA'
+ enddef
+ endclass
+
+ class B extends A
+ def F(): string
+ return 'BB'
+ enddef
+ def S(): string
+ return super.F()
+ enddef
+ def S0(): string
+ return this.S()
+ enddef
+ endclass
+
+ class C extends B
+ def F(): string
+ return 'CC'
+ enddef
+ def ToB(): string
+ return super.F()
+ enddef
+ endclass
+
+ assert_equal('AA', B.new().S())
+ assert_equal('AA', C.new().S())
+ assert_equal('AA', B.new().S0())
+ assert_equal('AA', C.new().S0())
+
+ assert_equal('BB', C.new().ToB())
+
+ assert_equal('CC', C.new().F())
+ assert_equal('BB', B.new().F())
+ assert_equal('AA', A.new().F())
+ END
+ v9.CheckSourceSuccess(lines)
+
+ lines =<< trim END
+ vim9script
+
+ var call_chain: list<string>
+
+ abstract class A
+ abstract def _G(): string
+
+ def F(): string
+ call_chain->add('A.F()')
+ return this._G()
+ enddef
+ def _H(): string
+ call_chain->add('A._H()')
+ return this.F()
+ enddef
+ endclass
+
+ class B extends A
+ def _G(): string
+ call_chain->add('B.G()')
+ return 'BBB'
+ enddef
+ def SF(): string
+ call_chain->add('B.SF()')
+ return super._H()
+ enddef
+ endclass
+
+ class C extends B
+ endclass
+
+ class D extends C
+ def SF(): string
+ call_chain->add('D.SF()')
+ return super.SF()
+ enddef
+ endclass
+
+ class E extends D
+ def SF(): string
+ call_chain->add('E.SF()')
+ return super.SF()
+ enddef
+ endclass
+
+ class F extends E
+ def _G(): string
+ call_chain->add('F._G()')
+ return 'FFF'
+ enddef
+ endclass
+
+ # E.new() -> A.F() -> B._G()
+ call_chain = []
+ var o1 = E.new()
+ assert_equal('BBB', o1.F())
+ assert_equal(['A.F()', 'B.G()'], call_chain)
+
+ # F.new() -> E.SF() -> D.SF() -> B.SF() -> A._H() -> A.F() -> F._G()
+ call_chain = []
+ var o2 = F.new()
+ assert_equal('FFF', o2.SF())
+ assert_equal(['E.SF()', 'D.SF()', 'B.SF()', 'A._H()', 'A.F()', 'F._G()'], call_chain)
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
def Test_class_import()
var lines =<< trim END
vim9script
@@ -7162,6 +7376,47 @@ def Test_null_object_method_call()
T()
END
v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
+
+ # Calling an object method defined in a class that is extended. This differs
+ # from the previous by invoking ISN_METHODCALL instead of ISN_DCALL.
+ lines =<< trim END
+ vim9script
+
+ class C0
+ def F()
+ enddef
+ endclass
+
+ class C extends C0
+ endclass
+
+ def X()
+ var o: C0 = null_object
+ o.F()
+ enddef
+ X()
+ END
+ v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
+
+ # Getting a function ref an object method.
+ lines =<< trim END
+ vim9script
+
+ class C0
+ def F()
+ enddef
+ endclass
+
+ class C extends C0
+ endclass
+
+ def X()
+ var o: C0 = null_object
+ var XXX = o.F
+ enddef
+ X()
+ END
+ v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
enddef
" Test for using a dict as an object member
@@ -10425,6 +10680,20 @@ func Test_object_string()
call v9.CheckSourceSuccess(lines)
endfunc
+" Test for using the string() builtin method with an object's method
+def Test_method_string()
+ var lines =<< trim END
+ vim9script
+ class A
+ def F()
+ enddef
+ endclass
+ assert_match('function(''<SNR>\d\+_A\.F'')', string(A.new().F))
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
+
" Test for using a class in the class definition
def Test_Ref_Class_Within_Same_Class()
var lines =<< trim END
@@ -10486,6 +10755,156 @@ def Test_Ref_Class_Within_Same_Class()
v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
enddef
+" Test for comparing a class referencing itself
+def Test_Object_Compare_With_Recursive_Class_Ref()
+ var lines =<< trim END
+ vim9script
+
+ class C
+ public var nest: C
+ endclass
+
+ var o1 = C.new()
+ o1.nest = o1
+
+ var result = o1 == o1
+ assert_equal(true, result)
+ END
+ v9.CheckScriptSuccess(lines)
+
+ lines =<< trim END
+ vim9script
+
+ class C
+ public var nest: C
+ endclass
+ var o1 = C.new()
+ var o2 = C.new(C.new())
+
+ var result = o1 == o2
+ assert_equal(false, result)
+ END
+ v9.CheckScriptSuccess(lines)
+
+ lines =<< trim END
+ vim9script
+ class C
+ var nest1: C
+ var nest2: C
+ def Init(n1: C, n2: C)
+ this.nest1 = n1
+ this.nest2 = n2
+ enddef
+ endclass
+
+ var o1 = C.new()
+ var o2 = C.new()
+ o1.Init(o1, o2)
+ o2.Init(o2, o1)
+
+ var result = o1 == o2
+ assert_equal(true, result)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
+" Test for comparing a class with nesting objects
+def Test_Object_Compare_With_Nesting_Objects()
+ # On a compare, after vim equal recurses 1000 times, not finding an unequal,
+ # return the compare is equal.
+ # Test that limit
+
+ var lines =<< trim END
+ vim9script
+ class C
+ public var n: number
+ public var nest: C
+
+ # Create a "C" that chains/nests to indicated depth.
+ # return {head: firstC, tail: lastC}
+ static def CreateNested(depth: number): dict<C>
+ var first = C.new(1, null_object)
+ var last = first
+ for i in range(2, depth)
+ last.nest = C.new(i, null_object)
+ last = last.nest
+ endfor
+ return {head: first, tail: last}
+ enddef
+
+ # Return pointer to nth item in chain.
+ def GetLink(depth: number): C
+ var count = 1
+ var p: C = this
+ while count < depth
+ p = p.nest
+ if p == null
+ throw "too deep"
+ endif
+ count += 1
+ endwhile
+ return p
+ enddef
+
+ # Return the length of the chain
+ def len(): number
+ var count = 1
+ var p: C = this
+ while p.nest != null
+ p = p.nest
+ count += 1
+ endwhile
+ return count
+ enddef
+ endclass
+
+ var chain = C.CreateNested(3)
+ var s = "object of C {n: 1, nest: object of C {n: 2, nest: object of C {n: 3, nest: object of [unknown]}}}"
+ assert_equal(s, string(chain.head))
+ assert_equal(3, chain.head->len())
+
+ var chain1 = C.CreateNested(100)
+ var chain2 = C.CreateNested(100)
+ assert_true(chain1.head == chain2.head)
+
+ # modify the tail of chain2, compare not equal
+ chain2.tail.n = 123456
+ assert_true(chain1.head != chain2.head)
+
+ # a tail of a different length compares not equal
+ chain2 = C.CreateNested(101)
+ assert_true(chain1.head != chain2.head)
+
+ chain1 = C.CreateNested(1000)
+ chain2 = C.CreateNested(1000)
+ assert_true(chain1.head == chain2.head)
+
+ # modify the tail of chain2, compare not equal
+ chain2.tail.n = 123456
+ assert_true(chain1.head != chain2.head)
+
+ # try a chain longer that the limit
+ chain1 = C.CreateNested(1001)
+ chain2 = C.CreateNested(1001)
+ assert_true(chain1.head == chain2.head)
+
+ # modify the tail, but still equal
+ chain2.tail.n = 123456
+ assert_true(chain1.head == chain2.head)
+
+ # remove 2 items from front, shorten the chain by two.
+ chain1.head = chain1.head.GetLink(3)
+ chain2.head = chain2.head.GetLink(3)
+ assert_equal(3, chain1.head.n)
+ assert_equal(3, chain2.head.n)
+ assert_equal(999, chain1.head->len())
+ assert_equal(999, chain2.head->len())
+ # Now less than the limit, compare not equal
+ assert_true(chain1.head != chain2.head)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
" Test for using a compound operator from a lambda function in an object method
def Test_compound_op_in_objmethod_lambda()
# Test using the "+=" operator
@@ -10744,4 +11163,54 @@ def Test_class_object_index()
v9.CheckScriptFailure(lines, 'E689: Index not allowed after a object: a[10] = 1', 5)
enddef
+def Test_class_member_init_typecheck()
+ # Ensure the class member is assigned its declared type.
+ var lines =<< trim END
+ vim9script
+ class S
+ static var l: list<string> = []
+ endclass
+ S.l->add(123)
+ END
+ v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 5)
+
+ # Ensure the initializer value and the declared type match.
+ lines =<< trim END
+ vim9script
+ class S
+ var l: list<string> = [1, 2, 3]
+ endclass
+ var o = S.new()
+ END
+ v9.CheckScriptFailure(lines, 'E1382: Variable "l": type mismatch, expected list<string> but got list<number>')
+
+ # Ensure the class member is assigned its declared type.
+ lines =<< trim END
+ vim9script
+ class S
+ var l: list<string> = []
+ endclass
+ var o = S.new()
+ o.l->add(123)
+ END
+ v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 6)
+enddef
+
+def Test_class_cast()
+ var lines =<< trim END
+ vim9script
+ class A
+ endclass
+ class B extends A
+ var mylen: number
+ endclass
+ def F(o: A): number
+ return (<B>o).mylen
+ enddef
+
+ defcompile F
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim
index a9e10e7..51ae7e6 100644
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -2036,6 +2036,14 @@ def Test_no_space_after_command()
v9.CheckDefExecAndScriptFailure(lines, 'E486:', 1)
enddef
+def Test_lambda_crash()
+ # This used to crash Vim
+ var lines =<< trim END
+ vim9 () => super => {
+ END
+ v9.CheckScriptFailureList(lines, ["E1356:", "E1405:"])
+enddef
+
" Test for the 'previewpopup' option
def Test_previewpopup()
set previewpopup=height:10,width:60
@@ -2044,6 +2052,7 @@ def Test_previewpopup()
assert_notequal(id, 0)
assert_match('Xppfile', popup_getoptions(id).title)
popup_clear()
+ bw Xppfile
set previewpopup&
enddef
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim
index c74cce4..7746b23 100644
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -1761,6 +1761,74 @@ def Test_disassemble_typecast()
instr)
enddef
+def Test_disassemble_object_cast()
+ # Downcasting.
+ var lines =<< trim END
+ vim9script
+ class A
+ endclass
+ class B extends A
+ var mylen: number
+ endclass
+ def F(o: A): number
+ return (<B>o).mylen
+ enddef
+
+ g:instr = execute('disassemble F')
+ END
+ v9.CheckScriptSuccess(lines)
+ assert_match('\<SNR>\d*_F\_s*' ..
+ 'return (<B>o).mylen\_s*' ..
+ '0 LOAD arg\[-1\]\_s*' ..
+ '1 CHECKTYPE object<B> stack\[-1\]\_s*' ..
+ '2 OBJ_MEMBER 0\_s*' ..
+ '3 RETURN\_s*',
+ g:instr)
+
+ # Upcasting.
+ lines =<< trim END
+ vim9script
+ class A
+ var mylen: number
+ endclass
+ class B extends A
+ endclass
+ def F(o: B): number
+ return (<A>o).mylen
+ enddef
+
+ g:instr = execute('disassemble F')
+ END
+ v9.CheckScriptSuccess(lines)
+ assert_match('\<SNR>\d*_F\_s*' ..
+ 'return (<A>o).mylen\_s*' ..
+ '0 LOAD arg\[-1\]\_s*' ..
+ '1 OBJ_MEMBER 0\_s*' ..
+ '2 RETURN\_s*',
+ g:instr)
+
+ # Casting, type is not statically known.
+ lines =<< trim END
+ vim9script
+ class A
+ endclass
+ class B extends A
+ endclass
+ def F(o: any): any
+ return <A>o
+ enddef
+
+ g:instr = execute('disassemble F')
+ END
+ v9.CheckScriptSuccess(lines)
+ assert_match('\<SNR>\d*_F\_s*' ..
+ 'return <A>o\_s*' ..
+ '0 LOAD arg\[-1\]\_s*' ..
+ '1 CHECKTYPE object<A> stack\[-1\]\_s*' ..
+ '2 RETURN\_s*',
+ g:instr)
+enddef
+
def s:Computing()
var nr = 3
var nrres = nr + 7
@@ -3496,4 +3564,26 @@ def Test_disassemble_compound_op_in_closure()
unlet g:instr
enddef
+def Test_disassemble_member_initializer()
+ var lines =<< trim END
+ vim9script
+ class A
+ var l: list<string> = []
+ var d: dict<string> = {}
+ endclass
+ g:instr = execute('disassemble A.new')
+ END
+ v9.CheckScriptSuccess(lines)
+ # Ensure SETTYPE is emitted and that matches the declared type.
+ assert_match('new\_s*' ..
+ '0 NEW A size \d\+\_s*' ..
+ '1 NEWLIST size 0\_s*' ..
+ '2 SETTYPE list<string>\_s*' ..
+ '3 STORE_THIS 0\_s*' ..
+ '4 NEWDICT size 0\_s*' ..
+ '5 SETTYPE dict<string>\_s*' ..
+ '6 STORE_THIS 1', g:instr)
+ unlet g:instr
+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 d07bbfb..030ff83 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -164,6 +164,16 @@ def Test_wrong_function_name()
END
v9.CheckScriptFailure(lines, 'E1182:')
delfunc g:Define
+
+ lines =<< trim END
+ vim9script
+ var F1_ref: func
+ def Start()
+ F1_ref()
+ enddef
+ Start()
+ END
+ v9.CheckScriptFailure(lines, 'E117:')
enddef
" Check that in a legacy script a :def accesses the correct script variables.
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 0b17150..bcb590d 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -4007,7 +4007,7 @@ def Test_restoring_cpo()
edit XanotherScript
so %
assert_equal('aABceFsMny>', &cpo)
- assert_equal('aABceFs', g:cpoval)
+ assert_equal('aABceFsz', g:cpoval)
:1del
setline(1, 'let g:cpoval = &cpo')
w
@@ -4048,10 +4048,10 @@ def Test_restoring_cpo()
exe "silent !" .. cmd
assert_equal([
- 'before: aABceFs',
- 'after: aABceFsM',
- 'later: aABceFsM',
- 'vim9: aABceFs'], readfile('Xrporesult'))
+ 'before: aABceFsz',
+ 'after: aABceFszM',
+ 'later: aABceFszM',
+ 'vim9: aABceFsz'], readfile('Xrporesult'))
$HOME = save_HOME
delete('Xrporesult')
@@ -5085,15 +5085,19 @@ def Test_null_values()
var nullValues = [
[null, 1, 'null', 7, 'special'],
[null_blob, 1, '0z', 10, 'blob'],
- [null_channel, 1, 'channel fail', 9, 'channel'],
[null_dict, 1, '{}', 4, 'dict<any>'],
[null_function, 1, "function('')", 2, 'func(...): unknown'],
- [null_job, 1, 'no process', 8, 'job'],
[null_list, 1, '[]', 3, 'list<any>'],
[null_object, 1, 'object of [unknown]', 13, 'object<Unknown>'],
[null_partial, 1, "function('')", 2, 'func(...): unknown'],
[null_string, 1, "''", 1, 'string']
]
+ if has('channel')
+ nullValues->add([null_channel, 1, 'channel fail', 9, 'channel'])
+ endif
+ if has('job')
+ nullValues->add([null_job, 1, 'no process', 8, 'job'])
+ endif
for [Val, emptyExp, stringExp, typeExp, typenameExp] in nullValues
assert_equal(emptyExp, empty(Val))
diff --git a/src/testdir/test_vimscript.vim b/src/testdir/test_vimscript.vim
index 8976779..21f894e 100644
--- a/src/testdir/test_vimscript.vim
+++ b/src/testdir/test_vimscript.vim
@@ -7536,6 +7536,31 @@ func Test_deeply_nested_source()
call system(cmd)
endfunc
+func Test_exception_silent()
+ XpathINIT
+ let lines =<< trim END
+ func Throw()
+ Xpath 'a'
+ throw "Uncaught"
+ " This line is not executed.
+ Xpath 'b'
+ endfunc
+ " The exception is suppressed due to the presence of silent!.
+ silent! call Throw()
+ try
+ call DoesNotExist()
+ catch /E117:/
+ Xpath 'c'
+ endtry
+ Xpath 'd'
+ END
+ let verify =<< trim END
+ call assert_equal('acd', g:Xpath)
+ END
+
+ call RunInNewVim(lines, verify)
+endfunc
+
"-------------------------------------------------------------------------------
" Modelines {{{1
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_winfixbuf.vim b/src/testdir/test_winfixbuf.vim
index f800338..3cec4ed 100644
--- a/src/testdir/test_winfixbuf.vim
+++ b/src/testdir/test_winfixbuf.vim
@@ -2934,6 +2934,7 @@ func Test_tfirst()
\ "Xtags", 'D')
call writefile(["one", "two", "three"], "Xfile", 'D')
call writefile(["one"], "Xother", 'D')
+ tag one
edit Xother
set winfixbuf
diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim
index a91a1fc..99e4998 100644
--- a/src/testdir/test_xxd.vim
+++ b/src/testdir/test_xxd.vim
@@ -73,21 +73,21 @@ func Test_xxd()
exe '0r! ' . s:xxd_cmd . ' -l 120 -ps -c20 ' . man_copy
$d
let expected = [
- \ '2e54482058584420312022417567757374203139',
- \ '39362220224d616e75616c207061676520666f72',
- \ '20787864220a2e5c220a2e5c222032317374204d',
- \ '617920313939360a2e5c22204d616e2070616765',
- \ '20617574686f723a0a2e5c2220202020546f6e79',
- \ '204e7567656e74203c746f6e79407363746e7567']
+ \ '2e544820585844203120224d6179203230323422',
+ \ '20224d616e75616c207061676520666f72207878',
+ \ '64220a2e5c220a2e5c222032317374204d617920',
+ \ '313939360a2e5c22204d616e2070616765206175',
+ \ '74686f723a0a2e5c2220202020546f6e79204e75',
+ \ '67656e74203c746f6e79407363746e7567656e2e']
call assert_equal(expected, getline(1,'$'), s:Mess(s:test))
" Test 6: Print the date from xxd.1
let s:test += 1
for arg in ['-l 13', '-l13', '-len 13']
%d
- exe '0r! ' . s:xxd_cmd . ' -s 0x36 ' . arg . ' -cols 13 ' . man_copy
+ exe '0r! ' . s:xxd_cmd . ' -s 0x33 ' . arg . ' -cols 13 ' . man_copy
$d
- call assert_equal('00000036: 3231 7374 204d 6179 2031 3939 36 21st May 1996', getline(1), s:Mess(s:test))
+ call assert_equal('00000033: 3231 7374 204d 6179 2031 3939 36 21st May 1996', getline(1), s:Mess(s:test))
endfor
" Cleanup after tests 5 and 6
diff --git a/src/testdir/test_zip_plugin.vim b/src/testdir/test_zip_plugin.vim
new file mode 100644
index 0000000..e831f26
--- /dev/null
+++ b/src/testdir/test_zip_plugin.vim
@@ -0,0 +1,237 @@
+so check.vim
+
+CheckExecutable unzip
+
+if 0 " Find uncovered line
+ profile start zip_profile
+ profile! file */zip*.vim
+endif
+
+runtime plugin/zipPlugin.vim
+
+def Test_zip_basic()
+
+ ### get our zip file
+ if !filecopy("samples/test.zip", "X.zip")
+ assert_report("Can't copy samples/test.zip")
+ return
+ endif
+ defer delete("X.zip")
+
+ e X.zip
+
+ ### Check header
+ assert_match('^" zip\.vim version v\d\+', getline(1))
+ assert_match('^" Browsing zipfile .*/X.zip', getline(2))
+ assert_match('^" Select a file with cursor and press ENTER', getline(3))
+ assert_match('^$', getline(4))
+
+ ### Check files listing
+ assert_equal(["Xzip/", "Xzip/dir/", "Xzip/file.txt"], getline(5, 7))
+
+ ### Check ENTER on header
+ :1
+ exe ":normal \<cr>"
+ assert_equal("X.zip", @%)
+
+ ### Check ENTER on directory
+ :1|:/^$//dir/
+ assert_match('Please specify a file, not a directory',
+ execute("normal \<CR>"))
+
+ ### Check ENTER on file
+ :1
+ search('file.txt')
+ exe ":normal \<cr>"
+ assert_match('zipfile://.*/X.zip::Xzip/file.txt', @%)
+ assert_equal('one', getline(1))
+
+ ### Check editing file
+ if executable("zip")
+ s/one/two/
+ assert_equal("two", getline(1))
+ w
+ bw|bw
+ e X.zip
+
+ :1|:/^$//file/
+ exe "normal \<cr>"
+ assert_equal("two", getline(1))
+ endif
+
+ only
+ e X.zip
+
+ ### Check extracting file
+ :1|:/^$//file/
+ normal x
+ assert_true(filereadable("Xzip/file.txt"))
+
+ ## Check not overwriting existing file
+ assert_match('<Xzip/file.txt> .* not overwriting!', execute("normal x"))
+
+ delete("Xzip", "rf")
+
+ ### Check extracting directory
+ :1|:/^$//dir/
+ assert_match('Please specify a file, not a directory', execute("normal x"))
+ assert_equal("X.zip", @%)
+
+ ### Check "x" on header
+ :1
+ normal x
+ assert_equal("X.zip", @%)
+ bw
+
+ ### Check opening zip when "unzip" program is missing
+ var save_zip_unzipcmd = g:zip_unzipcmd
+ g:zip_unzipcmd = "/"
+ assert_match('unzip not available on your system', execute("e X.zip"))
+
+ ### Check when "unzip" don't work
+ if executable("false")
+ g:zip_unzipcmd = "false"
+ assert_match('X\.zip is not a zip file', execute("e X.zip"))
+ endif
+ bw
+
+ g:zip_unzipcmd = save_zip_unzipcmd
+ e X.zip
+
+ ### Check opening file when "unzip" is missing
+ g:zip_unzipcmd = "/"
+ assert_match('sorry, your system doesn''t appear to have the / program',
+ execute("normal \<CR>"))
+
+ bw|bw
+ g:zip_unzipcmd = save_zip_unzipcmd
+ e X.zip
+
+ ### Check :write when "zip" program is missing
+ :1|:/^$//file/
+ exe "normal \<cr>Goanother\<esc>"
+ var save_zip_zipcmd = g:zip_zipcmd
+ g:zip_zipcmd = "/"
+ assert_match('sorry, your system doesn''t appear to have the / program',
+ execute("write"))
+
+ ### Check when "zip" report failure
+ if executable("false")
+ g:zip_zipcmd = "false"
+ assert_match('sorry, unable to update .*/X.zip with Xzip/file.txt',
+ execute("write"))
+ endif
+ bw!|bw
+
+ g:zip_zipcmd = save_zip_zipcmd
+
+ ### Check opening an no zipfile
+ writefile(["qsdf"], "Xcorupt.zip", "D")
+ e! Xcorupt.zip
+ assert_equal("qsdf", getline(1))
+
+ bw
+
+ ### Check no existing zipfile
+ assert_match('File not readable', execute("e Xnot_exists.zip"))
+
+ bw
+enddef
+
+def Test_zip_glob_fname()
+ CheckNotMSWindows
+ # does not work on Windows, why?
+
+ ### copy sample zip file
+ if !filecopy("samples/testa.zip", "X.zip")
+ assert_report("Can't copy samples/testa.zip")
+ return
+ endif
+ defer delete("X.zip")
+ defer delete('zipglob', 'rf')
+
+ e X.zip
+
+ ### 1) Check extracting strange files
+ :1
+ var fname = 'a[a].txt'
+ search('\V' .. fname)
+ normal x
+ assert_true(filereadable('zipglob/' .. fname))
+ delete('zipglob', 'rf')
+
+ :1
+ fname = 'a*.txt'
+ search('\V' .. fname)
+ normal x
+ assert_true(filereadable('zipglob/' .. fname))
+ delete('zipglob', 'rf')
+
+ :1
+ fname = 'a?.txt'
+ search('\V' .. fname)
+ normal x
+ assert_true(filereadable('zipglob/' .. fname))
+ delete('zipglob', 'rf')
+
+ :1
+ fname = 'a\.txt'
+ search('\V' .. escape(fname, '\\'))
+ normal x
+ assert_true(filereadable('zipglob/' .. fname))
+ delete('zipglob', 'rf')
+
+ :1
+ fname = 'a\\.txt'
+ search('\V' .. escape(fname, '\\'))
+ normal x
+ assert_true(filereadable('zipglob/' .. fname))
+ delete('zipglob', 'rf')
+
+ ### 2) Check entering strange file names
+ :1
+ fname = 'a[a].txt'
+ search('\V' .. fname)
+ exe ":normal \<cr>"
+ assert_match('zipfile://.*/X.zip::zipglob/a\[a\].txt', @%)
+ assert_equal('a test file with []', getline(1))
+ bw
+
+ e X.zip
+ :1
+ fname = 'a*.txt'
+ search('\V' .. fname)
+ exe ":normal \<cr>"
+ assert_match('zipfile://.*/X.zip::zipglob/a\*.txt', @%)
+ assert_equal('a test file with a*', getline(1))
+ bw
+
+ e X.zip
+ :1
+ fname = 'a?.txt'
+ search('\V' .. fname)
+ exe ":normal \<cr>"
+ assert_match('zipfile://.*/X.zip::zipglob/a?.txt', @%)
+ assert_equal('a test file with a?', getline(1))
+ bw
+
+ e X.zip
+ :1
+ fname = 'a\.txt'
+ search('\V' .. escape(fname, '\\'))
+ exe ":normal \<cr>"
+ assert_match('zipfile://.*/X.zip::zipglob/a\\.txt', @%)
+ assert_equal('a test file with a\', getline(1))
+ bw
+
+ e X.zip
+ :1
+ fname = 'a\\.txt'
+ search('\V' .. escape(fname, '\\'))
+ exe ":normal \<cr>"
+ assert_match('zipfile://.*/X.zip::zipglob/a\\\\.txt', @%)
+ assert_equal('a test file with a double \', getline(1))
+ bw
+
+ bw
+enddef
diff --git a/src/testdir/view_util.vim b/src/testdir/view_util.vim
index 71cb071..161c8b2 100644
--- a/src/testdir/view_util.vim
+++ b/src/testdir/view_util.vim
@@ -71,7 +71,7 @@ endfunc
" than the raw code.
" Return the modifyOtherKeys level 2 encoding for "key" with "modifier"
-" (number value, e.g. CTRL is 5).
+" (number value, e.g. CTRL is 5, Shift is 2, Alt is 3).
func GetEscCodeCSI27(key, modifier)
let key = printf("%d", char2nr(a:key))
let mod = printf("%d", a:modifier)
diff --git a/src/testdir/viewdumps.vim b/src/testdir/viewdumps.vim
new file mode 100644
index 0000000..62f7bbe
--- /dev/null
+++ b/src/testdir/viewdumps.vim
@@ -0,0 +1,11 @@
+vim9script
+
+exec 'source ' .. (((cwdpath: string) => cwdpath
+ ->strpart(0, cwdpath->strridx('/vim')))(getcwd()))
+ .. '/vim/src/testdir/commondumps.vim'
+g:Init('\<src\>', 0)
+
+# Match ":language" of runtest.vim.
+language messages C
+
+# vim:fdm=syntax:sw=2:ts=8:noet:nolist:nosta:
diff --git a/src/testing.c b/src/testing.c
index 3e9e077..7ab109c 100644
--- a/src/testing.c
+++ b/src/testing.c
@@ -99,7 +99,7 @@ ga_concat_shorten_esc(garray_T *gap, char_u *str)
return;
}
- for (p = str; *p != NUL; ++p)
+ for (p = str; *p != NUL; )
{
same_len = 1;
s = p;
@@ -118,10 +118,13 @@ ga_concat_shorten_esc(garray_T *gap, char_u *str)
vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
ga_concat(gap, buf);
ga_concat(gap, (char_u *)" times]");
- p = s - 1;
+ p = s;
}
else
+ {
ga_concat_esc(gap, p, clen);
+ p += clen;
+ }
}
}
@@ -187,7 +190,7 @@ fill_assert_error(
{
item2 = dict_find(got_d, hi->hi_key, -1);
if (item2 == NULL || !tv_equal(&HI2DI(hi)->di_tv,
- &item2->di_tv, FALSE, FALSE))
+ &item2->di_tv, FALSE))
{
// item of exp_d not present in got_d or values differ.
dict_add_tv(exp_tv->vval.v_dict,
@@ -262,7 +265,7 @@ assert_equal_common(typval_T *argvars, assert_type_T atype)
{
garray_T ga;
- if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)
+ if (tv_equal(&argvars[0], &argvars[1], FALSE)
!= (atype == ASSERT_EQUAL))
{
prepare_assert_error(&ga);
diff --git a/src/textobject.c b/src/textobject.c
index 1890d7c..aa2db07 100644
--- a/src/textobject.c
+++ b/src/textobject.c
@@ -1426,15 +1426,22 @@ again:
if (!do_include)
{
- // Exclude the start tag.
+ // Exclude the start tag,
+ // but skip over '>' if it appears in quotes
+ int in_quotes = FALSE;
curwin->w_cursor = start_pos;
while (inc_cursor() >= 0)
- if (*ml_get_cursor() == '>')
+ {
+ p = ml_get_cursor();
+ if (*p == '>' && !in_quotes)
{
inc_cursor();
start_pos = curwin->w_cursor;
break;
}
+ else if (*p == '"' || *p == '\'')
+ in_quotes = !in_quotes;
+ }
curwin->w_cursor = end_pos;
// If we are in Visual mode and now have the same text as before set
diff --git a/src/textprop.c b/src/textprop.c
index 83c42a3..fe0c8d2 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -2060,7 +2060,7 @@ list_types(hashtab_T *ht, list_T *l)
* prop_type_list([{bufnr}])
*/
void
-f_prop_type_list(typval_T *argvars, typval_T *rettv UNUSED)
+f_prop_type_list(typval_T *argvars, typval_T *rettv)
{
buf_T *buf = NULL;
diff --git a/src/typval.c b/src/typval.c
index 6a73719..01ffef5 100644
--- a/src/typval.c
+++ b/src/typval.c
@@ -267,11 +267,16 @@ tv_get_bool_or_number_chk(
break;
case VAR_OBJECT:
{
- 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);
+ if (varp->vval.v_object == NULL)
+ emsg(_(e_using_object_as_string));
else
- 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:
@@ -1146,11 +1151,16 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
break;
case VAR_OBJECT:
{
- 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
+ if (varp->vval.v_object == NULL)
emsg(_(e_using_object_as_string));
+ else
+ {
+ 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:
@@ -1605,8 +1615,7 @@ typval_compare_list(
}
else
{
- val = list_equal(tv1->vval.v_list, tv2->vval.v_list,
- ic, FALSE);
+ val = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic);
if (type == EXPR_NEQUAL)
val = !val;
}
@@ -1699,24 +1708,6 @@ typval_compare_blob(
}
/*
- * Compare "tv1" to "tv2" as classes according to "type".
- * Put the result, false or true, in "res".
- * Return FAIL and give an error message when the comparison can't be done.
- */
- int
-typval_compare_class(
- typval_T *tv1,
- typval_T *tv2,
- exprtype_T type UNUSED,
- int ic UNUSED,
- int *res)
-{
- // TODO: use "type"
- *res = tv1->vval.v_class == tv2->vval.v_class;
- return OK;
-}
-
-/*
* Compare "tv1" to "tv2" as objects according to "type".
* Put the result, false or true, in "res".
* Return FAIL and give an error message when the comparison can't be done.
@@ -1742,14 +1733,6 @@ typval_compare_object(
return OK;
}
- class_T *cl1 = tv1->vval.v_object->obj_class;
- class_T *cl2 = tv2->vval.v_object->obj_class;
- if (cl1 != cl2 || cl1 == NULL || cl2 == NULL)
- {
- *res = !res_match;
- return OK;
- }
-
object_T *obj1 = tv1->vval.v_object;
object_T *obj2 = tv2->vval.v_object;
if (type == EXPR_IS || type == EXPR_ISNOT)
@@ -1758,14 +1741,7 @@ typval_compare_object(
return OK;
}
- for (int i = 0; i < cl1->class_obj_member_count; ++i)
- if (!tv_equal((typval_T *)(obj1 + 1) + i,
- (typval_T *)(obj2 + 1) + i, ic, TRUE))
- {
- *res = !res_match;
- return OK;
- }
- *res = res_match;
+ *res = object_equal(obj1, obj2, ic) ? res_match : !res_match;
return OK;
}
@@ -1802,7 +1778,7 @@ typval_compare_dict(
}
else
{
- val = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, FALSE);
+ val = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic);
if (type == EXPR_NEQUAL)
val = !val;
}
@@ -1841,14 +1817,14 @@ typval_compare_func(
if (tv1->v_type == VAR_FUNC && tv2->v_type == VAR_FUNC)
// strings are considered the same if their value is
// the same
- val = tv_equal(tv1, tv2, ic, FALSE);
+ val = tv_equal(tv1, tv2, ic);
else if (tv1->v_type == VAR_PARTIAL && tv2->v_type == VAR_PARTIAL)
val = (tv1->vval.v_partial == tv2->vval.v_partial);
else
val = FALSE;
}
else
- val = tv_equal(tv1, tv2, ic, FALSE);
+ val = tv_equal(tv1, tv2, ic);
if (type == EXPR_NEQUAL || type == EXPR_ISNOT)
val = !val;
*res = val;
@@ -2003,7 +1979,7 @@ func_equal(
if (d1 != d2)
return FALSE;
}
- else if (!dict_equal(d1, d2, ic, TRUE))
+ else if (!dict_equal(d1, d2, ic))
return FALSE;
// empty list and no list considered the same
@@ -2013,7 +1989,7 @@ func_equal(
return FALSE;
for (i = 0; i < a1; ++i)
if (!tv_equal(tv1->vval.v_partial->pt_argv + i,
- tv2->vval.v_partial->pt_argv + i, ic, TRUE))
+ tv2->vval.v_partial->pt_argv + i, ic))
return FALSE;
return TRUE;
@@ -2028,8 +2004,7 @@ func_equal(
tv_equal(
typval_T *tv1,
typval_T *tv2,
- int ic, // ignore case
- int recursive) // TRUE when used recursively
+ int ic) // ignore case
{
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
char_u *s1, *s2;
@@ -2043,7 +2018,7 @@ tv_equal(
// Reduce the limit every time running into it. That should work fine for
// deeply linked structures that are not recursively linked and catch
// recursiveness quickly.
- if (!recursive)
+ if (recursive_cnt == 0)
tv_equal_recurse_limit = 1000;
if (recursive_cnt >= tv_equal_recurse_limit)
{
@@ -2073,13 +2048,13 @@ tv_equal(
{
case VAR_LIST:
++recursive_cnt;
- r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
+ r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic);
--recursive_cnt;
return r;
case VAR_DICT:
++recursive_cnt;
- r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
+ r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic);
--recursive_cnt;
return r;
@@ -2114,7 +2089,9 @@ tv_equal(
return tv1->vval.v_class == tv2->vval.v_class;
case VAR_OBJECT:
- (void)typval_compare_object(tv1, tv2, EXPR_EQUAL, ic, &r);
+ ++recursive_cnt;
+ r = object_equal(tv1->vval.v_object, tv2->vval.v_object, ic);
+ --recursive_cnt;
return r;
case VAR_PARTIAL:
@@ -2237,7 +2214,7 @@ eval_number(
char_u **arg,
typval_T *rettv,
int evaluate,
- int want_string UNUSED)
+ int want_string)
{
int len;
int skip_quotes = !in_old_script(4);
diff --git a/src/undo.c b/src/undo.c
index 1cd8912..8c2783a 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -3683,7 +3683,7 @@ u_eval_tree(buf_T *buf, u_header_T *first_uhp, list_T *list)
* "undofile(name)" function
*/
void
-f_undofile(typval_T *argvars UNUSED, typval_T *rettv)
+f_undofile(typval_T *argvars, typval_T *rettv)
{
if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
return;
@@ -3738,7 +3738,7 @@ u_undofile_reset_and_delete(buf_T *buf)
* "undotree(expr)" function
*/
void
-f_undotree(typval_T *argvars UNUSED, typval_T *rettv)
+f_undotree(typval_T *argvars, typval_T *rettv)
{
if (in_vim9script() && check_for_opt_buffer_arg(argvars, 0) == FAIL)
return;
diff --git a/src/usercmd.c b/src/usercmd.c
index e2c0114..585ced3 100644
--- a/src/usercmd.c
+++ b/src/usercmd.c
@@ -16,6 +16,7 @@
typedef struct ucmd
{
char_u *uc_name; // The command name
+ size_t uc_namelen; // The length of the command name (excluding the NUL)
long_u uc_argt; // The argument type
char_u *uc_rep; // The command's replacement string
long uc_def; // The default value for a range/count
@@ -39,93 +40,100 @@ static int ucmd_locked = 0;
/*
* List of names for completion for ":command" with the EXPAND_ flag.
- * Must be alphabetical for completion.
+ * Must be alphabetical on the 'value' field for completion and because
+ * it is used by bsearch()!
*/
-static struct
+static keyvalue_T command_complete_tab[] =
{
- int expand;
- char *name;
-} command_complete[] =
-{
- {EXPAND_ARGLIST, "arglist"},
- {EXPAND_AUGROUP, "augroup"},
- {EXPAND_BEHAVE, "behave"},
- {EXPAND_BUFFERS, "buffer"},
- {EXPAND_COLORS, "color"},
- {EXPAND_COMMANDS, "command"},
- {EXPAND_COMPILER, "compiler"},
+ KEYVALUE_ENTRY(EXPAND_ARGLIST, "arglist"),
+ KEYVALUE_ENTRY(EXPAND_AUGROUP, "augroup"),
+ KEYVALUE_ENTRY(EXPAND_BEHAVE, "behave"),
+#if defined(FEAT_EVAL)
+ KEYVALUE_ENTRY(EXPAND_BREAKPOINT, "breakpoint"),
+#endif
+ KEYVALUE_ENTRY(EXPAND_BUFFERS, "buffer"),
+ KEYVALUE_ENTRY(EXPAND_COLORS, "color"),
+ KEYVALUE_ENTRY(EXPAND_COMMANDS, "command"),
+ KEYVALUE_ENTRY(EXPAND_COMPILER, "compiler"),
#if defined(FEAT_CSCOPE)
- {EXPAND_CSCOPE, "cscope"},
+ KEYVALUE_ENTRY(EXPAND_CSCOPE, "cscope"),
#endif
#if defined(FEAT_EVAL)
- {EXPAND_USER_DEFINED, "custom"},
- {EXPAND_USER_LIST, "customlist"},
+ KEYVALUE_ENTRY(EXPAND_USER_DEFINED, "custom"),
+ KEYVALUE_ENTRY(EXPAND_USER_LIST, "customlist"),
#endif
- {EXPAND_DIFF_BUFFERS, "diff_buffer"},
- {EXPAND_DIRECTORIES, "dir"},
- {EXPAND_ENV_VARS, "environment"},
- {EXPAND_EVENTS, "event"},
- {EXPAND_EXPRESSION, "expression"},
- {EXPAND_FILES, "file"},
- {EXPAND_FILES_IN_PATH, "file_in_path"},
- {EXPAND_FILETYPE, "filetype"},
- {EXPAND_FUNCTIONS, "function"},
- {EXPAND_HELP, "help"},
- {EXPAND_HIGHLIGHT, "highlight"},
- {EXPAND_HISTORY, "history"},
+ KEYVALUE_ENTRY(EXPAND_DIFF_BUFFERS, "diff_buffer"),
+ KEYVALUE_ENTRY(EXPAND_DIRECTORIES, "dir"),
+ KEYVALUE_ENTRY(EXPAND_DIRS_IN_CDPATH, "dir_in_path"),
+ KEYVALUE_ENTRY(EXPAND_ENV_VARS, "environment"),
+ KEYVALUE_ENTRY(EXPAND_EVENTS, "event"),
+ KEYVALUE_ENTRY(EXPAND_EXPRESSION, "expression"),
+ KEYVALUE_ENTRY(EXPAND_FILES, "file"),
+ KEYVALUE_ENTRY(EXPAND_FILES_IN_PATH, "file_in_path"),
+ KEYVALUE_ENTRY(EXPAND_FILETYPE, "filetype"),
+ KEYVALUE_ENTRY(EXPAND_FUNCTIONS, "function"),
+ KEYVALUE_ENTRY(EXPAND_HELP, "help"),
+ KEYVALUE_ENTRY(EXPAND_HIGHLIGHT, "highlight"),
+ KEYVALUE_ENTRY(EXPAND_HISTORY, "history"),
#if defined(FEAT_KEYMAP)
- {EXPAND_KEYMAP, "keymap"},
+ KEYVALUE_ENTRY(EXPAND_KEYMAP, "keymap"),
#endif
#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
- {EXPAND_LOCALES, "locale"},
+ KEYVALUE_ENTRY(EXPAND_LOCALES, "locale"),
#endif
- {EXPAND_MAPCLEAR, "mapclear"},
- {EXPAND_MAPPINGS, "mapping"},
- {EXPAND_MENUS, "menu"},
- {EXPAND_MESSAGES, "messages"},
- {EXPAND_OWNSYNTAX, "syntax"},
-#if defined(FEAT_PROFILE)
- {EXPAND_SYNTIME, "syntime"},
+ KEYVALUE_ENTRY(EXPAND_MAPCLEAR, "mapclear"),
+ KEYVALUE_ENTRY(EXPAND_MAPPINGS, "mapping"),
+ KEYVALUE_ENTRY(EXPAND_MENUS, "menu"),
+ KEYVALUE_ENTRY(EXPAND_MESSAGES, "messages"),
+ KEYVALUE_ENTRY(EXPAND_SETTINGS, "option"),
+ KEYVALUE_ENTRY(EXPAND_PACKADD, "packadd"),
+ KEYVALUE_ENTRY(EXPAND_RUNTIME, "runtime"),
+#if defined(FEAT_EVAL)
+ KEYVALUE_ENTRY(EXPAND_SCRIPTNAMES, "scriptnames"),
#endif
- {EXPAND_SETTINGS, "option"},
- {EXPAND_PACKADD, "packadd"},
- {EXPAND_RUNTIME, "runtime"},
- {EXPAND_SHELLCMD, "shellcmd"},
+ KEYVALUE_ENTRY(EXPAND_SHELLCMD, "shellcmd"),
#if defined(FEAT_SIGNS)
- {EXPAND_SIGN, "sign"},
+ KEYVALUE_ENTRY(EXPAND_SIGN, "sign"),
#endif
- {EXPAND_TAGS, "tag"},
- {EXPAND_TAGS_LISTFILES, "tag_listfiles"},
- {EXPAND_USER, "user"},
- {EXPAND_USER_VARS, "var"},
-#if defined(FEAT_EVAL)
- {EXPAND_BREAKPOINT, "breakpoint"},
- {EXPAND_SCRIPTNAMES, "scriptnames"},
+ KEYVALUE_ENTRY(EXPAND_OWNSYNTAX, "syntax"),
+#if defined(FEAT_PROFILE)
+ KEYVALUE_ENTRY(EXPAND_SYNTIME, "syntime"),
#endif
- {0, NULL}
+ KEYVALUE_ENTRY(EXPAND_TAGS, "tag"),
+ KEYVALUE_ENTRY(EXPAND_TAGS_LISTFILES, "tag_listfiles"),
+ KEYVALUE_ENTRY(EXPAND_USER, "user"),
+ KEYVALUE_ENTRY(EXPAND_USER_VARS, "var")
};
+typedef struct
+{
+ cmd_addr_T key;
+ char *fullname;
+ size_t fullnamelen;
+ char *shortname;
+ size_t shortnamelen;
+} addrtype_T;
+
/*
* List of names of address types. Must be alphabetical for completion.
+ * Must be sorted by the 'fullname' field because it is used by bsearch()!
*/
-static struct
+#define ADDRTYPE_ENTRY(k, fn, sn) \
+ {(k), (fn), STRLEN_LITERAL(fn), (sn), STRLEN_LITERAL(sn)}
+static addrtype_T addr_type_complete_tab[] =
{
- cmd_addr_T expand;
- char *name;
- char *shortname;
-} addr_type_complete[] =
-{
- {ADDR_ARGUMENTS, "arguments", "arg"},
- {ADDR_LINES, "lines", "line"},
- {ADDR_LOADED_BUFFERS, "loaded_buffers", "load"},
- {ADDR_TABS, "tabs", "tab"},
- {ADDR_BUFFERS, "buffers", "buf"},
- {ADDR_WINDOWS, "windows", "win"},
- {ADDR_QUICKFIX, "quickfix", "qf"},
- {ADDR_OTHER, "other", "?"},
- {ADDR_NONE, NULL, NULL}
+ ADDRTYPE_ENTRY(ADDR_ARGUMENTS, "arguments", "arg"),
+ ADDRTYPE_ENTRY(ADDR_BUFFERS, "buffers", "buf"),
+ ADDRTYPE_ENTRY(ADDR_LINES, "lines", "line"),
+ ADDRTYPE_ENTRY(ADDR_LOADED_BUFFERS, "loaded_buffers", "load"),
+ ADDRTYPE_ENTRY(ADDR_OTHER, "other", "?"),
+ ADDRTYPE_ENTRY(ADDR_QUICKFIX, "quickfix", "qf"),
+ ADDRTYPE_ENTRY(ADDR_TABS, "tabs", "tab"),
+ ADDRTYPE_ENTRY(ADDR_WINDOWS, "windows", "win")
};
+static int cmp_addr_type(const void *a, const void *b);
+
/*
* Search for a user command that matches "eap->cmd".
* Return cmdidx in "eap->cmdidx", flags in "eap->argt", idx in "eap->useridx".
@@ -271,19 +279,16 @@ set_context_in_user_cmd(expand_T *xp, char_u *arg_in)
{
xp->xp_context = EXPAND_USER_COMPLETE;
xp->xp_pattern = p + 1;
- return NULL;
}
else if (STRNICMP(arg, "nargs", p - arg) == 0)
{
xp->xp_context = EXPAND_USER_NARGS;
xp->xp_pattern = p + 1;
- return NULL;
}
else if (STRNICMP(arg, "addr", p - arg) == 0)
{
xp->xp_context = EXPAND_USER_ADDR_TYPE;
xp->xp_pattern = p + 1;
- return NULL;
}
return NULL;
}
@@ -416,7 +421,9 @@ get_user_command_name(int idx, int cmdidx)
char_u *
get_user_cmd_addr_type(expand_T *xp UNUSED, int idx)
{
- return (char_u *)addr_type_complete[idx].name;
+ if (idx < 0 || idx >= (int)ARRAY_LENGTH(addr_type_complete_tab))
+ return NULL;
+ return (char_u *)addr_type_complete_tab[idx].fullname;
}
/*
@@ -431,7 +438,7 @@ get_user_cmd_flags(expand_T *xp UNUSED, int idx)
"count", "nargs", "range", "register", "keepscript"
};
- if (idx >= (int)ARRAY_LENGTH(user_cmd_flags))
+ if (idx < 0 || idx >= (int)ARRAY_LENGTH(user_cmd_flags))
return NULL;
return (char_u *)user_cmd_flags[idx];
}
@@ -444,7 +451,7 @@ get_user_cmd_nargs(expand_T *xp UNUSED, int idx)
{
static char *user_cmd_nargs[] = {"0", "1", "*", "?", "+"};
- if (idx >= (int)ARRAY_LENGTH(user_cmd_nargs))
+ if (idx < 0 || idx >= (int)ARRAY_LENGTH(user_cmd_nargs))
return NULL;
return (char_u *)user_cmd_nargs[idx];
}
@@ -456,7 +463,24 @@ get_user_cmd_nargs(expand_T *xp UNUSED, int idx)
char_u *
get_user_cmd_complete(expand_T *xp UNUSED, int idx)
{
- return (char_u *)command_complete[idx].name;
+ if (idx < 0 || idx >= (int)ARRAY_LENGTH(command_complete_tab))
+ return NULL;
+ return (char_u *)command_complete_tab[idx].value;
+}
+
+/*
+ * Return the row in the command_complete_tab table that contains the given key.
+ */
+ static keyvalue_T *
+get_commandtype(int expand)
+{
+ int i;
+
+ for (i = 0; i < (int)ARRAY_LENGTH(command_complete_tab); ++i)
+ if (command_complete_tab[i].key == expand)
+ return &command_complete_tab[i];
+
+ return NULL;
}
#ifdef FEAT_EVAL
@@ -466,13 +490,11 @@ get_user_cmd_complete(expand_T *xp UNUSED, int idx)
char_u *
cmdcomplete_type_to_str(int expand)
{
- int i;
+ keyvalue_T *kv;
- for (i = 0; command_complete[i].expand != 0; i++)
- if (command_complete[i].expand == expand)
- return (char_u *)command_complete[i].name;
+ kv = get_commandtype(expand);
- return NULL;
+ return (kv == NULL) ? NULL : (char_u *)kv->value;
}
/*
@@ -482,18 +504,35 @@ cmdcomplete_type_to_str(int expand)
int
cmdcomplete_str_to_type(char_u *complete_str)
{
- int i;
+ keyvalue_T target;
+ keyvalue_T *entry;
+ static keyvalue_T *last_entry = NULL; // cached result
if (STRNCMP(complete_str, "custom,", 7) == 0)
return EXPAND_USER_DEFINED;
if (STRNCMP(complete_str, "customlist,", 11) == 0)
return EXPAND_USER_LIST;
- for (i = 0; command_complete[i].expand != 0; ++i)
- if (STRCMP(complete_str, command_complete[i].name) == 0)
- return command_complete[i].expand;
+ target.key = 0;
+ target.value = (char *)complete_str;
+ target.length = 0; // not used, see cmp_keyvalue_value()
+
+ if (last_entry != NULL && cmp_keyvalue_value(&target, last_entry) == 0)
+ entry = last_entry;
+ else
+ {
+ entry = (keyvalue_T *)bsearch(&target,
+ &command_complete_tab,
+ ARRAY_LENGTH(command_complete_tab),
+ sizeof(command_complete_tab[0]),
+ cmp_keyvalue_value);
+ if (entry == NULL)
+ return EXPAND_NOTHING;
+
+ last_entry = entry;
+ }
- return EXPAND_NOTHING;
+ return entry->key;
}
#endif
@@ -510,6 +549,7 @@ uc_list(char_u *name, size_t name_len)
int over;
long a;
garray_T *gap;
+ keyvalue_T *entry;
// don't allow for adding or removing user commands here
++ucmd_locked;
@@ -563,7 +603,7 @@ uc_list(char_u *name, size_t name_len)
msg_putchar(' ');
msg_outtrans_attr(cmd->uc_name, HL_ATTR(HLF_D));
- len = (int)STRLEN(cmd->uc_name) + 4;
+ len = (int)cmd->uc_namelen + 4;
do {
msg_putchar(' ');
@@ -595,16 +635,14 @@ uc_list(char_u *name, size_t name_len)
if (a & EX_COUNT)
{
// -count=N
- sprintf((char *)IObuff + len, "%ldc", cmd->uc_def);
- len += (int)STRLEN(IObuff + len);
+ len += vim_snprintf((char *)IObuff + len, IOSIZE - len, "%ldc", cmd->uc_def);
}
else if (a & EX_DFLALL)
IObuff[len++] = '%';
else if (cmd->uc_def >= 0)
{
// -range=N
- sprintf((char *)IObuff + len, "%ld", cmd->uc_def);
- len += (int)STRLEN(IObuff + len);
+ len += vim_snprintf((char *)IObuff + len, IOSIZE - len, "%ld", cmd->uc_def);
}
else
IObuff[len++] = '.';
@@ -615,12 +653,12 @@ uc_list(char_u *name, size_t name_len)
} while (len < 8 - over);
// Address Type
- for (j = 0; addr_type_complete[j].expand != ADDR_NONE; ++j)
- if (addr_type_complete[j].expand != ADDR_LINES
- && addr_type_complete[j].expand == cmd->uc_addr_type)
+ for (j = 0; j < (int)ARRAY_LENGTH(addr_type_complete_tab); ++j)
+ if (addr_type_complete_tab[j].key != ADDR_LINES
+ && addr_type_complete_tab[j].key == cmd->uc_addr_type)
{
- STRCPY(IObuff + len, addr_type_complete[j].shortname);
- len += (int)STRLEN(IObuff + len);
+ STRCPY(IObuff + len, addr_type_complete_tab[j].shortname);
+ len += (int)addr_type_complete_tab[j].shortnamelen;
break;
}
@@ -629,28 +667,31 @@ uc_list(char_u *name, size_t name_len)
} while (len < 13 - over);
// Completion
- for (j = 0; command_complete[j].expand != 0; ++j)
- if (command_complete[j].expand == cmd->uc_compl)
- {
- STRCPY(IObuff + len, command_complete[j].name);
- len += (int)STRLEN(IObuff + len);
+ entry = get_commandtype(cmd->uc_compl);
+ if (entry != NULL)
+ {
+ STRCPY(IObuff + len, entry->value);
+ len += entry->length;
#ifdef FEAT_EVAL
- if (p_verbose > 0 && cmd->uc_compl_arg != NULL
- && STRLEN(cmd->uc_compl_arg) < 200)
+ if (p_verbose > 0 && cmd->uc_compl_arg != NULL)
+ {
+ size_t uc_compl_arglen = STRLEN(cmd->uc_compl_arg);
+
+ if (uc_compl_arglen < 200)
{
- IObuff[len] = ',';
- STRCPY(IObuff + len + 1, cmd->uc_compl_arg);
- len += (int)STRLEN(IObuff + len);
+ IObuff[len++] = ',';
+ STRCPY(IObuff + len, cmd->uc_compl_arg);
+ len += uc_compl_arglen;
}
-#endif
- break;
}
+#endif
+ }
do {
IObuff[len++] = ' ';
} while (len < 25 - over);
- IObuff[len] = '\0';
+ IObuff[len] = NUL;
msg_outtrans(IObuff);
msg_outtrans_special(cmd->uc_rep, FALSE,
@@ -686,7 +727,7 @@ uc_fun_cmd(void)
for (i = 0; fcmd[i]; ++i)
IObuff[i] = fcmd[i] - 0x40;
- IObuff[i] = 0;
+ IObuff[i] = NUL;
return (char *)IObuff;
}
@@ -699,33 +740,52 @@ parse_addr_type_arg(
int vallen,
cmd_addr_T *addr_type_arg)
{
- int i, a, b;
+ addrtype_T target;
+ addrtype_T *entry;
+ static addrtype_T *last_entry; // cached result
+
+ target.key = 0;
+ target.fullname = (char *)value;
+ target.fullnamelen = vallen;
- for (i = 0; addr_type_complete[i].expand != ADDR_NONE; ++i)
+ if (last_entry != NULL && cmp_addr_type(&target, last_entry) == 0)
+ entry = last_entry;
+ else
{
- a = (int)STRLEN(addr_type_complete[i].name) == vallen;
- b = STRNCMP(value, addr_type_complete[i].name, vallen) == 0;
- if (a && b)
+ entry = (addrtype_T *)bsearch(&target,
+ &addr_type_complete_tab,
+ ARRAY_LENGTH(addr_type_complete_tab),
+ sizeof(addr_type_complete_tab[0]),
+ cmp_addr_type);
+ if (entry == NULL)
{
- *addr_type_arg = addr_type_complete[i].expand;
- break;
- }
- }
+ int i;
+ char_u *err = value;
- if (addr_type_complete[i].expand == ADDR_NONE)
- {
- char_u *err = value;
+ for (i = 0; err[i] != NUL && !VIM_ISWHITE(err[i]); i++)
+ ;
+ err[i] = NUL;
+ semsg(_(e_invalid_address_type_value_str), err);
+ return FAIL;
+ }
- for (i = 0; err[i] != NUL && !VIM_ISWHITE(err[i]); i++)
- ;
- err[i] = NUL;
- semsg(_(e_invalid_address_type_value_str), err);
- return FAIL;
+ last_entry = entry;
}
+ *addr_type_arg = entry->key;
+
return OK;
}
+ static int
+cmp_addr_type(const void *a, const void *b)
+{
+ addrtype_T *at1 = (addrtype_T *)a;
+ addrtype_T *at2 = (addrtype_T *)b;
+
+ return STRNCMP(at1->fullname, at2->fullname, MAX(at1->fullnamelen, at2->fullnamelen));
+}
+
/*
* Parse a completion argument "value[vallen]".
* The detected completion goes in "*complp", argument type in "*argt".
@@ -747,6 +807,9 @@ parse_compl_arg(
# endif
int i;
int valend = vallen;
+ keyvalue_T target;
+ keyvalue_T *entry;
+ static keyvalue_T *last_entry = NULL; // cached result
// Look for any argument part - which is the part after any ','
for (i = 0; i < vallen; ++i)
@@ -762,33 +825,40 @@ parse_compl_arg(
}
}
- for (i = 0; command_complete[i].expand != 0; ++i)
+ target.key = 0;
+ target.value = (char *)value;
+ target.length = valend;
+
+ if (last_entry != NULL && cmp_keyvalue_value_n(&target, last_entry) == 0)
+ entry = last_entry;
+ else
{
- if ((int)STRLEN(command_complete[i].name) == valend
- && STRNCMP(value, command_complete[i].name, valend) == 0)
+ entry = (keyvalue_T *)bsearch(&target,
+ &command_complete_tab,
+ ARRAY_LENGTH(command_complete_tab),
+ sizeof(command_complete_tab[0]),
+ cmp_keyvalue_value_n);
+ if (entry == NULL)
{
- *complp = command_complete[i].expand;
- if (command_complete[i].expand == EXPAND_BUFFERS)
- *argt |= EX_BUFNAME;
- else if (command_complete[i].expand == EXPAND_DIRECTORIES
- || command_complete[i].expand == EXPAND_FILES)
- *argt |= EX_XFILE;
- break;
+ semsg(_(e_invalid_complete_value_str), value);
+ return FAIL;
}
- }
- if (command_complete[i].expand == 0)
- {
- semsg(_(e_invalid_complete_value_str), value);
- return FAIL;
+ last_entry = entry;
}
+ *complp = entry->key;
+ if (*complp == EXPAND_BUFFERS)
+ *argt |= EX_BUFNAME;
+ else if (*complp == EXPAND_DIRECTORIES || *complp == EXPAND_FILES)
+ *argt |= EX_XFILE;
+
+ if (
# if defined(FEAT_EVAL)
- if (*complp != EXPAND_USER_DEFINED && *complp != EXPAND_USER_LIST
- && arg != NULL)
-# else
- if (arg != NULL)
+ *complp != EXPAND_USER_DEFINED && *complp != EXPAND_USER_LIST
+ &&
# endif
+ arg != NULL)
{
emsg(_(e_completion_argument_only_allowed_for_custom_completion));
return FAIL;
@@ -805,6 +875,7 @@ parse_compl_arg(
if (arg != NULL)
*compl_arg = vim_strnsave(arg, arglen);
# endif
+
return OK;
}
@@ -1022,16 +1093,13 @@ uc_add_command(
// Search for the command in the already defined commands.
for (i = 0; i < gap->ga_len; ++i)
{
- size_t len;
-
cmd = USER_CMD_GA(gap, i);
- len = STRLEN(cmd->uc_name);
cmp = STRNCMP(name, cmd->uc_name, name_len);
if (cmp == 0)
{
- if (name_len < len)
+ if (name_len < cmd->uc_namelen)
cmp = -1;
- else if (name_len > len)
+ else if (name_len > cmd->uc_namelen)
cmp = 1;
}
@@ -1077,6 +1145,7 @@ uc_add_command(
++gap->ga_len;
cmd->uc_name = p;
+ cmd->uc_namelen = name_len;
}
cmd->uc_rep = rep_buf;
@@ -1198,7 +1267,7 @@ ex_command(exarg_T *eap)
p = skipwhite(end);
if (!has_attr && ends_excmd2(eap->arg, p))
{
- uc_list(name, end - name);
+ uc_list(name, name_len);
}
else if (!ASCII_ISUPPER(*name))
{
@@ -1281,6 +1350,7 @@ uc_clear(garray_T *gap)
{
cmd = USER_CMD_GA(gap, i);
vim_free(cmd->uc_name);
+ cmd->uc_namelen = 0;
vim_free(cmd->uc_rep);
# if defined(FEAT_EVAL)
vim_free(cmd->uc_compl_arg);
@@ -1438,30 +1508,31 @@ uc_split_args(char_u *arg, size_t *lenp)
}
}
*q++ = '"';
- *q = 0;
+ *q = NUL;
*lenp = len;
return buf;
}
static size_t
-add_cmd_modifier(char_u *buf, char *mod_str, int *multi_mods)
+add_cmd_modifier(char_u *buf, size_t buflen, char *mod_str, size_t mod_strlen, int *multi_mods)
{
- size_t result;
-
- result = STRLEN(mod_str);
- if (*multi_mods)
- result += 1;
if (buf != NULL)
{
if (*multi_mods)
- STRCAT(buf, " ");
- STRCAT(buf, mod_str);
+ {
+ STRCPY(buf + buflen, " "); // the separating space
+ ++buflen;
+ }
+ STRCPY(buf + buflen, mod_str);
}
- *multi_mods = 1;
+ if (*multi_mods)
+ ++mod_strlen; // +1 for the separating space
+ else
+ *multi_mods = 1;
- return result;
+ return mod_strlen;
}
/*
@@ -1471,17 +1542,17 @@ add_cmd_modifier(char_u *buf, char *mod_str, int *multi_mods)
size_t
add_win_cmd_modifiers(char_u *buf, cmdmod_T *cmod, int *multi_mods)
{
- size_t result = 0;
+ size_t buflen = 0;
// :aboveleft and :leftabove
if (cmod->cmod_split & WSP_ABOVE)
- result += add_cmd_modifier(buf, "aboveleft", multi_mods);
+ buflen += add_cmd_modifier(buf, buflen, "aboveleft", STRLEN_LITERAL("aboveleft"), multi_mods);
// :belowright and :rightbelow
if (cmod->cmod_split & WSP_BELOW)
- result += add_cmd_modifier(buf, "belowright", multi_mods);
+ buflen += add_cmd_modifier(buf, buflen, "belowright", STRLEN_LITERAL("belowright"), multi_mods);
// :botright
if (cmod->cmod_split & WSP_BOT)
- result += add_cmd_modifier(buf, "botright", multi_mods);
+ buflen += add_cmd_modifier(buf, buflen, "botright", STRLEN_LITERAL("botright"), multi_mods);
// :tab
if (cmod->cmod_tab > 0)
@@ -1492,27 +1563,29 @@ add_win_cmd_modifiers(char_u *buf, cmdmod_T *cmod, int *multi_mods)
{
// For compatibility, don't add a tabpage number if it is the same
// as the default number for :tab.
- result += add_cmd_modifier(buf, "tab", multi_mods);
+ buflen += add_cmd_modifier(buf, buflen, "tab", STRLEN_LITERAL("tab"), multi_mods);
}
else
{
char tab_buf[NUMBUFLEN + 3];
+ size_t tab_buflen;
- sprintf(tab_buf, "%dtab", tabnr);
- result += add_cmd_modifier(buf, tab_buf, multi_mods);
+ tab_buflen = vim_snprintf(tab_buf, sizeof(tab_buf), "%dtab", tabnr);
+ buflen += add_cmd_modifier(buf, buflen, tab_buf, tab_buflen, multi_mods);
}
}
// :topleft
if (cmod->cmod_split & WSP_TOP)
- result += add_cmd_modifier(buf, "topleft", multi_mods);
+ buflen += add_cmd_modifier(buf, buflen, "topleft", STRLEN_LITERAL("topleft"), multi_mods);
// :vertical
if (cmod->cmod_split & WSP_VERT)
- result += add_cmd_modifier(buf, "vertical", multi_mods);
+ buflen += add_cmd_modifier(buf, buflen, "vertical", STRLEN_LITERAL("vertical"), multi_mods);
// :horizontal
if (cmod->cmod_split & WSP_HOR)
- result += add_cmd_modifier(buf, "horizontal", multi_mods);
- return result;
+ buflen += add_cmd_modifier(buf, buflen, "horizontal", STRLEN_LITERAL("horizontal"), multi_mods);
+
+ return buflen;
}
/*
@@ -1522,78 +1595,92 @@ add_win_cmd_modifiers(char_u *buf, cmdmod_T *cmod, int *multi_mods)
size_t
produce_cmdmods(char_u *buf, cmdmod_T *cmod, int quote)
{
- size_t result = 0;
+ size_t buflen = 0;
int multi_mods = 0;
int i;
- typedef struct {
- int flag;
- char *name;
- } mod_entry_T;
- static mod_entry_T mod_entries[] = {
+ static keyvalue_T mod_entry_tab[] =
+ {
#ifdef FEAT_BROWSE_CMD
- {CMOD_BROWSE, "browse"},
+ KEYVALUE_ENTRY(CMOD_BROWSE, "browse"),
#endif
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
- {CMOD_CONFIRM, "confirm"},
+ KEYVALUE_ENTRY(CMOD_CONFIRM, "confirm"),
#endif
- {CMOD_HIDE, "hide"},
- {CMOD_KEEPALT, "keepalt"},
- {CMOD_KEEPJUMPS, "keepjumps"},
- {CMOD_KEEPMARKS, "keepmarks"},
- {CMOD_KEEPPATTERNS, "keeppatterns"},
- {CMOD_LOCKMARKS, "lockmarks"},
- {CMOD_NOSWAPFILE, "noswapfile"},
- {CMOD_UNSILENT, "unsilent"},
- {CMOD_NOAUTOCMD, "noautocmd"},
+ KEYVALUE_ENTRY(CMOD_HIDE, "hide"),
+ KEYVALUE_ENTRY(CMOD_KEEPALT, "keepalt"),
+ KEYVALUE_ENTRY(CMOD_KEEPJUMPS, "keepjumps"),
+ KEYVALUE_ENTRY(CMOD_KEEPMARKS, "keepmarks"),
+ KEYVALUE_ENTRY(CMOD_KEEPPATTERNS, "keeppatterns"),
+ KEYVALUE_ENTRY(CMOD_LOCKMARKS, "lockmarks"),
+ KEYVALUE_ENTRY(CMOD_NOSWAPFILE, "noswapfile"),
+ KEYVALUE_ENTRY(CMOD_UNSILENT, "unsilent"),
+ KEYVALUE_ENTRY(CMOD_NOAUTOCMD, "noautocmd"),
#ifdef HAVE_SANDBOX
- {CMOD_SANDBOX, "sandbox"},
+ KEYVALUE_ENTRY(CMOD_SANDBOX, "sandbox"),
#endif
- {CMOD_LEGACY, "legacy"},
- {0, NULL}
+ KEYVALUE_ENTRY(CMOD_LEGACY, "legacy")
};
- result = quote ? 2 : 0;
- if (buf != NULL)
+ if (quote)
{
- if (quote)
- *buf++ = '"';
- *buf = '\0';
+ ++buflen;
+ if (buf != NULL)
+ {
+ *buf = '"';
+ *(buf + buflen) = NUL;
+ }
}
+ else
+ if (buf != NULL)
+ *buf = NUL;
// the modifiers that are simple flags
- for (i = 0; mod_entries[i].name != NULL; ++i)
- if (cmod->cmod_flags & mod_entries[i].flag)
- result += add_cmd_modifier(buf, mod_entries[i].name, &multi_mods);
+ for (i = 0; i < (int)ARRAY_LENGTH(mod_entry_tab); ++i)
+ if (cmod->cmod_flags & mod_entry_tab[i].key)
+ buflen += add_cmd_modifier(buf, buflen, mod_entry_tab[i].value, mod_entry_tab[i].length, &multi_mods);
// :silent
if (cmod->cmod_flags & CMOD_SILENT)
- result += add_cmd_modifier(buf,
- (cmod->cmod_flags & CMOD_ERRSILENT) ? "silent!"
- : "silent", &multi_mods);
+ {
+ if (cmod->cmod_flags & CMOD_ERRSILENT)
+ buflen += add_cmd_modifier(buf, buflen, "silent!", STRLEN_LITERAL("silent!"), &multi_mods);
+ else
+ buflen += add_cmd_modifier(buf, buflen, "silent", STRLEN_LITERAL("silent"), &multi_mods);
+ }
+
// :verbose
if (cmod->cmod_verbose > 0)
{
int verbose_value = cmod->cmod_verbose - 1;
if (verbose_value == 1)
- result += add_cmd_modifier(buf, "verbose", &multi_mods);
+ buflen += add_cmd_modifier(buf, buflen, "verbose", STRLEN_LITERAL("verbose"), &multi_mods);
else
{
char verbose_buf[NUMBUFLEN];
+ size_t verbose_buflen;
- sprintf(verbose_buf, "%dverbose", verbose_value);
- result += add_cmd_modifier(buf, verbose_buf, &multi_mods);
+ verbose_buflen = vim_snprintf(verbose_buf, sizeof(verbose_buf), "%dverbose", verbose_value);
+ buflen += add_cmd_modifier(buf, buflen, verbose_buf, verbose_buflen, &multi_mods);
}
}
+
// flags from cmod->cmod_split
- result += add_win_cmd_modifiers(buf, cmod, &multi_mods);
+ buflen += add_win_cmd_modifiers((buf == NULL) ? NULL : buf + buflen, cmod, &multi_mods);
- if (quote && buf != NULL)
+ if (quote)
{
- buf += result - 2;
- *buf = '"';
+ if (buf == NULL)
+ ++buflen;
+ else
+ {
+ *(buf + buflen) = '"';
+ ++buflen;
+ *(buf + buflen) = NUL;
+ }
}
- return result;
+
+ return buflen;
}
/*
@@ -1754,15 +1841,14 @@ uc_check_code(
case ct_RANGE:
case ct_COUNT:
{
- char num_buf[20];
+ char num_buf[NUMBUFLEN];
long num = (type == ct_LINE1) ? eap->line1 :
(type == ct_LINE2) ? eap->line2 :
(type == ct_RANGE) ? eap->addr_count :
(eap->addr_count > 0) ? eap->line2 : cmd->uc_def;
size_t num_len;
- sprintf(num_buf, "%ld", num);
- num_len = STRLEN(num_buf);
+ num_len = vim_snprintf(num_buf, sizeof(num_buf), "%ld", num);
result = num_len;
if (quote)
diff --git a/src/userfunc.c b/src/userfunc.c
index 7536234..5d16710 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -2212,6 +2212,49 @@ find_func_with_prefix(char_u *name, int sid)
}
/*
+ * Find a function by name, return pointer to it.
+ * The name may be a local script variable, VAR_FUNC. or it may be a fully
+ * qualified import name such as 'i_imp.FuncName'.
+ *
+ * When VAR_FUNC, the import might either direct or autoload.
+ * When 'i_imp.FuncName' it is direct, autoload is rewritten as i_imp#FuncName
+ * in f_call and subsequently found.
+ */
+ static ufunc_T *
+find_func_imported(char_u *name, int flags)
+{
+ ufunc_T *func = NULL;
+ char_u *dot = name; // Find a dot, '.', in the name
+
+ // Either run into '.' or the end of the string
+ while (eval_isnamec(*dot))
+ ++dot;
+
+ if (*dot == '.')
+ {
+ imported_T *import = find_imported(name, dot - name, FALSE);
+ if (import != NULL)
+ func = find_func_with_sid(dot + 1, import->imp_sid);
+ }
+ else if (*dot == NUL) // looking at the entire string
+ {
+ hashtab_T *ht = get_script_local_ht();
+ if (ht != NULL)
+ {
+ hashitem_T *hi = hash_find(ht, name);
+ if (!HASHITEM_EMPTY(hi))
+ {
+ dictitem_T *di = HI2DI(hi);
+ if (di->di_tv.v_type == VAR_FUNC
+ && di->di_tv.vval.v_string != NULL)
+ func = find_func_even_dead(di->di_tv.vval.v_string, flags);
+ }
+ }
+ }
+ return func;
+}
+
+/*
* Find a function by name, return pointer to it in ufuncs.
* When "flags" has FFED_IS_GLOBAL don't find script-local or imported
* functions.
@@ -2260,8 +2303,15 @@ find_func_even_dead(char_u *name, int flags)
}
// Find autoload function if this is an autoload script.
- return find_func_with_prefix(name[0] == 's' && name[1] == ':'
+ func = find_func_with_prefix(name[0] == 's' && name[1] == ':'
? name + 2 : name, current_sctx.sc_sid);
+ if (func != NULL)
+ return func;
+
+ // Find a script-local "VAR_FUNC" or i_"imp.Func", so vim9script).
+ if (in_vim9script())
+ func = find_func_imported(name, flags);
+ return func;
}
/*
@@ -4009,7 +4059,7 @@ theend:
int
call_simple_func(
char_u *funcname, // name of the function
- int len, // length of "name" or -1 to use strlen()
+ size_t len, // length of "name"
typval_T *rettv) // return value goes here
{
int ret = FAIL;
@@ -5503,6 +5553,47 @@ ex_function(exarg_T *eap)
ga_clear_strings(&lines_to_free);
}
+ int
+get_func_arity(char_u *name, int *required, int *optional, int *varargs)
+{
+ ufunc_T *ufunc = NULL;
+ int argcount = 0;
+ int min_argcount = 0;
+ int idx;
+
+ idx = find_internal_func(name);
+ if (idx >= 0)
+ {
+ internal_func_get_argcount(idx, &argcount, &min_argcount);
+ *varargs = FALSE;
+ }
+ else
+ {
+ char_u fname_buf[FLEN_FIXED + 1];
+ char_u *tofree = NULL;
+ funcerror_T error = FCERR_NONE;
+ char_u *fname;
+
+ // May need to translate <SNR>123_ to K_SNR.
+ fname = fname_trans_sid(name, fname_buf, &tofree, &error);
+ if (error == FCERR_NONE)
+ ufunc = find_func(fname, FALSE);
+ vim_free(tofree);
+
+ if (ufunc == NULL)
+ return FAIL;
+
+ argcount = ufunc->uf_args.ga_len;
+ min_argcount = ufunc->uf_args.ga_len - ufunc->uf_def_args.ga_len;
+ *varargs = has_varargs(ufunc);
+ }
+
+ *required = min_argcount;
+ *optional = argcount - min_argcount;
+
+ return OK;
+}
+
/*
* Find a function by name, including "<lambda>123".
* Check for "profile" and "debug" arguments and set"compile_type".
diff --git a/src/version.c b/src/version.c
index 14a5922..314a320 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,410 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 698,
+/**/
+ 697,
+/**/
+ 696,
+/**/
+ 695,
+/**/
+ 694,
+/**/
+ 693,
+/**/
+ 692,
+/**/
+ 691,
+/**/
+ 690,
+/**/
+ 689,
+/**/
+ 688,
+/**/
+ 687,
+/**/
+ 686,
+/**/
+ 685,
+/**/
+ 684,
+/**/
+ 683,
+/**/
+ 682,
+/**/
+ 681,
+/**/
+ 680,
+/**/
+ 679,
+/**/
+ 678,
+/**/
+ 677,
+/**/
+ 676,
+/**/
+ 675,
+/**/
+ 674,
+/**/
+ 673,
+/**/
+ 672,
+/**/
+ 671,
+/**/
+ 670,
+/**/
+ 669,
+/**/
+ 668,
+/**/
+ 667,
+/**/
+ 666,
+/**/
+ 665,
+/**/
+ 664,
+/**/
+ 663,
+/**/
+ 662,
+/**/
+ 661,
+/**/
+ 660,
+/**/
+ 659,
+/**/
+ 658,
+/**/
+ 657,
+/**/
+ 656,
+/**/
+ 655,
+/**/
+ 654,
+/**/
+ 653,
+/**/
+ 652,
+/**/
+ 651,
+/**/
+ 650,
+/**/
+ 649,
+/**/
+ 648,
+/**/
+ 647,
+/**/
+ 646,
+/**/
+ 645,
+/**/
+ 644,
+/**/
+ 643,
+/**/
+ 642,
+/**/
+ 641,
+/**/
+ 640,
+/**/
+ 639,
+/**/
+ 638,
+/**/
+ 637,
+/**/
+ 636,
+/**/
+ 635,
+/**/
+ 634,
+/**/
+ 633,
+/**/
+ 632,
+/**/
+ 631,
+/**/
+ 630,
+/**/
+ 629,
+/**/
+ 628,
+/**/
+ 627,
+/**/
+ 626,
+/**/
+ 625,
+/**/
+ 624,
+/**/
+ 623,
+/**/
+ 622,
+/**/
+ 621,
+/**/
+ 620,
+/**/
+ 619,
+/**/
+ 618,
+/**/
+ 617,
+/**/
+ 616,
+/**/
+ 615,
+/**/
+ 614,
+/**/
+ 613,
+/**/
+ 612,
+/**/
+ 611,
+/**/
+ 610,
+/**/
+ 609,
+/**/
+ 608,
+/**/
+ 607,
+/**/
+ 606,
+/**/
+ 605,
+/**/
+ 604,
+/**/
+ 603,
+/**/
+ 602,
+/**/
+ 601,
+/**/
+ 600,
+/**/
+ 599,
+/**/
+ 598,
+/**/
+ 597,
+/**/
+ 596,
+/**/
+ 595,
+/**/
+ 594,
+/**/
+ 593,
+/**/
+ 592,
+/**/
+ 591,
+/**/
+ 590,
+/**/
+ 589,
+/**/
+ 588,
+/**/
+ 587,
+/**/
+ 586,
+/**/
+ 585,
+/**/
+ 584,
+/**/
+ 583,
+/**/
+ 582,
+/**/
+ 581,
+/**/
+ 580,
+/**/
+ 579,
+/**/
+ 578,
+/**/
+ 577,
+/**/
+ 576,
+/**/
+ 575,
+/**/
+ 574,
+/**/
+ 573,
+/**/
+ 572,
+/**/
+ 571,
+/**/
+ 570,
+/**/
+ 569,
+/**/
+ 568,
+/**/
+ 567,
+/**/
+ 566,
+/**/
+ 565,
+/**/
+ 564,
+/**/
+ 563,
+/**/
+ 562,
+/**/
+ 561,
+/**/
+ 560,
+/**/
+ 559,
+/**/
+ 558,
+/**/
+ 557,
+/**/
+ 556,
+/**/
+ 555,
+/**/
+ 554,
+/**/
+ 553,
+/**/
+ 552,
+/**/
+ 551,
+/**/
+ 550,
+/**/
+ 549,
+/**/
+ 548,
+/**/
+ 547,
+/**/
+ 546,
+/**/
+ 545,
+/**/
+ 544,
+/**/
+ 543,
+/**/
+ 542,
+/**/
+ 541,
+/**/
+ 540,
+/**/
+ 539,
+/**/
+ 538,
+/**/
+ 537,
+/**/
+ 536,
+/**/
+ 535,
+/**/
+ 534,
+/**/
+ 533,
+/**/
+ 532,
+/**/
+ 531,
+/**/
+ 530,
+/**/
+ 529,
+/**/
+ 528,
+/**/
+ 527,
+/**/
+ 526,
+/**/
+ 525,
+/**/
+ 524,
+/**/
+ 523,
+/**/
+ 522,
+/**/
+ 521,
+/**/
+ 520,
+/**/
+ 519,
+/**/
+ 518,
+/**/
+ 517,
+/**/
+ 516,
+/**/
+ 515,
+/**/
+ 514,
+/**/
+ 513,
+/**/
+ 512,
+/**/
+ 511,
+/**/
+ 510,
+/**/
+ 509,
+/**/
+ 508,
+/**/
+ 507,
+/**/
+ 506,
+/**/
+ 505,
+/**/
+ 504,
+/**/
+ 503,
+/**/
+ 502,
+/**/
+ 501,
+/**/
+ 500,
+/**/
+ 499,
+/**/
+ 498,
+/**/
+ 497,
+/**/
496,
/**/
495,
diff --git a/src/vim.h b/src/vim.h
index e703239..9c1434c 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -598,7 +598,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
# ifdef bindtextdomain
# undef bindtextdomain
# endif
-# define bindtextdomain(x, y) // empty
+# define bindtextdomain(x, y) ""
# ifdef bind_textdomain_codeset
# undef bind_textdomain_codeset
# endif
@@ -843,6 +843,8 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define EXPAND_ARGOPT 56
#define EXPAND_TERMINALOPT 57
#define EXPAND_KEYMAP 58
+#define EXPAND_DIRS_IN_CDPATH 59
+
// Values for exmode_active (0 is no exmode)
#define EXMODE_NORMAL 1
@@ -898,6 +900,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define EW_DODOT 0x4000 // also files starting with a dot
#define EW_EMPTYOK 0x8000 // no matches is not an error
#define EW_NOTENV 0x10000 // do not expand environment variables
+#define EW_CDPATH 0x20000 // search in 'cdpath' too
// Flags for find_file_*() functions.
#define FINDFILE_FILE 0 // only files
@@ -1074,6 +1077,8 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
// Values for flags argument of do_buffer()
#define DOBUF_FORCEIT 1 // :cmd!
#define DOBUF_NOPOPUP 2 // skip popup window buffers
+#define DOBUF_SKIPHELP 4 // skip or keep help buffers depending on b_help of the
+ // starting buffer
// Values for sub_cmd and which_pat argument for search_regcomp()
// Also used for which_pat argument for searchit()
@@ -1361,6 +1366,7 @@ enum auto_event
EVENT_CURSORHOLD, // cursor in same position for a while
EVENT_CURSORHOLDI, // idem, in Insert mode
EVENT_CURSORMOVED, // cursor was moved
+ EVENT_CURSORMOVEDC, // cursor was moved in Command line mode
EVENT_CURSORMOVEDI, // cursor was moved in Insert mode
EVENT_DIFFUPDATED, // after diffs were updated
EVENT_DIRCHANGED, // after user changed directory
@@ -1394,6 +1400,7 @@ enum auto_event
EVENT_INSERTENTER, // when entering Insert mode
EVENT_INSERTLEAVEPRE, // just before leaving Insert mode
EVENT_INSERTLEAVE, // just after leaving Insert mode
+ EVENT_KEYINPUTPRE, // before key input
EVENT_MENUPOPUP, // just before popup menu is displayed
EVENT_MODECHANGED, // after changing the mode
EVENT_OPTIONSET, // option was set
@@ -1762,6 +1769,7 @@ void *vim_memset(void *, int, size_t);
# define MB_STRICMP(d, s) mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL)
# define MB_STRNICMP(d, s, n) mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n))
+# define MB_STRNICMP2(d, s, n1, n2) mb_strnicmp2((char_u *)(d), (char_u *)(s), (n1), (n2))
#define STRCAT(d, s) strcat((char *)(d), (char *)(s))
#define STRNCAT(d, s, n) strncat((char *)(d), (char *)(s), (size_t)(n))
diff --git a/src/vim9.h b/src/vim9.h
index 54938fe..c502ac4 100644
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -238,8 +238,9 @@ typedef struct {
// arguments to ISN_METHODCALL
typedef struct {
class_T *cmf_itf; // interface used
- int cmf_idx; // index in "def_functions" for ISN_DCALL
+ int cmf_idx; // index in "def_functions" for ISN_METHODCALL
int cmf_argcount; // number of arguments on top of stack
+ int cmf_is_super; // doing "super.Func", use cmf_itf, not cmf_idx
} cmfunc_T;
// arguments to ISN_PCALL
diff --git a/src/vim9class.c b/src/vim9class.c
index f66aa68..d8813c6 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -1280,6 +1280,7 @@ add_class_members(class_T *cl, exarg_T *eap, garray_T *type_list_gap)
tv->v_type = m->ocm_type->tt_type;
tv->vval.v_string = NULL;
}
+ set_tv_type(tv, m->ocm_type);
if (m->ocm_flags & OCMFLAG_CONST)
item_lock(tv, DICT_MAXNEST, TRUE, TRUE);
}
@@ -2664,7 +2665,7 @@ typealias_unref(typealias_T *ta)
* Handle ":type". Create an alias for a type specification.
*/
void
-ex_type(exarg_T *eap UNUSED)
+ex_type(exarg_T *eap)
{
char_u *arg = eap->arg;
@@ -3100,7 +3101,7 @@ class_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
{
ret_m = m;
ret_idx = i;
- break;
+ break;
}
}
if (idx != NULL)
@@ -3183,11 +3184,11 @@ object_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
}
}
else if (STRCMP(name, m->ocm_name) == 0)
- {
+ {
ret_m = m;
ret_idx = i;
- break;
- }
+ break;
+ }
}
if (idx != NULL)
*idx = ret_idx;
@@ -3683,7 +3684,7 @@ method_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len)
}
else
semsg(_(e_method_not_found_on_class_str_str), method_name,
- cl->class_name);
+ cl->class_name);
vim_free(method_name);
}
@@ -3842,7 +3843,38 @@ object_len(object_T *obj)
}
/*
- * Return a textual representation of object "obj"
+ * Return TRUE when two objects have exactly the same values.
+ */
+ int
+object_equal(
+ object_T *o1,
+ object_T *o2,
+ int ic) // ignore case for strings
+{
+ class_T *cl1, *cl2;
+
+ if (o1 == o2)
+ return TRUE;
+ if (o1 == NULL || o2 == NULL)
+ return FALSE;
+
+ cl1 = o1->obj_class;
+ cl2 = o2->obj_class;
+
+ if (cl1 != cl2 || cl1 == NULL || cl2 == NULL)
+ return FALSE;
+
+ for (int i = 0; i < cl1->class_obj_member_count; ++i)
+ if (!tv_equal((typval_T *)(o1 + 1) + i, (typval_T *)(o2 + 1) + i, ic))
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Return a textual representation of object "obj".
+ * "obj" must not be NULL.
+ * May return NULL.
*/
char_u *
object2string(
@@ -3859,47 +3891,58 @@ object2string(
== OK
&& rettv.vval.v_string != NULL)
return rettv.vval.v_string;
+
+ int ok = OK;
+ class_T *cl = obj->obj_class;
+ garray_T ga;
+ ga_init2(&ga, 1, 50);
+
+ 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
{
- garray_T ga;
- ga_init2(&ga, 1, 50);
-
- class_T *cl = obj == NULL ? NULL : obj->obj_class;
- 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 *)" {");
- for (int i = 0; i < cl->class_obj_member_count; ++i)
+ 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 *)" {");
+ for (int i = 0; i < cl->class_obj_member_count; ++i)
+ {
+ if (i > 0)
+ ga_concat(&ga, (char_u *)", ");
+ ocmember_T *m = &cl->class_obj_members[i];
+ ga_concat(&ga, m->ocm_name);
+ ga_concat(&ga, (char_u *)": ");
+ char_u *tf = NULL;
+ char_u *s = echo_string_core((typval_T *)(obj + 1) + i,
+ &tf, numbuf, copyID, echo_style,
+ restore_copyID, composite_val);
+ if (s != NULL)
+ ga_concat(&ga, s);
+ vim_free(tf);
+ if (s == NULL || did_echo_string_emsg)
{
- if (i > 0)
- ga_concat(&ga, (char_u *)", ");
- ocmember_T *m = &cl->class_obj_members[i];
- ga_concat(&ga, m->ocm_name);
- ga_concat(&ga, (char_u *)": ");
- char_u *tf = NULL;
- ga_concat(&ga, echo_string_core(
- (typval_T *)(obj + 1) + i,
- &tf, numbuf, copyID, echo_style,
- restore_copyID, composite_val));
- vim_free(tf);
+ ok = FAIL;
+ break;
}
- ga_concat(&ga, (char_u *)"}");
+ line_breakcheck();
}
- return ga.ga_data;
+ ga_concat(&ga, (char_u *)"}");
+ }
+ if (ok == FAIL)
+ {
+ vim_free(ga.ga_data);
+ return NULL;
}
+ return (char_u *)ga.ga_data;
}
/*
diff --git a/src/vim9cmds.c b/src/vim9cmds.c
index 694bb33..c7fa60a 100644
--- a/src/vim9cmds.c
+++ b/src/vim9cmds.c
@@ -1639,7 +1639,7 @@ compile_try(char_u *arg, cctx_T *cctx)
* Compile "catch {expr}".
*/
char_u *
-compile_catch(char_u *arg, cctx_T *cctx UNUSED)
+compile_catch(char_u *arg, cctx_T *cctx)
{
scope_T *scope = cctx->ctx_scope;
garray_T *instr = &cctx->ctx_instr;
@@ -1923,7 +1923,7 @@ compile_endtry(char_u *arg, cctx_T *cctx)
* compile "throw {expr}"
*/
char_u *
-compile_throw(char_u *arg, cctx_T *cctx UNUSED)
+compile_throw(char_u *arg, cctx_T *cctx)
{
char_u *p = skipwhite(arg);
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 8e6f6e2..ea305b7 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -522,6 +522,8 @@ use_typecheck(type_T *actual, type_T *expected)
(actual->tt_member == &t_void)
== (expected->tt_member == &t_void))))
return TRUE;
+ if (actual->tt_type == VAR_OBJECT && expected->tt_type == VAR_OBJECT)
+ return TRUE;
if ((actual->tt_type == VAR_LIST || actual->tt_type == VAR_DICT)
&& actual->tt_type == expected->tt_type)
// This takes care of a nested list or dict.
@@ -3315,7 +3317,7 @@ obj_constructor_prologue(ufunc_T *ufunc, cctx_T *cctx)
// the initialization expression type.
m->ocm_type = type;
}
- else if (m->ocm_type->tt_type != type->tt_type)
+ else
{
// The type of the member initialization expression is
// determined at run time. Add a runtime type check.
@@ -3330,6 +3332,15 @@ obj_constructor_prologue(ufunc_T *ufunc, cctx_T *cctx)
else
push_default_value(cctx, m->ocm_type->tt_type, FALSE, NULL);
+ if ((m->ocm_type->tt_type == VAR_DICT
+ || m->ocm_type->tt_type == VAR_LIST)
+ && m->ocm_type->tt_member != NULL
+ && m->ocm_type->tt_member != &t_any
+ && m->ocm_type->tt_member != &t_unknown)
+ // Set the type in the list or dict, so that it can be checked,
+ // also in legacy script.
+ generate_SETTYPE(cctx, m->ocm_type);
+
generate_STORE_THIS(cctx, i);
}
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 3a3960a..f523e27 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -2254,26 +2254,35 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
{
// Need to get the member index now that the class is known.
object_T *obj = tv_dest->vval.v_object;
- class_T *cl = obj->obj_class;
- char_u *member = tv_idx->vval.v_string;
-
- int m_idx;
- ocmember_T *m = object_member_lookup(cl, member, 0, &m_idx);
- if (m != NULL)
+ if (obj == NULL)
{
- if (*member == '_')
- {
- emsg_var_cl_define(e_cannot_access_protected_variable_str,
- m->ocm_name, 0, cl);
- status = FAIL;
- }
-
- lidx = m_idx;
+ emsg(_(e_using_null_object));
+ status = FAIL;
}
else
{
- member_not_found_msg(cl, VAR_OBJECT, member, 0);
- status = FAIL;
+ class_T *cl = obj->obj_class;
+ char_u *member = tv_idx->vval.v_string;
+
+ int m_idx;
+ ocmember_T *m = object_member_lookup(cl, member, 0, &m_idx);
+ if (m != NULL)
+ {
+ if (*member == '_')
+ {
+ emsg_var_cl_define(
+ e_cannot_access_protected_variable_str,
+ m->ocm_name, 0, cl);
+ status = FAIL;
+ }
+
+ lidx = m_idx;
+ }
+ else
+ {
+ member_not_found_msg(cl, VAR_OBJECT, member, 0);
+ status = FAIL;
+ }
}
}
else if ((dest_type == VAR_LIST || dest_type == VAR_OBJECT)
@@ -3567,7 +3576,10 @@ exec_instructions(ectx_T *ectx)
p = tv_get_string_buf(tv, buf);
}
else
+ {
+ SOURCING_LNUM = iptr->isn_lnum;
p = tv_stringify(tv, buf);
+ }
len = (int)STRLEN(p);
if (GA_GROW_FAILS(&ga, len + 2))
@@ -4380,15 +4392,31 @@ exec_instructions(ectx_T *ectx)
object_required_error(tv);
goto on_error;
}
+
object_T *obj = tv->vval.v_object;
- class_T *cl = obj->obj_class;
+ if (obj == NULL)
+ {
+ emsg(_(e_using_null_object));
+ goto on_error;
+ }
- // convert the interface index to the object index
- int idx = object_index_from_itf_index(mfunc->cmf_itf,
- TRUE, mfunc->cmf_idx, cl);
+ ufunc_T *ufunc;
+ if (mfunc->cmf_is_super)
+ // Doing "super.Func", use the specific ufunc.
+ ufunc = mfunc->cmf_itf->class_obj_methods[
+ mfunc->cmf_idx];
+ else
+ {
+ class_T *cl = obj->obj_class;
- if (call_ufunc(cl->class_obj_methods[idx], NULL,
- mfunc->cmf_argcount, ectx, NULL, NULL) == FAIL)
+ // convert the interface index to the object index
+ int idx = object_index_from_itf_index(mfunc->cmf_itf,
+ TRUE, mfunc->cmf_idx, cl);
+ ufunc = cl->class_obj_methods[idx];
+ }
+
+ if (call_ufunc(ufunc, NULL, mfunc->cmf_argcount, ectx,
+ NULL, NULL) == FAIL)
goto on_error;
}
break;
@@ -4536,12 +4564,21 @@ exec_instructions(ectx_T *ectx)
tv = STACK_TV_BOT(-1);
if (tv->v_type != VAR_OBJECT)
{
+ SOURCING_LNUM = iptr->isn_lnum;
object_required_error(tv);
vim_free(pt);
goto on_error;
}
object_T *obj = tv->vval.v_object;
+ if (obj == NULL)
+ {
+ SOURCING_LNUM = iptr->isn_lnum;
+ emsg(_(e_using_null_object));
+ vim_free(pt);
+ goto on_error;
+ }
+
cl = obj->obj_class;
// drop the value from the stack
clear_tv(tv);
diff --git a/src/vim9expr.c b/src/vim9expr.c
index 8c412b8..cfdea7b 100644
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -349,6 +349,11 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
else
{
// type->tt_type == VAR_OBJECT: method call
+ // When compiling Func and doing "super.SomeFunc()", must be in the
+ // class context that defines Func.
+ if (is_super)
+ cl = cctx->ctx_ufunc->uf_defclass;
+
function_count = cl->class_obj_method_count;
child_count = cl->class_obj_method_count_child;
functions = cl->class_obj_methods;
@@ -419,13 +424,13 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
return generate_PCALL(cctx, argcount, name, ocm->ocm_type, TRUE);
if (type->tt_type == VAR_OBJECT
&& (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED)))
- return generate_CALL(cctx, ufunc, cl, fi, argcount);
- return generate_CALL(cctx, ufunc, NULL, 0, argcount);
+ return generate_CALL(cctx, ufunc, cl, fi, argcount, is_super);
+ return generate_CALL(cctx, ufunc, NULL, 0, argcount, FALSE);
}
if (type->tt_type == VAR_OBJECT)
{
- ocmember_T *m = object_member_lookup(cl, name, len, &m_idx);
+ ocmember_T *m = object_member_lookup(cl, name, len, &m_idx);
if (m_idx >= 0)
{
if (*name == '_' && !inside_class(cctx, cl))
@@ -1035,7 +1040,7 @@ compile_builtin_method_call(cctx_T *cctx, class_builtin_T builtin_method)
ufunc_T *uf = class_get_builtin_method(type->tt_class, builtin_method,
&method_idx);
if (uf != NULL)
- res = generate_CALL(cctx, uf, type->tt_class, method_idx, 0);
+ res = generate_CALL(cctx, uf, type->tt_class, method_idx, 0, FALSE);
}
return res;
@@ -1238,7 +1243,7 @@ compile_call(
{
if (!func_is_global(ufunc))
{
- res = generate_CALL(cctx, ufunc, NULL, 0, argcount);
+ res = generate_CALL(cctx, ufunc, NULL, 0, argcount, FALSE);
goto theend;
}
if (!has_g_namespace
@@ -1257,7 +1262,7 @@ compile_call(
if (cctx->ctx_ufunc->uf_defclass == cl)
{
res = generate_CALL(cctx, cl->class_class_functions[mi], NULL,
- 0, argcount);
+ 0, argcount, FALSE);
}
else
{
@@ -1285,7 +1290,7 @@ compile_call(
// If we can find a global function by name generate the right call.
if (ufunc != NULL)
{
- res = generate_CALL(cctx, ufunc, NULL, 0, argcount);
+ res = generate_CALL(cctx, ufunc, NULL, 0, argcount, FALSE);
goto theend;
}
@@ -2836,12 +2841,13 @@ compile_expr8(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
type_T *actual;
where_T where = WHERE_INIT;
+ where.wt_kind = WT_CAST;
generate_ppconst(cctx, ppconst);
actual = get_type_on_stack(cctx, 0);
if (check_type_maybe(want_type, actual, FALSE, where) != OK)
{
- if (need_type(actual, want_type, FALSE,
- -1, 0, cctx, FALSE, FALSE) == FAIL)
+ if (need_type_where(actual, want_type, FALSE, -1, where, cctx, FALSE, FALSE)
+ == FAIL)
return FAIL;
}
}
diff --git a/src/vim9instr.c b/src/vim9instr.c
index ad8beb1..4368e3c 100644
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -1805,6 +1805,8 @@ generate_BLOBAPPEND(cctx_T *cctx)
* Generate an ISN_DCALL, ISN_UCALL or ISN_METHODCALL instruction.
* When calling a method on an object, of which we know the interface only,
* then "cl" is the interface and "mi" the method index on the interface.
+ * save is_super in the "isn->isn_arg"; it flags execution to use mfunc
+ * directly to determine ufunc.
* Return FAIL if the number of arguments is wrong.
*/
int
@@ -1813,7 +1815,8 @@ generate_CALL(
ufunc_T *ufunc,
class_T *cl,
int mi,
- int pushed_argcount)
+ int pushed_argcount,
+ int is_super)
{
isn_T *isn;
int regular_args = ufunc->uf_args.ga_len;
@@ -1898,6 +1901,7 @@ generate_CALL(
++cl->class_refcount;
isn->isn_arg.mfunc->cmf_idx = mi;
isn->isn_arg.mfunc->cmf_argcount = argcount;
+ isn->isn_arg.mfunc->cmf_is_super = is_super;
}
else if (isn->isn_type == ISN_DCALL)
{
diff --git a/src/vim9type.c b/src/vim9type.c
index ffdf7fa..1f044d3 100644
--- a/src/vim9type.c
+++ b/src/vim9type.c
@@ -934,6 +934,7 @@ type_mismatch_where(type_T *expected, type_T *actual, where_T where)
semsg(_(e_argument_nr_type_mismatch_expected_str_but_got_str_in_str),
where.wt_index, typename1, typename2, where.wt_func_name);
break;
+ case WT_CAST:
case WT_UNKNOWN:
if (where.wt_func_name == NULL)
semsg(_(e_type_mismatch_expected_str_but_got_str),
@@ -1090,7 +1091,15 @@ check_type_maybe(
ret = FAIL;
}
else if (!class_instance_of(actual->tt_class, expected->tt_class))
- ret = FAIL;
+ {
+ // Check if this is an up-cast, if so we'll have to check the type at
+ // runtime.
+ if (where.wt_kind == WT_CAST &&
+ class_instance_of(expected->tt_class, actual->tt_class))
+ ret = MAYBE;
+ else
+ ret = FAIL;
+ }
}
if (ret == FAIL && give_msg)
@@ -2129,12 +2138,13 @@ check_type_is_value(type_T *type)
switch (type->tt_type)
{
case VAR_CLASS:
- if (IS_ENUM(type->tt_class))
+ if (type->tt_class != NULL && 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);
+ type->tt_class == NULL ? (char_u *)""
+ : type->tt_class->class_name);
return FAIL;
case VAR_TYPEALIAS:
diff --git a/src/viminfo.c b/src/viminfo.c
index 540422c..11a2946 100644
--- a/src/viminfo.c
+++ b/src/viminfo.c
@@ -251,7 +251,7 @@ barline_writestring(FILE *fd, char_u *s, int remaining_start)
viminfo_readstring(
vir_T *virp,
int off, // offset for virp->vir_line
- int convert UNUSED) // convert the string
+ int convert) // convert the string
{
char_u *retval = NULL;
char_u *s, *d;
diff --git a/src/window.c b/src/window.c
index 7322905..b2c90c7 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1708,7 +1708,7 @@ win_count(void)
int
make_windows(
int count,
- int vertical UNUSED) // split windows vertically if TRUE
+ int vertical) // split windows vertically if TRUE
{
int maxcount;
int todo;
@@ -2511,7 +2511,7 @@ close_windows(
for (wp = firstwin; wp != NULL && !ONE_WINDOW; )
{
if (wp->w_buffer == buf && (!keep_curwin || wp != curwin)
- && !(wp->w_closing || wp->w_buffer->b_locked > 0))
+ && !(win_locked(wp) || wp->w_buffer->b_locked > 0))
{
if (win_close(wp, FALSE) == FAIL)
// If closing the window fails give up, to avoid looping
@@ -2532,7 +2532,7 @@ close_windows(
if (tp != curtab)
FOR_ALL_WINDOWS_IN_TAB(tp, wp)
if (wp->w_buffer == buf
- && !(wp->w_closing || wp->w_buffer->b_locked > 0))
+ && !(win_locked(wp) || wp->w_buffer->b_locked > 0))
{
win_close_othertab(wp, FALSE, tp);
@@ -2654,10 +2654,10 @@ win_close_buffer(win_T *win, int action, int abort_if_last)
bufref_T bufref;
set_bufref(&bufref, curbuf);
- win->w_closing = TRUE;
+ win->w_locked = TRUE;
close_buffer(win, win->w_buffer, action, abort_if_last, TRUE);
if (win_valid_any_tab(win))
- win->w_closing = FALSE;
+ win->w_locked = FALSE;
// Make sure curbuf is valid. It can become invalid if 'bufhidden' is
// "wipe".
if (!bufref_valid(&bufref))
@@ -2705,7 +2705,7 @@ win_close(win_T *win, int free_buf)
if (window_layout_locked(CMD_close))
return FAIL;
- if (win->w_closing || (win->w_buffer != NULL
+ if (win_locked(win) || (win->w_buffer != NULL
&& win->w_buffer->b_locked > 0))
return FAIL; // window is already being closed
if (win_unlisted(win))
@@ -2754,19 +2754,19 @@ win_close(win_T *win, int free_buf)
other_buffer = TRUE;
if (!win_valid(win))
return FAIL;
- win->w_closing = TRUE;
+ win->w_locked = TRUE;
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
if (!win_valid(win))
return FAIL;
- win->w_closing = FALSE;
+ win->w_locked = FALSE;
if (last_window())
return FAIL;
}
- win->w_closing = TRUE;
+ win->w_locked = TRUE;
apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
if (!win_valid(win))
return FAIL;
- win->w_closing = FALSE;
+ win->w_locked = FALSE;
if (last_window())
return FAIL;
#ifdef FEAT_EVAL
@@ -3346,7 +3346,7 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
// Get here with win->w_buffer == NULL when win_close() detects the tab
// page changed.
- if (win->w_closing || (win->w_buffer != NULL
+ if (win_locked(win) || (win->w_buffer != NULL
&& win->w_buffer->b_locked > 0))
return; // window is already being closed
@@ -3486,7 +3486,7 @@ win_free_all(void)
win_T *
winframe_remove(
win_T *win,
- int *dirp UNUSED, // set to 'v' or 'h' for direction if 'ea'
+ int *dirp, // set to 'v' or 'h' for direction if 'ea'
tabpage_T *tp, // tab page "win" is in, NULL for current
frame_T **unflat_altfr) // if not NULL, set to pointer of frame that got
// the space, and it is not flattened
@@ -3782,15 +3782,24 @@ win_altframe(
static tabpage_T *
alt_tabpage(void)
{
- tabpage_T *tp;
+ tabpage_T *tp = NULL;
+ int forward;
- // Use the next tab page if possible.
- if (curtab->tp_next != NULL)
- return curtab->tp_next;
+ // Use the last accessed tab page, if possible.
+ if ((tcl_flags & TCL_USELAST) && valid_tabpage(lastused_tabpage))
+ return lastused_tabpage;
+
+ // Use the next tab page, if possible.
+ forward = curtab->tp_next != NULL &&
+ ((tcl_flags & TCL_LEFT) == 0 || curtab == first_tabpage);
+
+ if (forward)
+ tp = curtab->tp_next;
+ else
+ // Use the previous tab page.
+ for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next)
+ ;
- // Find the last but one tab page.
- for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next)
- ;
return tp;
}
@@ -4598,6 +4607,11 @@ free_tabpage(tabpage_T *tp)
* It will edit the current buffer, like after ":split".
* When "after" is 0 put it just after the current Tab page.
* Otherwise put it just before tab page "after".
+ *
+ * Does not trigger WinNewPre, since the window structures
+ * are not completly setup yet and could cause dereferencing
+ * NULL pointers
+ *
* Return FAIL or OK.
*/
int
@@ -4631,8 +4645,6 @@ win_new_tabpage(int after)
newtp->tp_localdir = (tp->tp_localdir == NULL)
? NULL : vim_strsave(tp->tp_localdir);
- trigger_winnewpre();
-
// Create a new empty window.
if (win_alloc_firstwin(tp->tp_curwin) == OK)
{
@@ -4846,8 +4858,8 @@ tabpage_index(tabpage_T *ftp)
*/
static int
leave_tabpage(
- buf_T *new_curbuf UNUSED, // what is going to be the new curbuf,
- // NULL if unknown
+ buf_T *new_curbuf, // what is going to be the new curbuf,
+ // NULL if unknown
int trigger_leave_autocmds)
{
tabpage_T *tp = curtab;
@@ -4899,7 +4911,7 @@ leave_tabpage(
static void
enter_tabpage(
tabpage_T *tp,
- buf_T *old_curbuf UNUSED,
+ buf_T *old_curbuf,
int trigger_enter_autocmds,
int trigger_leave_autocmds)
{
@@ -5828,10 +5840,7 @@ win_free(
win_free_lsize(wp);
for (i = 0; i < wp->w_tagstacklen; ++i)
- {
- vim_free(wp->w_tagstack[i].tagname);
- vim_free(wp->w_tagstack[i].user_data);
- }
+ tagstack_clear_entry(&wp->w_tagstack[i]);
vim_free(wp->w_localdir);
vim_free(wp->w_prevdir);
@@ -7846,7 +7855,7 @@ get_win_number(win_T *wp, win_T *first_win)
}
int
-get_tab_number(tabpage_T *tp UNUSED)
+get_tab_number(tabpage_T *tp)
{
int i = 1;
tabpage_T *t;
@@ -7991,3 +8000,12 @@ get_last_winid(void)
{
return last_win_id;
}
+
+/*
+ * Don't let autocommands close the given window
+ */
+ int
+win_locked(win_T *wp)
+{
+ return wp->w_locked;
+}
diff --git a/src/xxd/Make_ming.mak b/src/xxd/Make_ming.mak
index 2d32261..e621e67 100644
--- a/src/xxd/Make_ming.mak
+++ b/src/xxd/Make_ming.mak
@@ -16,7 +16,7 @@ CC = gcc
CFLAGS = -O2 -Wall -DWIN32 $(DEFINES)
ifneq (sh.exe, $(SHELL))
-DEL = rm
+DEL = rm -f
else
DEL = del
endif
diff --git a/src/xxd/Make_mvc.mak b/src/xxd/Make_mvc.mak
index 0133d73..2361ab3 100644
--- a/src/xxd/Make_mvc.mak
+++ b/src/xxd/Make_mvc.mak
@@ -9,7 +9,7 @@ SUBSYSTEM = $(SUBSYSTEM),$(SUBSYSTEM_VER)
xxd: xxd.exe
xxd.exe: xxd.c
- cl /nologo -DWIN32 xxd.c -link -subsystem:$(SUBSYSTEM)
+ cl /nologo /source-charset:utf-8 -DWIN32 xxd.c -link -subsystem:$(SUBSYSTEM)
# This was for an older compiler
# cl /nologo -DWIN32 xxd.c /link setargv.obj