From 5bc13453b2dd8067597793e32c4f94aa3031054a Mon Sep 17 00:00:00 2001 From: "K.Takata" Date: Fri, 9 Sep 2022 10:52:47 +0100 Subject: [PATCH 01/28] patch 9.0.0421: MS-Windows makefiles are inconsistently named Problem: MS-Windows makefiles are inconsistently named. Solution: Use consistent names. (Ken Takata, closes #11088) --- .appveyor.yml | 6 +- .github/workflows/ci.yml | 6 +- Filelist | 11 ++- src/GvimExt/Make_mvc.mak | 98 +++++++++++++++++++++++++ src/GvimExt/Makefile | 100 +------------------------ src/Make_cyg_ming.mak | 4 +- src/Make_mvc.mak | 30 ++++---- src/tee/Make_ming.mak | 21 ++++++ src/tee/Makefile | 23 +----- src/testdir/Make_dos.mak | 154 +-------------------------------------- src/testdir/Make_mvc.mak | 152 ++++++++++++++++++++++++++++++++++++++ src/testdir/README.txt | 2 +- src/version.c | 2 + 13 files changed, 310 insertions(+), 299 deletions(-) create mode 100644 src/GvimExt/Make_mvc.mak create mode 100644 src/tee/Make_ming.mak create mode 100644 src/testdir/Make_mvc.mak diff --git a/.appveyor.yml b/.appveyor.yml index 80f8e38f0b..866725f0b1 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -26,9 +26,9 @@ test_script: - cd src/testdir # Testing with MSVC gvim - path C:\Python35-x64;%PATH% - - nmake -f Make_dos.mak VIMPROG=..\gvim - - nmake -f Make_dos.mak clean + - nmake -f Make_mvc.mak VIMPROG=..\gvim + - nmake -f Make_mvc.mak clean # Testing with MSVC console version - - nmake -f Make_dos.mak VIMPROG=..\vim + - nmake -f Make_mvc.mak VIMPROG=..\vim # vim: sw=2 sts=2 et ts=8 sr diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4f234a41a..05e675de81 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -563,11 +563,11 @@ jobs: call "%VCVARSALL%" ${{ matrix.vcarch }} echo %COL_GREEN%Start testing Vim in background.%COL_RESET% - start cmd /c "cd src2\testdir & nmake -nologo -f Make_dos.mak VIMPROG=..\..\src\vim > nul & echo done>done.txt" + start cmd /c "cd src2\testdir & nmake -nologo -f Make_mvc.mak VIMPROG=..\..\src\vim > nul & echo done>done.txt" echo %COL_GREEN%Test gVim:%COL_RESET% cd src\testdir - nmake -nologo -f Make_dos.mak VIMPROG=..\gvim || exit 1 + nmake -nologo -f Make_mvc.mak VIMPROG=..\gvim || exit 1 - name: Show the result of testing Vim shell: cmd @@ -590,7 +590,7 @@ jobs: echo %COL_GREEN%The result of testing Vim:%COL_RESET% cd src2\testdir if exist messages type messages - nmake -nologo -f Make_dos.mak report VIMPROG=..\..\src\vim || exit 1 + nmake -nologo -f Make_mvc.mak report VIMPROG=..\..\src\vim || exit 1 if "%timeout%"=="1" ( echo %COL_RED%Timed out.%COL_RESET% diff --git a/Filelist b/Filelist index d601a7ff99..519964b61d 100644 --- a/Filelist +++ b/Filelist @@ -171,7 +171,6 @@ SRC_ALL = \ src/viminfo.c \ src/winclip.c \ src/window.c \ - src/tee/tee.c \ src/xxd/xxd.c \ src/testdir/gen_opt_test.vim \ src/testdir/README.txt \ @@ -487,7 +486,6 @@ SRC_UNIX = \ src/vimtutor \ src/gvimtutor \ src/which.sh \ - src/tee/Makefile \ src/xxd/Makefile \ # source files for both DOS and Unix @@ -516,7 +514,7 @@ SRC_DOS_UNIX = \ src/proto/if_tcl.pro \ src/typemap \ -# source files for DOS (also in the extra archive) +# source files for MS-Windows (also in the extra archive) SRC_DOS = \ src/GvimExt/*.mak \ src/GvimExt/GvimExt.reg \ @@ -570,6 +568,7 @@ SRC_DOS = \ src/proto/os_win32.pro \ src/proto/os_mswin.pro \ src/testdir/Make_dos.mak \ + src/testdir/Make_mvc.mak \ src/testdir/Make_ming.mak \ src/testdir/dos.vim \ src/uninstall.c \ @@ -578,7 +577,10 @@ SRC_DOS = \ src/vimrun.c \ src/xpm_w32.c \ src/xpm_w32.h \ + src/tee/Make_ming.mak \ src/tee/Make_mvc.mak \ + src/tee/Makefile \ + src/tee/tee.c \ src/xxd/Make_ming.mak \ src/xxd/Make_mvc.mak \ nsis/gvim.nsi \ @@ -945,9 +947,6 @@ EXTRA = \ README_extra.txt \ src/VisVim/VisVim.dll \ runtime/vimlogo.xpm \ - src/tee/Makefile \ - src/tee/Make_mvc.mak \ - src/tee/tee.c \ # files in READMEdir that are included from the top dir IN_README_DIR = \ diff --git a/src/GvimExt/Make_mvc.mak b/src/GvimExt/Make_mvc.mak new file mode 100644 index 0000000000..4b83f52dd5 --- /dev/null +++ b/src/GvimExt/Make_mvc.mak @@ -0,0 +1,98 @@ +# Makefile for GvimExt, using MSVC +# Options: +# DEBUG=yes Build debug version (for VC7 and maybe later) +# CPUARG= /arch:IA32/AVX/etc, call from main makefile to set +# automatically from CPUNR +# + +TARGETOS = WINNT + +!ifndef APPVER +APPVER = 5.01 +!endif +!ifndef WINVER +WINVER = 0x0501 +!endif + +!if "$(DEBUG)" != "yes" +NODEBUG = 1 +!endif + +!ifdef PROCESSOR_ARCHITECTURE +# On Windows NT +! ifndef CPU +CPU = i386 +! if !defined(PLATFORM) && defined(TARGET_CPU) +PLATFORM = $(TARGET_CPU) +! endif +! ifdef PLATFORM +! if ("$(PLATFORM)" == "x64") || ("$(PLATFORM)" == "X64") +CPU = AMD64 +! elseif ("$(PLATFORM)" == "arm64") || ("$(PLATFORM)" == "ARM64") +CPU = ARM64 +! elseif ("$(PLATFORM)" != "x86") && ("$(PLATFORM)" != "X86") +! error *** ERROR Unknown target platform "$(PLATFORM)". Make aborted. +! endif +! endif +! endif +!else +CPU = i386 +!endif + +!ifdef SDK_INCLUDE_DIR +!include $(SDK_INCLUDE_DIR)\Win32.mak +!elseif "$(USE_WIN32MAK)"=="yes" +!include +!else +cc = cl +link = link +rc = rc +cflags = -nologo -c +lflags = -incremental:no -nologo +rcflags = /r +olelibsdll = ole32.lib uuid.lib oleaut32.lib user32.lib gdi32.lib advapi32.lib +!endif + +# include CPUARG +cflags = $(cflags) $(CPUARG) + +# set WINVER and _WIN32_WINNT +cflags = $(cflags) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) + +!if "$(CL)" == "/D_USING_V110_SDK71_" +rcflags = $(rcflags) /D_USING_V110_SDK71_ +!endif + +SUBSYSTEM = console +!if "$(SUBSYSTEM_VER)" != "" +SUBSYSTEM = $(SUBSYSTEM),$(SUBSYSTEM_VER) +!endif + +!if "$(CPU)" == "AMD64" || "$(CPU)" == "ARM64" +OFFSET = 0x11C000000 +!else +OFFSET = 0x1C000000 +!endif + +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 + +.cpp.obj: + $(cc) $(cflags) -DFEAT_GETTEXT $(cvarsmt) $*.cpp + +gvimext.res: gvimext.rc + $(rc) /nologo $(rcflags) $(rcvars) gvimext.rc + +clean: + - if exist gvimext.dll del gvimext.dll + - if exist gvimext.lib del gvimext.lib + - 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/GvimExt/Makefile b/src/GvimExt/Makefile index 4b83f52dd5..18b91ece29 100644 --- a/src/GvimExt/Makefile +++ b/src/GvimExt/Makefile @@ -1,98 +1,4 @@ -# Makefile for GvimExt, using MSVC -# Options: -# DEBUG=yes Build debug version (for VC7 and maybe later) -# CPUARG= /arch:IA32/AVX/etc, call from main makefile to set -# automatically from CPUNR -# +!message This makefile is deprecated. Use Make_mvc.mak instead. +!message -TARGETOS = WINNT - -!ifndef APPVER -APPVER = 5.01 -!endif -!ifndef WINVER -WINVER = 0x0501 -!endif - -!if "$(DEBUG)" != "yes" -NODEBUG = 1 -!endif - -!ifdef PROCESSOR_ARCHITECTURE -# On Windows NT -! ifndef CPU -CPU = i386 -! if !defined(PLATFORM) && defined(TARGET_CPU) -PLATFORM = $(TARGET_CPU) -! endif -! ifdef PLATFORM -! if ("$(PLATFORM)" == "x64") || ("$(PLATFORM)" == "X64") -CPU = AMD64 -! elseif ("$(PLATFORM)" == "arm64") || ("$(PLATFORM)" == "ARM64") -CPU = ARM64 -! elseif ("$(PLATFORM)" != "x86") && ("$(PLATFORM)" != "X86") -! error *** ERROR Unknown target platform "$(PLATFORM)". Make aborted. -! endif -! endif -! endif -!else -CPU = i386 -!endif - -!ifdef SDK_INCLUDE_DIR -!include $(SDK_INCLUDE_DIR)\Win32.mak -!elseif "$(USE_WIN32MAK)"=="yes" -!include -!else -cc = cl -link = link -rc = rc -cflags = -nologo -c -lflags = -incremental:no -nologo -rcflags = /r -olelibsdll = ole32.lib uuid.lib oleaut32.lib user32.lib gdi32.lib advapi32.lib -!endif - -# include CPUARG -cflags = $(cflags) $(CPUARG) - -# set WINVER and _WIN32_WINNT -cflags = $(cflags) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) - -!if "$(CL)" == "/D_USING_V110_SDK71_" -rcflags = $(rcflags) /D_USING_V110_SDK71_ -!endif - -SUBSYSTEM = console -!if "$(SUBSYSTEM_VER)" != "" -SUBSYSTEM = $(SUBSYSTEM),$(SUBSYSTEM_VER) -!endif - -!if "$(CPU)" == "AMD64" || "$(CPU)" == "ARM64" -OFFSET = 0x11C000000 -!else -OFFSET = 0x1C000000 -!endif - -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 - -.cpp.obj: - $(cc) $(cflags) -DFEAT_GETTEXT $(cvarsmt) $*.cpp - -gvimext.res: gvimext.rc - $(rc) /nologo $(rcflags) $(rcvars) gvimext.rc - -clean: - - if exist gvimext.dll del gvimext.dll - - if exist gvimext.lib del gvimext.lib - - 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 +!include Make_mvc.mak diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index 9c004fa8d2..fe393fbeda 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -1149,7 +1149,7 @@ xxd/xxd.exe: xxd/xxd.c $(MAKE) -C xxd -f Make_ming.mak CC='$(CC)' tee/tee.exe: tee/tee.c - $(MAKE) -C tee CC='$(CC)' + $(MAKE) -C tee -f Make_ming.mak CC='$(CC)' GvimExt/gvimext.dll: GvimExt/gvimext.cpp GvimExt/gvimext.rc GvimExt/gvimext.h $(MAKE) -C GvimExt -f Make_ming.mak CROSS=$(CROSS) CROSS_COMPILE=$(CROSS_COMPILE) CXX='$(CXX)' STATIC_STDCPLUS=$(STATIC_STDCPLUS) @@ -1176,7 +1176,7 @@ ifdef MZSCHEME endif $(MAKE) -C GvimExt -f Make_ming.mak clean $(MAKE) -C xxd -f Make_ming.mak clean - $(MAKE) -C tee clean + $(MAKE) -C tee -f Make_ming.mak clean # Run vim script to generate the Ex command lookup table. # This only needs to be run when a command name has been added or changed. diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index 52282cb1e7..7619fdbf00 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -1400,7 +1400,7 @@ tee/tee.exe: tee/tee.c GvimExt/gvimext.dll: GvimExt/gvimext.cpp GvimExt/gvimext.rc GvimExt/gvimext.h cd GvimExt - $(MAKE) /NOLOGO -f Makefile $(MAKEFLAGS_GVIMEXT) + $(MAKE) /NOLOGO -f Make_mvc.mak $(MAKEFLAGS_GVIMEXT) cd .. @@ -1441,7 +1441,7 @@ clean: testclean $(MAKE) /NOLOGO -f Make_mvc.mak clean cd .. cd GvimExt - $(MAKE) /NOLOGO -f Makefile clean + $(MAKE) /NOLOGO -f Make_mvc.mak clean cd .. # Run vim script to generate the Ex command lookup table. @@ -1463,27 +1463,27 @@ nvcmdidxs: nv_cmds.h test: cd testdir - $(MAKE) /NOLOGO -f Make_dos.mak + $(MAKE) /NOLOGO -f Make_mvc.mak cd .. testgvim testgui: cd testdir - $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\gvim + $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\gvim cd .. testtiny: cd testdir - $(MAKE) /NOLOGO -f Make_dos.mak tiny + $(MAKE) /NOLOGO -f Make_mvc.mak tiny cd .. testgvimtiny: cd testdir - $(MAKE) /NOLOGO -f Make_dos.mak tiny VIMPROG=..\gvim + $(MAKE) /NOLOGO -f Make_mvc.mak tiny VIMPROG=..\gvim cd .. testclean: cd testdir - $(MAKE) /NOLOGO -f Make_dos.mak clean + $(MAKE) /NOLOGO -f Make_mvc.mak clean cd .. # Run individual OLD style test. @@ -1491,8 +1491,8 @@ testclean: $(SCRIPTS_TINY): cd testdir - if exist $@.out del $@.out - $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) nolog - $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) $@.out + $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\$(VIMTESTTARGET) nolog + $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\$(VIMTESTTARGET) $@.out @ if exist test.log ( type test.log & exit /b 1 ) cd .. @@ -1501,9 +1501,9 @@ $(SCRIPTS_TINY): $(NEW_TESTS): cd testdir - if exist $@.res del $@.res - $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) nolog - $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) $@.res - $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) report + $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\$(VIMTESTTARGET) nolog + $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\$(VIMTESTTARGET) $@.res + $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\$(VIMTESTTARGET) report cd .. # Run Vim9 tests. @@ -1511,9 +1511,9 @@ $(NEW_TESTS): test_vim9: cd testdir -del test_vim9_*.res - $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) nolog - $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) $(TEST_VIM9_RES) - $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) report + $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\$(VIMTESTTARGET) nolog + $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\$(VIMTESTTARGET) $(TEST_VIM9_RES) + $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\$(VIMTESTTARGET) report cd .. ########################################################################### diff --git a/src/tee/Make_ming.mak b/src/tee/Make_ming.mak new file mode 100644 index 0000000000..f6e91358fb --- /dev/null +++ b/src/tee/Make_ming.mak @@ -0,0 +1,21 @@ +# A very (if not the most) simplistic Makefile for MS-Windows and OS/2 + +CC=gcc +CFLAGS=-O2 -fno-strength-reduce + +ifneq (sh.exe, $(SHELL)) +DEL = rm -f +else +DEL = del +endif + +tee.exe: tee.o + $(CC) $(CFLAGS) -s -o $@ $< + +tee.o: tee.c + $(CC) $(CFLAGS) -c $< + +clean: + - $(DEL) tee.o + - $(DEL) tee.exe + diff --git a/src/tee/Makefile b/src/tee/Makefile index f6e91358fb..fe7777931d 100644 --- a/src/tee/Makefile +++ b/src/tee/Makefile @@ -1,21 +1,2 @@ -# A very (if not the most) simplistic Makefile for MS-Windows and OS/2 - -CC=gcc -CFLAGS=-O2 -fno-strength-reduce - -ifneq (sh.exe, $(SHELL)) -DEL = rm -f -else -DEL = del -endif - -tee.exe: tee.o - $(CC) $(CFLAGS) -s -o $@ $< - -tee.o: tee.c - $(CC) $(CFLAGS) -c $< - -clean: - - $(DEL) tee.o - - $(DEL) tee.exe - +$(warning This makefile is deprecated. Use Make_ming.mak instead.) +include Make_ming.mak diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak index 9d1dc4ecc2..7f9d6bfb1c 100644 --- a/src/testdir/Make_dos.mak +++ b/src/testdir/Make_dos.mak @@ -1,152 +1,4 @@ -# -# Makefile to run all tests for Vim, on Dos-like machines. -# -# Requires a set of Unix tools: echo, diff, etc. +!message Make_dos.mak is deprecated. Use Make_mvc.mak instead. +!message -VIMPROG = ..\\vim - -default: nongui - -!include Make_all.mak - -# Explicit dependencies. -test_options.res test_alot.res: opt_test.vim - -TEST_OUTFILES = $(SCRIPTS_TINY_OUT) -DOSTMP = dostmp -DOSTMP_OUTFILES = $(TEST_OUTFILES:test=dostmp\test) -DOSTMP_INFILES = $(DOSTMP_OUTFILES:.out=.in) - -.SUFFIXES: .in .out .res .vim - -# Add --gui-dialog-file to avoid getting stuck in a dialog. -COMMON_ARGS = $(NO_INITS) --gui-dialog-file guidialog - -nongui: nolog tinytests newtests report - -gui: nolog tinytests newtests report - -tiny: nolog tinytests report - -benchmark: $(SCRIPTS_BENCH) - -report: - @rem without the +eval feature test_result.log is a copy of test.log - @if exist test.log ( copy /y test.log test_result.log > nul ) \ - else ( echo No failures reported > test_result.log ) - $(VIMPROG) -u NONE $(COMMON_ARGS) -S summarize.vim messages - @echo. - @echo Test results: - @cmd /c type test_result.log - @if exist test.log ( echo TEST FAILURE & exit /b 1 ) \ - else ( echo ALL DONE ) - - -# Execute an individual new style test, e.g.: -# nmake -f Make_dos.mak test_largefile -$(NEW_TESTS): - -if exist $@.res del $@.res - -if exist test.log del test.log - -if exist messages del messages - @$(MAKE) -nologo -f Make_dos.mak $@.res VIMPROG=$(VIMPROG) - @type messages - @if exist test.log exit 1 - - -# Delete files that may interfere with running tests. This includes some files -# that may result from working on the tests, not only from running them. -clean: - -if exist *.out del *.out - -if exist *.failed del *.failed - -if exist *.res del *.res - -if exist $(DOSTMP) rd /s /q $(DOSTMP) - -if exist test.in del test.in - -if exist test.ok del test.ok - -if exist Xdir1 rd /s /q Xdir1 - -if exist Xfind rd /s /q Xfind - -if exist XfakeHOME rd /s /q XfakeHOME - -if exist X* del X* - -for /d %i in (X*) do @rd /s/q %i - -if exist viminfo del viminfo - -if exist test.log del test.log - -if exist test_result.log del test_result.log - -if exist messages del messages - -if exist benchmark.out del benchmark.out - -if exist opt_test.vim del opt_test.vim - -if exist guidialog del guidialog - -if exist guidialogfile del guidialogfile - -nolog: - -if exist test.log del test.log - -if exist test_result.log del test_result.log - -if exist messages del messages - - -# Tiny tests. Works even without the +eval feature. -tinytests: $(SCRIPTS_TINY_OUT) - -# Copy the input files to dostmp, changing the fileformat to dos. -$(DOSTMP_INFILES): $(*B).in - if not exist $(DOSTMP)\NUL md $(DOSTMP) - if exist $@ del $@ - $(VIMPROG) -u dos.vim $(COMMON_ARGS) "+set ff=dos|f $@|wq" $(*B).in - -# For each input file dostmp/test99.in run the tests. -# This moves test99.in to test99.in.bak temporarily. -$(TEST_OUTFILES): $(DOSTMP)\$(*B).in - -@if exist test.out DEL test.out - -@if exist $(DOSTMP)\$(*B).out DEL $(DOSTMP)\$(*B).out - move $(*B).in $(*B).in.bak > nul - copy $(DOSTMP)\$(*B).in $(*B).in > nul - copy $(*B).ok test.ok > nul - $(VIMPROG) -u dos.vim $(COMMON_ARGS) -s dotest.in $(*B).in - -@if exist test.out MOVE /y test.out $(DOSTMP)\$(*B).out > nul - -@if exist $(*B).in.bak move /y $(*B).in.bak $(*B).in > nul - -@if exist test.ok del test.ok - -@if exist Xdir1 rd /s /q Xdir1 - -@if exist Xfind rd /s /q Xfind - -@if exist XfakeHOME rd /s /q XfakeHOME - -@del X* - -@if exist viminfo del viminfo - $(VIMPROG) -u dos.vim $(COMMON_ARGS) "+set ff=unix|f test.out|wq" \ - $(DOSTMP)\$(*B).out - @diff test.out $*.ok & if errorlevel 1 \ - ( move /y test.out $*.failed > nul \ - & del $(DOSTMP)\$(*B).out \ - & echo $* FAILED >> test.log ) \ - else ( move /y test.out $*.out > nul ) - - -# New style of tests uses Vim script with assert calls. These are easier -# to write and a lot easier to read and debug. -# Limitation: Only works with the +eval feature. - -newtests: newtestssilent - @if exist messages type messages - -newtestssilent: $(NEW_TESTS_RES) - -.vim.res: - @echo $(VIMPROG) > vimcmd - $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim - @del vimcmd - -test_gui.res: test_gui.vim - @echo $(VIMPROG) > vimcmd - $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim - @del vimcmd - -test_gui_init.res: test_gui_init.vim - @echo $(VIMPROG) > vimcmd - $(VIMPROG) -u gui_preinit.vim -U gui_init.vim $(NO_PLUGINS) -S runtest.vim $*.vim - @del vimcmd - -opt_test.vim: ../optiondefs.h gen_opt_test.vim - $(VIMPROG) -u NONE -S gen_opt_test.vim --noplugin --not-a-term ../optiondefs.h - -test_bench_regexp.res: test_bench_regexp.vim - -if exist benchmark.out del benchmark.out - @echo $(VIMPROG) > vimcmd - $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim - @del vimcmd - @IF EXIST benchmark.out ( type benchmark.out ) +!include Make_mvc.mak diff --git a/src/testdir/Make_mvc.mak b/src/testdir/Make_mvc.mak new file mode 100644 index 0000000000..882c5d082f --- /dev/null +++ b/src/testdir/Make_mvc.mak @@ -0,0 +1,152 @@ +# +# Makefile to run all tests for Vim, on Dos-like machines. +# +# Requires a set of Unix tools: echo, diff, etc. + +VIMPROG = ..\\vim + +default: nongui + +!include Make_all.mak + +# Explicit dependencies. +test_options.res test_alot.res: opt_test.vim + +TEST_OUTFILES = $(SCRIPTS_TINY_OUT) +DOSTMP = dostmp +DOSTMP_OUTFILES = $(TEST_OUTFILES:test=dostmp\test) +DOSTMP_INFILES = $(DOSTMP_OUTFILES:.out=.in) + +.SUFFIXES: .in .out .res .vim + +# Add --gui-dialog-file to avoid getting stuck in a dialog. +COMMON_ARGS = $(NO_INITS) --gui-dialog-file guidialog + +nongui: nolog tinytests newtests report + +gui: nolog tinytests newtests report + +tiny: nolog tinytests report + +benchmark: $(SCRIPTS_BENCH) + +report: + @rem without the +eval feature test_result.log is a copy of test.log + @if exist test.log ( copy /y test.log test_result.log > nul ) \ + else ( echo No failures reported > test_result.log ) + $(VIMPROG) -u NONE $(COMMON_ARGS) -S summarize.vim messages + @echo. + @echo Test results: + @cmd /c type test_result.log + @if exist test.log ( echo TEST FAILURE & exit /b 1 ) \ + else ( echo ALL DONE ) + + +# Execute an individual new style test, e.g.: +# nmake -f Make_mvc.mak test_largefile +$(NEW_TESTS): + -if exist $@.res del $@.res + -if exist test.log del test.log + -if exist messages del messages + @$(MAKE) -nologo -f Make_mvc.mak $@.res VIMPROG=$(VIMPROG) + @type messages + @if exist test.log exit 1 + + +# Delete files that may interfere with running tests. This includes some files +# that may result from working on the tests, not only from running them. +clean: + -if exist *.out del *.out + -if exist *.failed del *.failed + -if exist *.res del *.res + -if exist $(DOSTMP) rd /s /q $(DOSTMP) + -if exist test.in del test.in + -if exist test.ok del test.ok + -if exist Xdir1 rd /s /q Xdir1 + -if exist Xfind rd /s /q Xfind + -if exist XfakeHOME rd /s /q XfakeHOME + -if exist X* del X* + -for /d %i in (X*) do @rd /s/q %i + -if exist viminfo del viminfo + -if exist test.log del test.log + -if exist test_result.log del test_result.log + -if exist messages del messages + -if exist benchmark.out del benchmark.out + -if exist opt_test.vim del opt_test.vim + -if exist guidialog del guidialog + -if exist guidialogfile del guidialogfile + +nolog: + -if exist test.log del test.log + -if exist test_result.log del test_result.log + -if exist messages del messages + + +# Tiny tests. Works even without the +eval feature. +tinytests: $(SCRIPTS_TINY_OUT) + +# Copy the input files to dostmp, changing the fileformat to dos. +$(DOSTMP_INFILES): $(*B).in + if not exist $(DOSTMP)\NUL md $(DOSTMP) + if exist $@ del $@ + $(VIMPROG) -u dos.vim $(COMMON_ARGS) "+set ff=dos|f $@|wq" $(*B).in + +# For each input file dostmp/test99.in run the tests. +# This moves test99.in to test99.in.bak temporarily. +$(TEST_OUTFILES): $(DOSTMP)\$(*B).in + -@if exist test.out DEL test.out + -@if exist $(DOSTMP)\$(*B).out DEL $(DOSTMP)\$(*B).out + move $(*B).in $(*B).in.bak > nul + copy $(DOSTMP)\$(*B).in $(*B).in > nul + copy $(*B).ok test.ok > nul + $(VIMPROG) -u dos.vim $(COMMON_ARGS) -s dotest.in $(*B).in + -@if exist test.out MOVE /y test.out $(DOSTMP)\$(*B).out > nul + -@if exist $(*B).in.bak move /y $(*B).in.bak $(*B).in > nul + -@if exist test.ok del test.ok + -@if exist Xdir1 rd /s /q Xdir1 + -@if exist Xfind rd /s /q Xfind + -@if exist XfakeHOME rd /s /q XfakeHOME + -@del X* + -@if exist viminfo del viminfo + $(VIMPROG) -u dos.vim $(COMMON_ARGS) "+set ff=unix|f test.out|wq" \ + $(DOSTMP)\$(*B).out + @diff test.out $*.ok & if errorlevel 1 \ + ( move /y test.out $*.failed > nul \ + & del $(DOSTMP)\$(*B).out \ + & echo $* FAILED >> test.log ) \ + else ( move /y test.out $*.out > nul ) + + +# New style of tests uses Vim script with assert calls. These are easier +# to write and a lot easier to read and debug. +# Limitation: Only works with the +eval feature. + +newtests: newtestssilent + @if exist messages type messages + +newtestssilent: $(NEW_TESTS_RES) + +.vim.res: + @echo $(VIMPROG) > vimcmd + $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim + @del vimcmd + +test_gui.res: test_gui.vim + @echo $(VIMPROG) > vimcmd + $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim + @del vimcmd + +test_gui_init.res: test_gui_init.vim + @echo $(VIMPROG) > vimcmd + $(VIMPROG) -u gui_preinit.vim -U gui_init.vim $(NO_PLUGINS) -S runtest.vim $*.vim + @del vimcmd + +opt_test.vim: ../optiondefs.h gen_opt_test.vim + $(VIMPROG) -u NONE -S gen_opt_test.vim --noplugin --not-a-term ../optiondefs.h + +test_bench_regexp.res: test_bench_regexp.vim + -if exist benchmark.out del benchmark.out + @echo $(VIMPROG) > vimcmd + $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim + @del vimcmd + @IF EXIST benchmark.out ( type benchmark.out ) diff --git a/src/testdir/README.txt b/src/testdir/README.txt index b8bc52f1e6..f72bdbfb85 100644 --- a/src/testdir/README.txt +++ b/src/testdir/README.txt @@ -106,7 +106,7 @@ tests are successful, then this file will be an empty file. - To run the test on MS-Windows using the MSVC nmake: - > nmake -f Make_dos.mak + > nmake -f Make_mvc.mak - To run the tests with GUI Vim: diff --git a/src/version.c b/src/version.c index cfebf04d75..c232a7b62f 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 421, /**/ 420, /**/ From 0dc2fd307ffc223cf010d1fdea6e3d5c4524d43c Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Fri, 9 Sep 2022 11:27:59 +0100 Subject: [PATCH 02/28] patch 9.0.0422: not enough testing of the :all command Problem: Not enough testing of the :all command. Solution: Add more testing. (Yegappan Lakshmanan, closes #11091) --- src/testdir/test_arglist.vim | 126 +++++++++++++++++++++++++++++++++++ src/version.c | 2 + 2 files changed, 128 insertions(+) diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim index 2a46de06c1..298514ef09 100644 --- a/src/testdir/test_arglist.vim +++ b/src/testdir/test_arglist.vim @@ -610,4 +610,130 @@ func Test_clear_arglist_in_all() au! * endfunc +" Test for the :all command +func Test_all_command() + %argdelete + + " :all command should not close windows with files in the argument list, + " but can rearrange the windows. + args Xargnew1 Xargnew2 + %bw! + edit Xargold1 + split Xargnew1 + let Xargnew1_winid = win_getid() + split Xargold2 + split Xargnew2 + let Xargnew2_winid = win_getid() + split Xargold3 + all + call assert_equal(2, winnr('$')) + call assert_equal([Xargnew1_winid, Xargnew2_winid], + \ [win_getid(1), win_getid(2)]) + call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2')], + \ [winbufnr(1), winbufnr(2)]) + + " :all command should close windows for files which are not in the + " argument list in the current tab page. + %bw! + edit Xargold1 + split Xargold2 + tabedit Xargold3 + split Xargold4 + tabedit Xargold5 + tabfirst + all + call assert_equal(3, tabpagenr('$')) + call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2')], tabpagebuflist(1)) + call assert_equal([bufnr('Xargold4'), bufnr('Xargold3')], tabpagebuflist(2)) + call assert_equal([bufnr('Xargold5')], tabpagebuflist(3)) + + " :tab all command should close windows for files which are not in the + " argument list across all the tab pages. + %bw! + edit Xargold1 + split Xargold2 + tabedit Xargold3 + split Xargold4 + tabedit Xargold5 + tabfirst + args Xargnew1 Xargnew2 + tab all + call assert_equal(2, tabpagenr('$')) + call assert_equal([bufnr('Xargnew1')], tabpagebuflist(1)) + call assert_equal([bufnr('Xargnew2')], tabpagebuflist(2)) + + " If a count is specified, then :all should open only that many windows. + %bw! + args Xargnew1 Xargnew2 Xargnew3 Xargnew4 Xargnew5 + all 3 + call assert_equal(3, winnr('$')) + call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2'), bufnr('Xargnew3')], + \ [winbufnr(1), winbufnr(2), winbufnr(3)]) + + " The :all command should not open more than 'tabpagemax' tab pages. + " If there are more files, then they should be opened in the last tab page. + %bw! + set tabpagemax=3 + tab all + call assert_equal(3, tabpagenr('$')) + call assert_equal([bufnr('Xargnew1')], tabpagebuflist(1)) + call assert_equal([bufnr('Xargnew2')], tabpagebuflist(2)) + call assert_equal([bufnr('Xargnew3'), bufnr('Xargnew4'), bufnr('Xargnew5')], + \ tabpagebuflist(3)) + set tabpagemax& + + " Without the 'hidden' option, modified buffers should not be closed. + args Xargnew1 Xargnew2 + %bw! + edit Xargtemp1 + call setline(1, 'temp buffer 1') + split Xargtemp2 + call setline(1, 'temp buffer 2') + all + call assert_equal(4, winnr('$')) + call assert_equal([bufnr('Xargtemp2'), bufnr('Xargtemp1'), bufnr('Xargnew1'), + \ bufnr('Xargnew2')], + \ [winbufnr(1), winbufnr(2), winbufnr(3), winbufnr(4)]) + + " With the 'hidden' option set, both modified and unmodified buffers in + " closed windows should be hidden. + set hidden + all + call assert_equal(2, winnr('$')) + call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2')], + \ [winbufnr(1), winbufnr(2)]) + call assert_equal([1, 1, 0, 0], [getbufinfo('Xargtemp1')[0].hidden, + \ getbufinfo('Xargtemp2')[0].hidden, + \ getbufinfo('Xargnew1')[0].hidden, + \ getbufinfo('Xargnew2')[0].hidden]) + set nohidden + + " When 'winheight' is set to a large value, :all should open only one + " window. + args Xargnew1 Xargnew2 Xargnew3 Xargnew4 Xargnew5 + %bw! + set winheight=9999 + call assert_fails('all', 'E36:') + call assert_equal([1, bufnr('Xargnew1')], [winnr('$'), winbufnr(1)]) + set winheight& + + " When 'winwidth' is set to a large value, :vert all should open only one + " window. + %bw! + set winwidth=9999 + call assert_fails('vert all', 'E36:') + call assert_equal([1, bufnr('Xargnew1')], [winnr('$'), winbufnr(1)]) + set winwidth& + + " empty argument list tests + %bw! + %argdelete + call assert_equal('', execute('args')) + all + call assert_equal(1, winnr('$')) + + %argdelete + %bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index c232a7b62f..fe87dabfcc 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 422, /**/ 421, /**/ From 9132426334a8c7e159db93ec1b08ed61ac600aae Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 9 Sep 2022 13:27:59 +0100 Subject: [PATCH 03/28] patch 9.0.0423: "for" and "while" not recognized after :vim9cmd and :legacy Problem: "for" and "while" not recognized after :vim9cmd and :legacy. (Emanuele Torre) Solution: Recognize all the command modifiers. (closes #11087) Add a test to check the list of modifiers. --- src/ex_docmd.c | 5 ++++- src/testdir/Make_all.mak | 2 ++ src/testdir/test_cmdmods.vim | 35 +++++++++++++++++++++++++++++++++ src/testdir/test_eval_stuff.vim | 9 +++++++++ src/version.c | 2 ++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/testdir/test_cmdmods.vim diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 0b6b217121..0024c99c63 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -2888,7 +2888,7 @@ parse_command_modifiers( switch (*p) { - // When adding an entry, also modify cmd_exists(). + // When adding an entry, also modify cmdmods[]. case 'a': if (!checkforcmd_noparen(&eap->cmd, "aboveleft", 3)) break; cmod->cmod_split |= WSP_ABOVE; @@ -3958,11 +3958,13 @@ static struct cmdmod {"confirm", 4, FALSE}, {"filter", 4, FALSE}, {"hide", 3, FALSE}, + {"horizontal", 3, FALSE}, {"keepalt", 5, FALSE}, {"keepjumps", 5, FALSE}, {"keepmarks", 3, FALSE}, {"keeppatterns", 5, FALSE}, {"leftabove", 5, FALSE}, + {"legacy", 3, FALSE}, {"lockmarks", 3, FALSE}, {"noautocmd", 3, FALSE}, {"noswapfile", 3, FALSE}, @@ -3974,6 +3976,7 @@ static struct cmdmod {"unsilent", 3, FALSE}, {"verbose", 4, TRUE}, {"vertical", 4, FALSE}, + {"vim9cmd", 4, FALSE}, }; /* diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak index dbda7e15f3..d7abcb5a48 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -87,6 +87,7 @@ NEW_TESTS = \ test_clientserver \ test_close_count \ test_cmdline \ + test_cmdmods \ test_cmdwin \ test_command_count \ test_comments \ @@ -346,6 +347,7 @@ NEW_TESTS_RES = \ test_clientserver.res \ test_close_count.res \ test_cmdline.res \ + test_cmdmods.res \ test_cmdwin.res \ test_command_count.res \ test_comments.res \ diff --git a/src/testdir/test_cmdmods.vim b/src/testdir/test_cmdmods.vim new file mode 100644 index 0000000000..eb6dff1cee --- /dev/null +++ b/src/testdir/test_cmdmods.vim @@ -0,0 +1,35 @@ +" Test for all comand modifiers in + +def Test_cmdmods_array() + # Get all the command modifiers from ex_cmds.h. + var lines = readfile('../ex_cmds.h')->filter((_, l) => l =~ 'ex_wrongmodifier,') + var cmds = lines->map((_, v) => substitute(v, '.*"\(\k*\)".*', '\1', '')) + + # :hide is both a command and a modifier + cmds->extend(['hide']) + + # Get the entries of cmdmods[] in ex_docmd.c + edit ../ex_docmd.c + var top = search('^} cmdmods[') + 1 + var bot = search('^};') - 1 + lines = getline(top, bot) + var mods = lines->map((_, v) => substitute(v, '.*"\(\k*\)".*', '\1', '')) + + # Check the lists are equal. Convert them to a dict to get a clearer error + # message. + var cmds_dict = {} + for v in cmds + cmds_dict[v] = 1 + endfor + var mods_dict = {} + for v in mods + mods_dict[v] = 1 + endfor + assert_equal(cmds_dict, mods_dict) + + bwipe! +enddef + + +" vim: shiftwidth=2 sts=2 expandtab + diff --git a/src/testdir/test_eval_stuff.vim b/src/testdir/test_eval_stuff.vim index 0081d89a52..7d8421b725 100644 --- a/src/testdir/test_eval_stuff.vim +++ b/src/testdir/test_eval_stuff.vim @@ -146,6 +146,15 @@ func Test_for_over_null_string() let &enc = save_enc endfunc +func Test_for_with_modifier() + " this checks has_loop_cmd() works with a modifier + let result = [] + vim9cmd for i in range(3) + call extend(result, [i]) + endfor + call assert_equal([0, 1, 2], result) +endfunc + func Test_for_invalid_line_count() let lines =<< trim END 111111111111111111111111 for line in ['one'] diff --git a/src/version.c b/src/version.c index fe87dabfcc..445ac6dde5 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 423, /**/ 422, /**/ From 7d56cfc861e57145f003315efd835cf5dfd5b145 Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Fri, 9 Sep 2022 14:11:41 +0100 Subject: [PATCH 04/28] patch 9.0.0424: gitattributes files are not recognized Problem: gitattributes files are not recognized. Solution: Add patterns to match gitattributes files. (closes #11085) --- runtime/filetype.vim | 4 ++++ src/testdir/test_filetype.vim | 1 + src/version.c | 2 ++ 3 files changed, 7 insertions(+) diff --git a/runtime/filetype.vim b/runtime/filetype.vim index f445d7cb05..d9e1433270 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -720,7 +720,11 @@ au BufNewFile,BufRead *.git/worktrees/*/config.worktree setf gitconfig au BufNewFile,BufRead .gitmodules,*.git/modules/*/config setf gitconfig if !empty($XDG_CONFIG_HOME) au BufNewFile,BufRead $XDG_CONFIG_HOME/git/config setf gitconfig + au BufNewFile,BufRead $XDG_CONFIG_HOME/git/attributes setf gitattributes endif +au BufNewFile,BufRead .gitattributes,*.git/info/attributes setf gitattributes +au BufNewFile,BufRead */.config/git/attributes setf gitattributes +au BufNewFile,BufRead */etc/gitattributes setf gitattributes au BufNewFile,BufRead git-rebase-todo setf gitrebase au BufRead,BufNewFile .gitsendemail.msg.?????? setf gitsendemail au BufNewFile,BufRead *.git/* diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index 33b0894b2a..b70a9fe875 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -213,6 +213,7 @@ let s:filename_checks = { \ 'gedcom': ['file.ged', 'lltxxxxx.txt', '/tmp/lltmp', '/tmp/lltmp-file', 'any/tmp/lltmp', 'any/tmp/lltmp-file'], \ 'gemtext': ['file.gmi', 'file.gemini'], \ 'gift': ['file.gift'], + \ 'gitattributes': ['file.git/info/attributes', '.gitattributes', '/.config/git/attributes', '/etc/gitattributes', '/usr/local/etc/gitattributes', 'some.git/info/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'], \ 'gitolite': ['gitolite.conf', '/gitolite-admin/conf/file', 'any/gitolite-admin/conf/file'], diff --git a/src/version.c b/src/version.c index 445ac6dde5..24c99fd4e7 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 424, /**/ 423, /**/ From ae04a6049b3f0e30a671966ed2dda1979e0b5f20 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 9 Sep 2022 15:08:10 +0100 Subject: [PATCH 05/28] patch 9.0.0425: autocmd test is a bit flaky on MS-Windows Problem: Autocmd test is a bit flaky on MS-Windows. Solution: Add a bit more sleeping. (Ken Takata, closes #11095) --- src/testdir/test_autocmd.vim | 4 +++- src/version.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 3370190960..458ac38f47 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -763,7 +763,7 @@ func Test_autocmd_bufwipe_in_SessLoadPost() call writefile(content, 'Xvimrc', 'D') call system(GetVimCommand('Xvimrc') .. ' --not-a-term --noplugins -S Session.vim -c cq') - sleep 50m + sleep 100m let errors = join(readfile('Xerrors')) call assert_match('E814:', errors) @@ -787,6 +787,7 @@ func Test_autocmd_blast_badd() call writefile(content, 'XblastBall', 'D') call system(GetVimCommand() .. ' --clean -S XblastBall') + sleep 100m call assert_match('OK', readfile('Xerrors')->join()) call delete('Xerrors') @@ -823,6 +824,7 @@ func Test_autocmd_bufwipe_in_SessLoadPost2() call writefile(content, 'Xvimrc', 'D') call system(GetVimCommand('Xvimrc') .. ' --not-a-term --noplugins -S Session.vim -c cq') + sleep 100m let errors = join(readfile('Xerrors')) " This probably only ever matches on unix. call assert_notmatch('Caught deadly signal SEGV', errors) diff --git a/src/version.c b/src/version.c index 24c99fd4e7..34fa8ef228 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 425, /**/ 424, /**/ From 65258d36ddfab371c7982343efc9b2533ba39075 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 9 Sep 2022 15:09:59 +0100 Subject: [PATCH 06/28] patch 9.0.0426: failed flaky tests reports only start time Problem: Failed flaky tests reports only start time. Solution: Also report the end time. --- src/testdir/runtest.vim | 3 ++- src/version.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/testdir/runtest.vim b/src/testdir/runtest.vim index 72a8f989f8..68c3dd3eff 100644 --- a/src/testdir/runtest.vim +++ b/src/testdir/runtest.vim @@ -479,7 +479,8 @@ for g:testfunc in sort(s:tests) call add(s:messages, 'Found errors in ' .. g:testfunc .. ':') call extend(s:messages, v:errors) - call add(total_errors, starttime .. ' Run ' .. g:run_nr .. ':') + let endtime = strftime("%H:%M:%S") + call add(total_errors, $'Run {g:run_nr}, {starttime} - {endtime}:') call extend(total_errors, v:errors) if g:run_nr >= 5 || prev_error == v:errors[0] diff --git a/src/version.c b/src/version.c index 34fa8ef228..14767813e8 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 426, /**/ 425, /**/ From 8995c4cd4e697141faf74da9a87e0c1221bfb161 Mon Sep 17 00:00:00 2001 From: Rodrigo Aguilera Date: Fri, 9 Sep 2022 16:10:26 +0100 Subject: [PATCH 07/28] patch 9.0.0427: Drupal theme files are not recognized Problem: Drupal theme files are not recognized. Solution: Use php filetype for Drupl theme files. Remove trailing spaces. (Rodrigo Aguilera, closes #11096) --- runtime/filetype.vim | 5 +++-- src/testdir/test_filetype.vim | 16 ++++++++-------- src/version.c | 2 ++ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/runtime/filetype.vim b/runtime/filetype.vim index d9e1433270..9c43fb85fd 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1323,7 +1323,7 @@ au BufNewFile,BufRead *.or setf openroad au BufNewFile,BufRead *.[Oo][Pp][Ll] setf opl " OpenSCAD -au BufNewFile,BufRead *.scad setf openscad +au BufNewFile,BufRead *.scad setf openscad " Oracle config file au BufNewFile,BufRead *.ora setf ora @@ -1398,7 +1398,8 @@ au BufNewFile,BufRead *.pod setf pod " Also Phtml (was used for PHP 2 in the past). " Also .ctp for Cake template file. " Also .phpt for php tests. -au BufNewFile,BufRead *.php,*.php\d,*.phtml,*.ctp,*.phpt setf php +" Also .theme for Drupal theme files. +au BufNewFile,BufRead *.php,*.php\d,*.phtml,*.ctp,*.phpt,*.theme setf php " PHP config au BufNewFile,BufRead php.ini-* setf dosini diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index b70a9fe875..d2bfa91073 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -410,7 +410,7 @@ let s:filename_checks = { \ 'perl': ['file.plx', 'file.al', 'file.psgi', 'gitolite.rc', '.gitolite.rc', 'example.gitolite.rc'], \ 'pf': ['pf.conf'], \ 'pfmain': ['main.cf'], - \ 'php': ['file.php', 'file.php9', 'file.phtml', 'file.ctp', 'file.phpt'], + \ 'php': ['file.php', 'file.php9', 'file.phtml', 'file.ctp', 'file.phpt', 'file.theme'], \ 'pike': ['file.pike', 'file.pmod'], \ 'pilrc': ['file.rcp'], \ 'pine': ['.pinerc', 'pinerc', '.pinercex', 'pinercex'], @@ -535,7 +535,7 @@ let s:filename_checks = { \ 'stata': ['file.ado', 'file.do', 'file.imata', 'file.mata'], \ 'stp': ['file.stp'], \ 'sudoers': ['any/etc/sudoers', 'sudoers.tmp', '/etc/sudoers', 'any/etc/sudoers.d/file'], - \ 'supercollider': ['file.quark'], + \ 'supercollider': ['file.quark'], \ 'surface': ['file.sface'], \ 'svelte': ['file.svelte'], \ 'svg': ['file.svg'], @@ -1355,7 +1355,7 @@ func Test_mod_file() unlet g:filetype_mod bwipe! - " RAPID header start with a line containing only "%%%", + " RAPID header start with a line containing only "%%%", " but is not always present. call writefile(['%%%'], 'modfile.mod') split modfile.mod @@ -1371,7 +1371,7 @@ func Test_mod_file() bwipe! call delete('modfile.Mod') - " RAPID is not case sensitive, embedded spaces, sysmodule, + " RAPID is not case sensitive, embedded spaces, sysmodule, " file starts with empty line(s). call writefile(['', 'MODULE rapidmödüle (SYSMODULE,NOSTEPIN)'], 'modfile.MOD') split modfile.MOD @@ -1499,7 +1499,7 @@ func Test_prg_file() unlet g:filetype_prg bwipe! - " RAPID header start with a line containing only "%%%", + " RAPID header start with a line containing only "%%%", " but is not always present. call writefile(['%%%'], 'prgfile.prg') split prgfile.prg @@ -1515,7 +1515,7 @@ func Test_prg_file() bwipe! call delete('prgfile.Prg') - " RAPID is not case sensitive, embedded spaces, sysmodule, + " RAPID is not case sensitive, embedded spaces, sysmodule, " file starts with empty line(s). call writefile(['', 'MODULE rapidmödüle (SYSMODULE,NOSTEPIN)'], 'prgfile.PRG') split prgfile.PRG @@ -1626,7 +1626,7 @@ func Test_sys_file() unlet g:filetype_sys bwipe! - " RAPID header start with a line containing only "%%%", + " RAPID header start with a line containing only "%%%", " but is not always present. call writefile(['%%%'], 'sysfile.sys') split sysfile.sys @@ -1642,7 +1642,7 @@ func Test_sys_file() bwipe! call delete('sysfile.Sys') - " RAPID is not case sensitive, embedded spaces, sysmodule, + " RAPID is not case sensitive, embedded spaces, sysmodule, " file starts with empty line(s). call writefile(['', 'MODULE rapidmödüle (SYSMODULE,NOSTEPIN)'], 'sysfile.SYS') split sysfile.SYS diff --git a/src/version.c b/src/version.c index 14767813e8..dd12a26f6d 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 427, /**/ 426, /**/ From be9fc5b60cbdf697c4f6d12345dd7fcdb5d6ca01 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 9 Sep 2022 17:09:35 +0100 Subject: [PATCH 08/28] patch 9.0.0428: autocmd test uses common file name Problem: Autocmd test uses common file name. Solution: Use unique name to reduce flakiness. --- src/testdir/test_autocmd.vim | 18 +++++++++--------- src/testdir/test_startup.vim | 32 ++++++++++++++++---------------- src/version.c | 2 ++ 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 458ac38f47..17bfd1b60b 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -756,7 +756,7 @@ func Test_autocmd_bufwipe_in_SessLoadPost() augroup END func WriteErrors() - call writefile([execute("messages")], "Xerrors") + call writefile([execute("messages")], "XerrorsBwipe") endfunc au VimLeave * call WriteErrors() [CODE] @@ -764,11 +764,11 @@ func Test_autocmd_bufwipe_in_SessLoadPost() call writefile(content, 'Xvimrc', 'D') call system(GetVimCommand('Xvimrc') .. ' --not-a-term --noplugins -S Session.vim -c cq') sleep 100m - let errors = join(readfile('Xerrors')) + let errors = join(readfile('XerrorsBwipe')) call assert_match('E814:', errors) set swapfile - for file in ['Session.vim', 'Xerrors'] + for file in ['Session.vim', 'XerrorsBwipe'] call delete(file) endfor endfunc @@ -781,16 +781,16 @@ func Test_autocmd_blast_badd() edit foo1 au BufNew,BufAdd,BufWinEnter,BufEnter,BufLeave,BufWinLeave,BufUnload,VimEnter foo* ball edit foo2 - call writefile(['OK'], 'Xerrors') + call writefile(['OK'], 'XerrorsBlast') qall [CODE] call writefile(content, 'XblastBall', 'D') call system(GetVimCommand() .. ' --clean -S XblastBall') sleep 100m - call assert_match('OK', readfile('Xerrors')->join()) + call assert_match('OK', readfile('XerrorsBlast')->join()) - call delete('Xerrors') + call delete('XerrorsBlast') endfunc " SEGV occurs in older versions. @@ -817,7 +817,7 @@ func Test_autocmd_bufwipe_in_SessLoadPost2() au SessionLoadPost * call DeleteInactiveBufs() func WriteErrors() - call writefile([execute("messages")], "Xerrors") + call writefile([execute("messages")], "XerrorsPost") endfunc au VimLeave * call WriteErrors() [CODE] @@ -825,13 +825,13 @@ func Test_autocmd_bufwipe_in_SessLoadPost2() call writefile(content, 'Xvimrc', 'D') call system(GetVimCommand('Xvimrc') .. ' --not-a-term --noplugins -S Session.vim -c cq') sleep 100m - let errors = join(readfile('Xerrors')) + let errors = join(readfile('XerrorsPost')) " This probably only ever matches on unix. call assert_notmatch('Caught deadly signal SEGV', errors) call assert_match('SessionLoadPost DONE', errors) set swapfile - for file in ['Session.vim', 'Xerrors'] + for file in ['Session.vim', 'XerrorsPost'] call delete(file) endfor endfunc diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 573b6767ee..6cc62ad015 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -306,9 +306,9 @@ func Test_q_arg() call writefile(lines, 'Xbadfile.c') let after =<< trim [CODE] - call writefile([&errorfile, string(getpos("."))], "Xtestout") + call writefile([&errorfile, string(getpos("."))], "XtestoutQarg") copen - w >> Xtestout + w >> XtestoutQarg qall [CODE] @@ -316,30 +316,30 @@ func Test_q_arg() call assert_equal('errors.err', &errorfile) call writefile(["Xbadfile.c:4:12: error: expected ';' before '}' token"], 'errors.err') if RunVim([], after, '-q') - let lines = readfile('Xtestout') + let lines = readfile('XtestoutQarg') call assert_equal(['errors.err', \ '[0, 4, 12, 0]', \ "Xbadfile.c|4 col 12| error: expected ';' before '}' token"], \ lines) endif - call delete('Xtestout') + call delete('XtestoutQarg') call delete('errors.err') - " Test with explicit argument '-q Xerrors' (with space). - call writefile(["Xbadfile.c:4:12: error: expected ';' before '}' token"], 'Xerrors') - if RunVim([], after, '-q Xerrors') - let lines = readfile('Xtestout') - call assert_equal(['Xerrors', + " Test with explicit argument '-q XerrorsQarg' (with space). + call writefile(["Xbadfile.c:4:12: error: expected ';' before '}' token"], 'XerrorsQarg') + if RunVim([], after, '-q XerrorsQarg') + let lines = readfile('XtestoutQarg') + call assert_equal(['XerrorsQarg', \ '[0, 4, 12, 0]', \ "Xbadfile.c|4 col 12| error: expected ';' before '}' token"], \ lines) endif - call delete('Xtestout') + call delete('XtestoutQarg') - " Test with explicit argument '-qXerrors' (without space). - if RunVim([], after, '-qXerrors') - let lines = readfile('Xtestout') - call assert_equal(['Xerrors', + " Test with explicit argument '-qXerrorsQarg' (without space). + if RunVim([], after, '-qXerrorsQarg') + let lines = readfile('XtestoutQarg') + call assert_equal(['XerrorsQarg', \ '[0, 4, 12, 0]', \ "Xbadfile.c|4 col 12| error: expected ';' before '}' token"], \ lines) @@ -350,8 +350,8 @@ func Test_q_arg() call assert_equal(3, v:shell_error) call delete('Xbadfile.c') - call delete('Xtestout') - call delete('Xerrors') + call delete('XtestoutQarg') + call delete('XerrorsQarg') endfunc " Test the -V[N]{filename} argument to set the 'verbose' option to N diff --git a/src/version.c b/src/version.c index dd12a26f6d..4ba0b1e80c 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 428, /**/ 427, /**/ From 0adae2da17598669e442ba38547ab18a6c1406de Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Fri, 9 Sep 2022 17:39:02 +0100 Subject: [PATCH 09/28] patch 9.0.0429: not all keys are tested for the MS-Windows GUI Problem: Not all keys are tested for the MS-Windows GUI. Solution: Add more key codes to the list. (Yegappan Lakshmanan, closes #11097) --- src/testdir/test_gui.vim | 128 ++++++++++++++++++++++++--------------- src/version.c | 2 + 2 files changed, 80 insertions(+), 50 deletions(-) diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim index b9b6bd8df3..65e59b7759 100644 --- a/src/testdir/test_gui.vim +++ b/src/testdir/test_gui.vim @@ -1651,63 +1651,91 @@ func Test_gui_lowlevel_keyevent() endfor " Test for the various Ctrl and Shift key combinations. + " Refer to the following page for the virtual key codes: + " https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes let keytests = [ - \ [[0x10, 0x21], "\", 2], - \ [[0x11, 0x21], "\", 4], - \ [[0x10, 0x22], "\", 2], - \ [[0x11, 0x22], "\", 4], - \ [[0x10, 0x23], "\", 0], - \ [[0x11, 0x23], "\", 0], - \ [[0x10, 0x24], "\", 0], - \ [[0x11, 0x24], "\", 0], - \ [[0x10, 0x25], "\", 0], - \ [[0x11, 0x25], "\", 0], - \ [[0x10, 0x26], "\", 0], - \ [[0x11, 0x26], "\", 4], - \ [[0x10, 0x27], "\", 0], - \ [[0x11, 0x27], "\", 0], - \ [[0x10, 0x28], "\", 0], - \ [[0x11, 0x28], "\", 4], - \ [[0x11, 0x30], "\", 4], - \ [[0x11, 0x31], "\", 4], - \ [[0x11, 0x32], "\", 4], - \ [[0x11, 0x33], "\", 4], - \ [[0x11, 0x34], "\", 4], - \ [[0x11, 0x35], "\", 4], - \ [[0x11, 0x36], "\", 0], - \ [[0x11, 0x37], "\", 4], - \ [[0x11, 0x38], "\", 4], - \ [[0x11, 0x39], "\", 4], - \ [[0x11, 0x60], "\", 4], - \ [[0x11, 0x61], "\", 4], - \ [[0x11, 0x62], "\", 4], - \ [[0x11, 0x63], "\", 4], - \ [[0x11, 0x64], "\", 4], - \ [[0x11, 0x65], "\", 4], - \ [[0x11, 0x66], "\", 4], - \ [[0x11, 0x67], "\", 4], - \ [[0x11, 0x68], "\", 4], - \ [[0x11, 0x69], "\", 4], - \ [[0x11, 0x6A], "\", 4], - \ [[0x11, 0x6B], "\", 4], - \ [[0x11, 0x6D], "\", 4], - \ [[0x11, 0x70], "\", 4], - \ [[0x11, 0x71], "\", 4], - \ [[0x11, 0x72], "\", 4], - \ [[0x11, 0x73], "\", 4], - \ [[0x11, 0x74], "\", 4], - \ [[0x11, 0x75], "\", 4], - \ [[0x11, 0x76], "\", 4], - \ [[0x11, 0x77], "\", 4], - \ [[0x11, 0x78], "\", 4], + \ [[0x10, 0x21], "S-Pageup", 2], + \ [[0xA0, 0x21], "S-Pageup", 2], + \ [[0xA1, 0x21], "S-Pageup", 2], + \ [[0x11, 0x21], "C-Pageup", 4], + \ [[0xA2, 0x21], "C-Pageup", 4], + \ [[0xA3, 0x21], "C-Pageup", 4], + \ [[0x11, 0x10, 0x21], "C-S-Pageup", 6], + \ [[0x10, 0x22], "S-PageDown", 2], + \ [[0xA0, 0x22], "S-PageDown", 2], + \ [[0xA1, 0x22], "S-PageDown", 2], + \ [[0x11, 0x22], "C-PageDown", 4], + \ [[0xA2, 0x22], "C-PageDown", 4], + \ [[0xA3, 0x22], "C-PageDown", 4], + \ [[0x11, 0x10, 0x22], "C-S-PageDown", 6], + \ [[0x10, 0x23], "S-End", 0], + \ [[0x11, 0x23], "C-End", 0], + \ [[0x11, 0x10, 0x23], "C-S-End", 4], + \ [[0x10, 0x24], "S-Home", 0], + \ [[0x11, 0x24], "C-Home", 0], + \ [[0x11, 0x10, 0x24], "C-S-Home", 4], + \ [[0x10, 0x25], "S-Left", 0], + \ [[0x11, 0x25], "C-Left", 0], + \ [[0x11, 0x10, 0x25], "C-S-Left", 4], + \ [[0x10, 0x26], "S-Up", 0], + \ [[0x11, 0x26], "C-Up", 4], + \ [[0x11, 0x10, 0x26], "C-S-Up", 4], + \ [[0x10, 0x27], "S-Right", 0], + \ [[0x11, 0x27], "C-Right", 0], + \ [[0x11, 0x10, 0x27], "C-S-Right", 4], + \ [[0x10, 0x28], "S-Down", 0], + \ [[0x11, 0x28], "C-Down", 4], + \ [[0x11, 0x10, 0x28], "C-S-Down", 4], + \ [[0x11, 0x30], "C-0", 4], + \ [[0x11, 0x31], "C-1", 4], + \ [[0x11, 0x32], "C-2", 4], + \ [[0x11, 0x33], "C-3", 4], + \ [[0x11, 0x34], "C-4", 4], + \ [[0x11, 0x35], "C-5", 4], + \ [[0x11, 0x36], "C-^", 0], + \ [[0x11, 0x37], "C-7", 4], + \ [[0x11, 0x38], "C-8", 4], + \ [[0x11, 0x39], "C-9", 4], + \ [[0x11, 0x60], "C-0", 4], + \ [[0x11, 0x61], "C-1", 4], + \ [[0x11, 0x62], "C-2", 4], + \ [[0x11, 0x63], "C-3", 4], + \ [[0x11, 0x64], "C-4", 4], + \ [[0x11, 0x65], "C-5", 4], + \ [[0x11, 0x66], "C-6", 4], + \ [[0x11, 0x67], "C-7", 4], + \ [[0x11, 0x68], "C-8", 4], + \ [[0x11, 0x69], "C-9", 4], + \ [[0x11, 0x6A], "C-*", 4], + \ [[0x11, 0x6B], "C-+", 4], + \ [[0x11, 0x6D], "C--", 4], + \ [[0x11, 0x70], "C-F1", 4], + \ [[0x11, 0x10, 0x70], "C-S-F1", 4], + \ [[0x11, 0x71], "C-F2", 4], + \ [[0x11, 0x10, 0x71], "C-S-F2", 4], + \ [[0x11, 0x72], "C-F3", 4], + \ [[0x11, 0x10, 0x72], "C-S-F3", 4], + \ [[0x11, 0x73], "C-F4", 4], + \ [[0x11, 0x10, 0x73], "C-S-F4", 4], + \ [[0x11, 0x74], "C-F5", 4], + \ [[0x11, 0x10, 0x74], "C-S-F5", 4], + \ [[0x11, 0x75], "C-F6", 4], + \ [[0x11, 0x10, 0x75], "C-S-F6", 4], + \ [[0x11, 0x76], "C-F7", 4], + \ [[0x11, 0x10, 0x76], "C-S-F7", 4], + \ [[0x11, 0x77], "C-F8", 4], + \ [[0x11, 0x10, 0x77], "C-S-F8", 4], + \ [[0x11, 0x78], "C-F9", 4], + \ [[0x11, 0x10, 0x78], "C-S-F9", 4], \ ] for [kcodes, kstr, kmod] in keytests call SendKeys(kcodes) let ch = getcharstr() let mod = getcharmod() - call assert_equal(kstr, ch, $"key = {kstr}") - call assert_equal(kmod, mod) + let keycode = eval('"\<' .. kstr .. '>"') + call assert_equal(keycode, ch, $"key = {kstr}") + call assert_equal(kmod, mod, $"key = {kstr}") endfor bw! diff --git a/src/version.c b/src/version.c index 4ba0b1e80c..ef5f102cd4 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 429, /**/ 428, /**/ From 375141e1f80dced9be738568a3418f65813f4a2f Mon Sep 17 00:00:00 2001 From: Bakudankun Date: Fri, 9 Sep 2022 18:46:47 +0100 Subject: [PATCH 10/28] patch 9.0.0430: cannot use repeat() with a blob Problem: Cannot use repeat() with a blob. Solution: Implement blob repeat. (closes #11090) --- runtime/doc/builtin.txt | 7 +++--- src/errors.h | 2 ++ src/evalfunc.c | 41 ++++++++++++++++++++++++++++--- src/proto/typval.pro | 1 + src/testdir/test_blob.vim | 12 +++++++++ src/testdir/test_vim9_builtin.vim | 6 +++-- src/testdir/test_vim9_func.vim | 6 +++++ src/typval.c | 18 ++++++++++++++ src/version.c | 2 ++ 9 files changed, 87 insertions(+), 8 deletions(-) diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 12d62a6760..01263402fa 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -471,7 +471,8 @@ remove({blob}, {idx} [, {end}]) Number/Blob remove bytes {idx}-{end} from {blob} remove({dict}, {key}) any remove entry {key} from {dict} rename({from}, {to}) Number rename (move) file from {from} to {to} -repeat({expr}, {count}) String repeat {expr} {count} times +repeat({expr}, {count}) List/Blob/String + repeat {expr} {count} times resolve({filename}) String get filename a shortcut points to reverse({list}) List reverse {list} in-place round({expr}) Float round off {expr} @@ -7294,8 +7295,8 @@ repeat({expr}, {count}) *repeat()* result. Example: > :let separator = repeat('-', 80) < When {count} is zero or negative the result is empty. - When {expr} is a |List| the result is {expr} concatenated - {count} times. Example: > + When {expr} is a |List| or a |Blob| the result is {expr} + concatenated {count} times. Example: > :let longlist = repeat(['a', 'b'], 3) < Results in ['a', 'b', 'a', 'b', 'a', 'b']. diff --git a/src/errors.h b/src/errors.h index 2ed62a2afd..45f0d6a66c 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3329,4 +3329,6 @@ EXTERN char e_window_unexpectedly_close_while_searching_for_tags[] #ifdef FEAT_EVAL EXTERN char e_cannot_use_partial_with_dictionary_for_defer[] INIT(= N_("E1300: Cannot use a partial with dictionary for :defer")); +EXTERN char e_string_number_list_or_blob_required_for_argument_nr[] + INIT(= N_("E1301: String, Number, List or Blob required for argument %d")); #endif diff --git a/src/evalfunc.c b/src/evalfunc.c index 2c041fa6de..bc0e23e9c8 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -872,6 +872,7 @@ arg_repeat1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) || type->tt_type == VAR_UNKNOWN || type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER + || type->tt_type == VAR_BLOB || type->tt_type == VAR_LIST) return OK; @@ -4400,6 +4401,10 @@ f_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED) #endif } +/* + * "function()" function + * "funcref()" function + */ static void common_function(typval_T *argvars, typval_T *rettv, int is_funcref) { @@ -8399,18 +8404,19 @@ f_rename(typval_T *argvars, typval_T *rettv) f_repeat(typval_T *argvars, typval_T *rettv) { char_u *p; - int n; + varnumber_T n; int slen; int len; char_u *r; int i; if (in_vim9script() - && (check_for_string_or_number_or_list_arg(argvars, 0) == FAIL + && (check_for_string_or_number_or_list_or_blob_arg(argvars, 0) + == FAIL || check_for_number_arg(argvars, 1) == FAIL)) return; - n = (int)tv_get_number(&argvars[1]); + n = tv_get_number(&argvars[1]); if (argvars[0].v_type == VAR_LIST) { if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) @@ -8419,6 +8425,35 @@ f_repeat(typval_T *argvars, typval_T *rettv) argvars[0].vval.v_list, NULL) == FAIL) break; } + else if (argvars[0].v_type == VAR_BLOB) + { + if (rettv_blob_alloc(rettv) == FAIL + || argvars[0].vval.v_blob == NULL + || n <= 0) + return; + + slen = argvars[0].vval.v_blob->bv_ga.ga_len; + len = (int)slen * n; + if (len <= 0) + return; + + if (ga_grow(&rettv->vval.v_blob->bv_ga, len) == FAIL) + return; + + rettv->vval.v_blob->bv_ga.ga_len = len; + + for (i = 0; i < slen; ++i) + if (blob_get(argvars[0].vval.v_blob, i) != 0) + break; + + if (i == slen) + // No need to copy since all bytes are already zero + return; + + for (i = 0; i < n; ++i) + blob_set_range(rettv->vval.v_blob, + (long)i * slen, ((long)i + 1) * slen - 1, argvars); + } else { p = tv_get_string(&argvars[0]); diff --git a/src/proto/typval.pro b/src/proto/typval.pro index 7d32a03d94..b4733fd474 100644 --- a/src/proto/typval.pro +++ b/src/proto/typval.pro @@ -42,6 +42,7 @@ int check_for_opt_string_or_list_arg(typval_T *args, int idx); int check_for_string_or_dict_arg(typval_T *args, int idx); int check_for_string_or_number_or_list_arg(typval_T *args, int idx); int check_for_opt_string_or_number_or_list_arg(typval_T *args, int idx); +int check_for_string_or_number_or_list_or_blob_arg(typval_T *args, int idx); int check_for_string_or_list_or_dict_arg(typval_T *args, int idx); int check_for_string_or_func_arg(typval_T *args, int idx); int check_for_list_or_blob_arg(typval_T *args, int idx); diff --git a/src/testdir/test_blob.vim b/src/testdir/test_blob.vim index 46370c4749..b0239fd610 100644 --- a/src/testdir/test_blob.vim +++ b/src/testdir/test_blob.vim @@ -725,6 +725,18 @@ func Test_blob2string() call assert_equal(v, string(b)) endfunc +func Test_blob_repeat() + call assert_equal(0z, repeat(0z00, 0)) + call assert_equal(0z00, repeat(0z00, 1)) + call assert_equal(0z0000, repeat(0z00, 2)) + call assert_equal(0z00000000, repeat(0z0000, 2)) + + call assert_equal(0z, repeat(0z12, 0)) + call assert_equal(0z, repeat(0z1234, 0)) + call assert_equal(0z1234, repeat(0z1234, 1)) + call assert_equal(0z12341234, repeat(0z1234, 2)) +endfunc + " Test for blob allocation failure func Test_blob_alloc_failure() " blob variable diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index b74a8eced2..109cb35af6 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -3329,12 +3329,14 @@ def Test_rename() enddef def Test_repeat() - v9.CheckDefAndScriptFailure(['repeat(1.1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1224: String, Number or List required for argument 1']) - v9.CheckDefAndScriptFailure(['repeat({a: 10}, 2)'], ['E1013: Argument 1: type mismatch, expected string but got dict<', 'E1224: String, Number or List required for argument 1']) + v9.CheckDefAndScriptFailure(['repeat(1.1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1301: String, Number, List or Blob required for argument 1']) + v9.CheckDefAndScriptFailure(['repeat({a: 10}, 2)'], ['E1013: Argument 1: type mismatch, expected string but got dict<', 'E1301: String, Number, List or Blob required for argument 1']) var lines =<< trim END assert_equal('aaa', repeat('a', 3)) assert_equal('111', repeat(1, 3)) assert_equal([1, 1, 1], repeat([1], 3)) + assert_equal(0z000102000102000102, repeat(0z000102, 3)) + assert_equal(0z000000, repeat(0z00, 3)) var s = '-' s ..= repeat(5, 3) assert_equal('-555', s) diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index c616e1890d..fce215e47c 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -2533,6 +2533,12 @@ def Test_repeat_return_type() endfor res->assert_equal(3) + res = 0 + for n in repeat(0z01, 3)->blob2list() + res += n + endfor + res->assert_equal(3) + res = 0 for n in add([1, 2], 3) res += n diff --git a/src/typval.c b/src/typval.c index 12a741ec22..95abe212e3 100644 --- a/src/typval.c +++ b/src/typval.c @@ -791,6 +791,24 @@ check_for_opt_string_or_number_or_list_arg(typval_T *args, int idx) || check_for_string_or_number_or_list_arg(args, idx) != FAIL); } +/* + * Give an error and return FAIL unless "args[idx]" is a string or a number + * or a list or a blob. + */ + int +check_for_string_or_number_or_list_or_blob_arg(typval_T *args, int idx) +{ + if (args[idx].v_type != VAR_STRING + && args[idx].v_type != VAR_NUMBER + && args[idx].v_type != VAR_LIST + && args[idx].v_type != VAR_BLOB) + { + semsg(_(e_string_number_list_or_blob_required_for_argument_nr), idx + 1); + return FAIL; + } + return OK; +} + /* * Give an error and return FAIL unless "args[idx]" is a string or a list * or a dict. diff --git a/src/version.c b/src/version.c index ef5f102cd4..3b02a3b111 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 430, /**/ 429, /**/ From 7cf5839287de6f65c981a876d8a1c7e6f8d2494b Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 9 Sep 2022 20:19:40 +0100 Subject: [PATCH 11/28] patch 9.0.0431: current mode shows in message window Problem: Current mode shows in message window. Solution: Reset in_echowindow before redrawing. (issue #11094) --- src/popupwin.c | 3 ++- src/testdir/dumps/Test_echowin_showmode.dump | 8 ++++++++ src/testdir/test_messages.vim | 20 ++++++++++++++++++++ src/version.c | 2 ++ 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/testdir/dumps/Test_echowin_showmode.dump diff --git a/src/popupwin.c b/src/popupwin.c index 5f003803ba..a33fa5f8b7 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -4545,6 +4545,8 @@ start_echowindow(void) void end_echowindow(void) { + in_echowindow = FALSE; + // show the message window now redraw_cmd(FALSE); @@ -4553,7 +4555,6 @@ end_echowindow(void) msg_didout = TRUE; if (msg_col == 0) msg_col = 1; - in_echowindow = FALSE; } #endif diff --git a/src/testdir/dumps/Test_echowin_showmode.dump b/src/testdir/dumps/Test_echowin_showmode.dump new file mode 100644 index 0000000000..24eb4d0233 --- /dev/null +++ b/src/testdir/dumps/Test_echowin_showmode.dump @@ -0,0 +1,8 @@ +>o+0&#ffffff0|n+0&#e0e0e08|e| | +0&#ffffff0@70 +|t|w|o| @71 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|═+0#e000002&@74 +|e|c|h|o| |w|i|n|d|o|w| @63 +|-+2#0000000&@1| |V|I|S|U|A|L| |L|I|N|E| |-@1| +0&&@29|1| @8|1|,|1| @10|A|l@1| diff --git a/src/testdir/test_messages.vim b/src/testdir/test_messages.vim index 07a4b229a7..4a2deae1e6 100644 --- a/src/testdir/test_messages.vim +++ b/src/testdir/test_messages.vim @@ -440,5 +440,25 @@ func Test_echowin_eval() call delete('XtestEchowindow') endfunc +" messages window should not be used for showing the mode +func Test_echowin_showmode() + CheckScreendump + + let lines =<< trim END + vim9script + setline(1, ['one', 'two']) + timer_start(100, (_) => { + echowin 'echo window' + }) + normal V + END + call writefile(lines, 'XtestEchowinMode', 'D') + let buf = RunVimInTerminal('-S XtestEchowinMode', #{rows: 8}) + call VerifyScreenDump(buf, 'Test_echowin_showmode', {}) + + " clean up + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 3b02a3b111..eb979bc046 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 431, /**/ 430, /**/ From 6de2296e5e696b894576d48239aaab0ae84486ff Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 9 Sep 2022 21:35:36 +0100 Subject: [PATCH 12/28] patch 9.0.0432: crash when using for loop variable in closure Problem: Crash when using for loop variable in closure. Solution: Check that the variable wasn't deleted. (issue #11094) --- src/errors.h | 2 ++ .../dumps/Test_vim9_closure_fails.dump | 6 +++++ src/testdir/test_vim9_func.vim | 27 +++++++++++++++++-- src/version.c | 2 ++ src/vim9execute.c | 6 +++++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/testdir/dumps/Test_vim9_closure_fails.dump diff --git a/src/errors.h b/src/errors.h index 45f0d6a66c..050cec768d 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3331,4 +3331,6 @@ EXTERN char e_cannot_use_partial_with_dictionary_for_defer[] INIT(= N_("E1300: Cannot use a partial with dictionary for :defer")); EXTERN char e_string_number_list_or_blob_required_for_argument_nr[] INIT(= N_("E1301: String, Number, List or Blob required for argument %d")); +EXTERN char e_script_variable_was_deleted[] + INIT(= N_("E1302: Script variable was deleted")); #endif diff --git a/src/testdir/dumps/Test_vim9_closure_fails.dump b/src/testdir/dumps/Test_vim9_closure_fails.dump new file mode 100644 index 0000000000..1189a3a919 --- /dev/null +++ b/src/testdir/dumps/Test_vim9_closure_fails.dump @@ -0,0 +1,6 @@ +|~+0#4040ff13#ffffff0| @73 +|~| @73 +|E+0#ffffff16#e000002|r@1|o|r| |d|e|t|e|c|t|e|d| |w|h|i|l|e| |p|r|o|c|e|s@1|i|n|g| |f|u|n|c|t|i|o|n| |<|l|a|m|b|d|a|>|1|:| +0#0000000#ffffff0@23 +|l+0#af5f00255&|i|n|e| @3|1|:| +0#0000000&@64 +|E+0#ffffff16#e000002|1|3|0|2|:| |S|c|r|i|p|t| |v|a|r|i|a|b|l|e| |w|a|s| |d|e|l|e|t|e|d| +0#0000000#ffffff0@40 +|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/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index fce215e47c..70a71ea932 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -2943,6 +2943,30 @@ def Test_nested_closure_fails() v9.CheckScriptFailure(lines, 'E1012:') enddef +def Run_Test_closure_in_for_loop_fails() + var lines =<< trim END + vim9script + for n in [0] + timer_start(10, (_) => { + echo n + }) + endfor + END + writefile(lines, 'XTest_closure_fails', 'D') + + # Check that an error shows + var buf = g:RunVimInTerminal('-S XTest_closure_fails', {'rows': 6}) + g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {}) + + # clean up + g:StopVimInTerminal(buf) +enddef + +func Test_closure_in_for_loop_fails() + CheckScreendump + call Run_Test_closure_in_for_loop_fails() +endfunc + def Test_global_closure() var lines =<< trim END vim9script @@ -3321,7 +3345,7 @@ def Run_Test_silent_echo() enddef defcompile END - writefile(lines, 'XTest_silent_echo') + writefile(lines, 'XTest_silent_echo', 'D') # Check that the balloon shows up after a mouse move var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) @@ -3330,7 +3354,6 @@ def Run_Test_silent_echo() # clean up g:StopVimInTerminal(buf) - delete('XTest_silent_echo') enddef def SilentlyError() diff --git a/src/version.c b/src/version.c index eb979bc046..3c7c9c82da 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 432, /**/ 431, /**/ diff --git a/src/vim9execute.c b/src/vim9execute.c index 30ff7a7755..d4d1ad6995 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -1716,6 +1716,12 @@ get_script_svar(scriptref_T *sref, int dfunc_idx) return NULL; } sv = ((svar_T *)si->sn_var_vals.ga_data) + sref->sref_idx; + if (sv->sv_name == NULL) + { + if (dfunc != NULL) + emsg(_(e_script_variable_was_deleted)); + return NULL; + } if (!equal_type(sv->sv_type, sref->sref_type, 0)) { if (dfunc != NULL) From 12553ada3b1ceee0179527abc9980b8392fd6c7e Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 10 Sep 2022 10:42:20 +0100 Subject: [PATCH 13/28] patch 9.0.0433: Coverity warns for not checking allocation failure Problem: Coverity warns for not checking allocation failure. Solution: Check that allocating a list or blob succeeded. --- src/eval.c | 10 +++++++--- src/version.c | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/eval.c b/src/eval.c index 9891473813..d69abb0172 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1121,6 +1121,8 @@ get_lval( var2.v_type = VAR_UNKNOWN; while (*p == '[' || (*p == '.' && p[1] != '=' && p[1] != '.')) { + int r; + if (*p == '.' && lp->ll_tv->v_type != VAR_DICT) { if (!quiet) @@ -1136,12 +1138,14 @@ get_lval( return NULL; } - // a NULL list/blob works like an empty list/blob, allocate one now. + // A NULL list/blob works like an empty list/blob, allocate one now. if (lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list == NULL) - rettv_list_alloc(lp->ll_tv); + r = rettv_list_alloc(lp->ll_tv); else if (lp->ll_tv->v_type == VAR_BLOB && lp->ll_tv->vval.v_blob == NULL) - rettv_blob_alloc(lp->ll_tv); + r = rettv_blob_alloc(lp->ll_tv); + if (r == FAIL) + return NULL; if (lp->ll_range) { diff --git a/src/version.c b/src/version.c index 3c7c9c82da..51478ad6e3 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 433, /**/ 432, /**/ From 9ba2786f15f0b53a90fd221832a5bedfc6dbfe20 Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Sat, 10 Sep 2022 11:04:24 +0100 Subject: [PATCH 14/28] patch 9.0.0434: gitignore files are not recognized Problem: gitignore files are not recognized. Solution: Add patterns for the gitignore filetype. (closes #11102) --- runtime/filetype.vim | 11 +++++++---- src/testdir/test_filetype.vim | 1 + src/version.c | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 9c43fb85fd..0223402a4b 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -721,12 +721,15 @@ au BufNewFile,BufRead .gitmodules,*.git/modules/*/config setf gitconfig if !empty($XDG_CONFIG_HOME) au BufNewFile,BufRead $XDG_CONFIG_HOME/git/config setf gitconfig au BufNewFile,BufRead $XDG_CONFIG_HOME/git/attributes setf gitattributes + au BufNewFile,BufRead $XDG_CONFIG_HOME/git/ignore setf gitignore endif au BufNewFile,BufRead .gitattributes,*.git/info/attributes setf gitattributes -au BufNewFile,BufRead */.config/git/attributes setf gitattributes -au BufNewFile,BufRead */etc/gitattributes setf gitattributes -au BufNewFile,BufRead git-rebase-todo setf gitrebase -au BufRead,BufNewFile .gitsendemail.msg.?????? setf gitsendemail +au BufNewFile,BufRead */.config/git/attributes setf gitattributes +au BufNewFile,BufRead */etc/gitattributes setf gitattributes +au BufNewFile,BufRead .gitignore,*.git/info/exclude setf gitignore +au BufNewFile,BufRead */.config/git/ignore setf gitignore +au BufNewFile,BufRead git-rebase-todo setf gitrebase +au BufRead,BufNewFile .gitsendemail.msg.?????? setf gitsendemail au BufNewFile,BufRead *.git/* \ if getline(1) =~# '^\x\{40,\}\>\|^ref: ' | \ setf git | diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index d2bfa91073..e42b8a0da5 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -216,6 +216,7 @@ let s:filename_checks = { \ 'gitattributes': ['file.git/info/attributes', '.gitattributes', '/.config/git/attributes', '/etc/gitattributes', '/usr/local/etc/gitattributes', 'some.git/info/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'], + \ 'gitignore': ['file.git/info/exclude', '.gitignore', '/.config/git/ignore', 'some.git/info/exclude'], \ 'gitolite': ['gitolite.conf', '/gitolite-admin/conf/file', 'any/gitolite-admin/conf/file'], \ 'gitrebase': ['git-rebase-todo'], \ 'gitsendemail': ['.gitsendemail.msg.xxxxxx'], diff --git a/src/version.c b/src/version.c index 51478ad6e3..7b0edde67f 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 434, /**/ 433, /**/ From f21d546d8f80b85a1770fc4c9f48f2d92e2e82fa Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 10 Sep 2022 12:36:00 +0100 Subject: [PATCH 15/28] patch 9.0.0435: compiler warning for uninitialized variable Problem: Compiler warning for uninitialized variable. Solution: Initialize it. --- src/eval.c | 2 +- src/version.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/eval.c b/src/eval.c index d69abb0172..db8b4e6c98 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1121,7 +1121,7 @@ get_lval( var2.v_type = VAR_UNKNOWN; while (*p == '[' || (*p == '.' && p[1] != '=' && p[1] != '.')) { - int r; + int r = OK; if (*p == '.' && lp->ll_tv->v_type != VAR_DICT) { diff --git a/src/version.c b/src/version.c index 7b0edde67f..29483f3060 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 435, /**/ 434, /**/ From 2da11a4124989e3be917fa8024025d2e1452b363 Mon Sep 17 00:00:00 2001 From: "K.Takata" Date: Sat, 10 Sep 2022 13:03:12 +0100 Subject: [PATCH 16/28] patch 9.0.0436: CI: running tests in parallel causes flakiness Problem: CI: running tests in parallel causes flakiness. Solution: Reorganize the MS-Windows runs. (Ken Takata, closes #11101) --- .github/workflows/ci.yml | 192 +++++++++++++++++++-------------------- src/errors.h | 4 +- src/gui_w32.c | 4 +- src/os_win32.c | 6 +- src/version.c | 2 + 5 files changed, 101 insertions(+), 107 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05e675de81..8494379797 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -382,35 +382,15 @@ jobs: strategy: fail-fast: false matrix: - toolchain: [msvc, mingw] - arch: [x64, x86] - features: [HUGE, NORMAL] include: - - arch: x64 - vcarch: amd64 - warch: x64 - bits: 64 - msystem: MINGW64 - cygreg: registry - pyreg: "" - - arch: x86 - vcarch: x86 - warch: ia32 - bits: 32 - msystem: MINGW32 - cygreg: registry32 - pyreg: "-32" - - toolchain: mingw - arch: x64 - features: HUGE - coverage: yes - exclude: - - toolchain: msvc - arch: x64 - features: NORMAL - - toolchain: mingw - arch: x86 - features: NORMAL + - { features: HUGE, toolchain: msvc, VIMDLL: no, GUI: no, arch: x64 } + - { features: HUGE, toolchain: mingw, VIMDLL: yes, GUI: yes, arch: x86, coverage: yes } + - { features: HUGE, toolchain: msvc, VIMDLL: no, GUI: yes, arch: x86 } + - { features: HUGE, toolchain: mingw, VIMDLL: yes, GUI: no, arch: x64, coverage: yes } + - { features: NORMAL, toolchain: msvc, VIMDLL: yes, GUI: no, arch: x86 } + - { features: NORMAL, toolchain: mingw, VIMDLL: no, GUI: yes, arch: x64 } + - { features: TINY, toolchain: msvc, VIMDLL: yes, GUI: yes, arch: x64 } + - { features: TINY, toolchain: mingw, VIMDLL: no, GUI: no, arch: x86 } steps: - name: Initialize @@ -418,13 +398,32 @@ jobs: shell: bash run: | git config --global core.autocrlf input - echo "VCVARSALL=$(vswhere -products \* -latest -property installationPath)\\VC\\Auxiliary\\Build\\vcvarsall.bat" >> $GITHUB_ENV - if [ "${{ matrix.arch }}" = "x86" ]; then - choco install python2 --forcex86 + + if [ "${{ matrix.arch }}" = "x64" ]; then + cygreg=registry + pyreg= + echo "VCARCH=amd64" >> $GITHUB_ENV + echo "WARCH=x64" >> $GITHUB_ENV + echo "BITS=64" >> $GITHUB_ENV + echo "MSYSTEM=MINGW64" >> $GITHUB_ENV else - choco install python2 + cygreg=registry32 + pyreg=-32 + echo "VCARCH=x86" >> $GITHUB_ENV + echo "WARCH=ia32" >> $GITHUB_ENV + echo "BITS=32" >> $GITHUB_ENV + echo "MSYSTEM=MINGW32" >> $GITHUB_ENV fi - python3_dir=$(cat "/proc/${{ matrix.cygreg }}/HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${PYTHON3_VER_DOT}${{ matrix.pyreg }}/InstallPath/@") + + echo "VCVARSALL=$(vswhere -products \* -latest -property installationPath)\\VC\\Auxiliary\\Build\\vcvarsall.bat" >> $GITHUB_ENV + if [ "${{ matrix.features }}" != "TINY" ]; then + if [ "${{ matrix.arch }}" = "x86" ]; then + choco install python2 --forcex86 + else + choco install python2 + fi + fi + python3_dir=$(cat "/proc/$cygreg/HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${PYTHON3_VER_DOT}$pyreg/InstallPath/@") echo "PYTHON3_DIR=$python3_dir" >> $GITHUB_ENV - uses: msys2/setup-msys2@v2 @@ -434,7 +433,7 @@ jobs: install: tar pacboy: >- make:p gcc:p - msystem: ${{ matrix.msystem }} + msystem: ${{ env.MSYSTEM }} release: false - name: Checkout repository from github @@ -451,7 +450,7 @@ jobs: uses: actions/cache@v3 with: path: downloads - key: ${{ runner.os }}-${{ matrix.bits }}-${{ hashFiles('urls.txt') }} + key: ${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('urls.txt') }} - name: Download dependencies shell: cmd @@ -460,14 +459,14 @@ jobs: if not exist downloads mkdir downloads echo %COL_GREEN%Download Lua%COL_RESET% - call :downloadfile %LUA${{ matrix.bits }}_URL% downloads\lua.zip + call :downloadfile %LUA${{ env.BITS }}_URL% downloads\lua.zip 7z x downloads\lua.zip -o%LUA_DIR% > nul || exit 1 echo %COL_GREEN%Download winpty%COL_RESET% call :downloadfile %WINPTY_URL% downloads\winpty.zip 7z x -y downloads\winpty.zip -oD:\winpty > nul || exit 1 - copy /Y D:\winpty\${{ matrix.warch }}\bin\winpty.dll src\winpty${{ matrix.bits }}.dll - copy /Y D:\winpty\${{ matrix.warch }}\bin\winpty-agent.exe src\ + copy /Y D:\winpty\%WARCH%\bin\winpty.dll src\winpty%BITS%.dll + copy /Y D:\winpty\%WARCH%\bin\winpty-agent.exe src\ goto :eof @@ -482,31 +481,28 @@ jobs: ) goto :eof - - name: Copy src directory to src2 - shell: cmd - run: xcopy src src2\ /E > nul - - name: Build (MSVC) if: matrix.toolchain == 'msvc' shell: cmd run: | - call "%VCVARSALL%" ${{ matrix.vcarch }} + call "%VCVARSALL%" %VCARCH% cd src + if "${{ matrix.VIMDLL }}"=="yes" ( + set GUI=yes + ) else ( + set GUI=${{ matrix.GUI }} + ) if "${{ matrix.features }}"=="HUGE" ( nmake -nologo -f Make_mvc.mak ^ FEATURES=${{ matrix.features }} ^ - GUI=yes IME=yes ICONV=yes VIMDLL=yes ^ + GUI=%GUI% IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} ^ DYNAMIC_LUA=yes LUA=%LUA_DIR% ^ DYNAMIC_PYTHON=yes PYTHON=%PYTHON_DIR% ^ DYNAMIC_PYTHON3=yes PYTHON3=%PYTHON3_DIR% ) else ( nmake -nologo -f Make_mvc.mak ^ FEATURES=${{ matrix.features }} ^ - GUI=yes IME=yes ICONV=yes VIMDLL=yes - ) - if not exist vim${{ matrix.bits }}.dll ( - echo %COL_RED%Build failure.%COL_RESET% - exit 1 + GUI=%GUI% IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} ) - name: Build (MinGW) @@ -514,10 +510,15 @@ jobs: shell: msys2 {0} run: | cd src + if [ "${{ matrix.VIMDLL }}" = "yes" ]; then + GUI=yes + else + GUI=${{ matrix.GUI }} + fi if [ "${{ matrix.features }}" = "HUGE" ]; then mingw32-make -f Make_ming.mak -j2 \ FEATURES=${{ matrix.features }} \ - GUI=yes IME=yes ICONV=yes VIMDLL=yes \ + GUI=$GUI IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} \ DYNAMIC_LUA=yes LUA=${LUA_DIR_SLASH} \ DYNAMIC_PYTHON=yes PYTHON=${PYTHON_DIR} \ DYNAMIC_PYTHON3=yes PYTHON3=${PYTHON3_DIR} \ @@ -525,17 +526,27 @@ jobs: else mingw32-make -f Make_ming.mak -j2 \ FEATURES=${{ matrix.features }} \ - GUI=yes IME=yes ICONV=yes VIMDLL=yes \ + GUI=$GUI IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} \ STATIC_STDCPLUS=yes fi - name: Check version shell: cmd run: | - PATH %LUA_DIR%;C:\msys64\${{ matrix.msystem }}\bin;%PATH%;%PYTHON3_DIR% - src\vim --version || exit 1 - src\vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit - src\vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit + PATH %LUA_DIR%;C:\msys64\%MSYSTEM%\bin;%PATH%;%PYTHON3_DIR% + if "${{ matrix.GUI }}"=="yes" ( + start /wait src\gvim -u NONE -i NONE -c "redir > version.txt | ver | q" || exit 1 + type version.txt + echo. + start /wait src\gvim -u NONE -i NONE -c "redir! > version.txt | so ci\if_ver-1.vim | q" + start /wait src\gvim -u NONE -i NONE -c "redir >> version.txt | so ci\if_ver-2.vim | q" + type version.txt + del version.txt + ) else ( + src\vim --version || exit 1 + src\vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit + src\vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit + ) #- name: Prepare Artifact # shell: cmd @@ -550,51 +561,39 @@ jobs: # name: vim${{ matrix.bits }}-${{ matrix.toolchain }} # path: ./artifacts - - name: Copy gcov data files to src2 - if: matrix.coverage - shell: msys2 {0} - run: find src -name '*.gcno' | tar -c -T - | tar -x -C src2 --strip-components 1 - - name: Test and show the result of testing gVim + if: matrix.GUI == 'yes' || matrix.VIMDLL == 'yes' shell: cmd - timeout-minutes: 20 + timeout-minutes: 15 run: | - PATH %LUA_DIR%;C:\msys64\${{ matrix.msystem }}\bin;%PATH%;%PYTHON3_DIR% - call "%VCVARSALL%" ${{ matrix.vcarch }} - - echo %COL_GREEN%Start testing Vim in background.%COL_RESET% - start cmd /c "cd src2\testdir & nmake -nologo -f Make_mvc.mak VIMPROG=..\..\src\vim > nul & echo done>done.txt" + PATH %LUA_DIR%;C:\msys64\%MSYSTEM%\bin;%PATH%;%PYTHON3_DIR% + call "%VCVARSALL%" %VCARCH% echo %COL_GREEN%Test gVim:%COL_RESET% cd src\testdir - nmake -nologo -f Make_mvc.mak VIMPROG=..\gvim || exit 1 - - - name: Show the result of testing Vim - shell: cmd - timeout-minutes: 20 - run: | - PATH %LUA_DIR%;C:\msys64\${{ matrix.msystem }}\bin;%PATH%;%PYTHON3_DIR% - call "%VCVARSALL%" ${{ matrix.vcarch }} - - echo %COL_GREEN%Wait for Vim tests to finish.%COL_RESET% - cd src2\testdir - :: Wait about 10 minutes. - for /L %%i in (1,1,60) do ( - if exist done.txt goto exitloop - timeout 10 > NUL 2>&1 - if ERRORLEVEL 1 ping -n 11 localhost > NUL + if "${{ matrix.GUI }}"=="yes" ( + nmake -nologo -f Make_mvc.mak VIMPROG=..\gvim || exit 1 + ) else ( + @rem Run only tiny tests. + nmake -nologo -f Make_mvc.mak tiny VIMPROG=..\gvim || exit 1 ) - set timeout=1 - :exitloop - echo %COL_GREEN%The result of testing Vim:%COL_RESET% - cd src2\testdir - if exist messages type messages - nmake -nologo -f Make_mvc.mak report VIMPROG=..\..\src\vim || exit 1 + - name: Test and show the result of testing Vim + if: matrix.GUI == 'no' || matrix.VIMDLL == 'yes' + shell: cmd + timeout-minutes: 15 + run: | + PATH %LUA_DIR%;C:\msys64\%MSYSTEM%\bin;%PATH%;%PYTHON3_DIR% + call "%VCVARSALL%" %VCARCH% - if "%timeout%"=="1" ( - echo %COL_RED%Timed out.%COL_RESET% - exit 1 + echo %COL_GREEN%Test Vim:%COL_RESET% + cd src\testdir + nmake -nologo -f Make_mvc.mak clean + if "${{ matrix.GUI }}"=="no" ( + nmake -nologo -f Make_mvc.mak VIMPROG=..\vim || exit 1 + ) else ( + @rem Run only tiny tests. + nmake -nologo -f Make_mvc.mak tiny VIMPROG=..\vim || exit 1 ) - name: Generate gcov files @@ -603,19 +602,10 @@ jobs: run: | cd src find . -type f -name '*.gcno' -exec gcov -pb {} + || true - cd ../src2 - find . -type f -name '*.gcno' -exec gcov -pb {} + || true - - name: Codecov (gVim) + - name: Codecov if: matrix.coverage uses: codecov/codecov-action@v3.1.0 with: directory: src - flags: windows,${{ matrix.toolchain }}-${{ matrix.arch }}-${{ matrix.features }}-gui - - - name: Codecov (Vim) - if: matrix.coverage - uses: codecov/codecov-action@v3.1.0 - with: - directory: src2 flags: windows,${{ matrix.toolchain }}-${{ matrix.arch }}-${{ matrix.features }} diff --git a/src/errors.h b/src/errors.h index 050cec768d..43baa6a1ad 100644 --- a/src/errors.h +++ b/src/errors.h @@ -2011,11 +2011,11 @@ EXTERN char e_cannot_delete_variable[] INIT(= N_("E795: Cannot delete variable")); EXTERN char e_cannot_delete_variable_str[] INIT(= N_("E795: Cannot delete variable %s")); +#endif +#ifdef MSWIN // E796 -# ifdef MSWIN EXTERN char e_writing_to_device_disabled_with_opendevice_option[] INIT(= N_("writing to device disabled with 'opendevice' option")); -# endif #endif #ifdef FEAT_SPELL EXTERN char e_spellfilemising_autocommand_deleted_buffer[] diff --git a/src/gui_w32.c b/src/gui_w32.c index 8ae0cd069b..203b8fa548 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -198,9 +198,7 @@ gui_mch_set_rendering_options(char_u *s) # ifndef __MINGW32__ # include # endif -# if defined(FEAT_TOOLBAR) || defined(FEAT_BEVAL_GUI) || defined(FEAT_GUI_TABLINE) -# include -# endif +# include # include #endif // PROTO diff --git a/src/os_win32.c b/src/os_win32.c index d936e4f087..af2622caeb 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -2834,7 +2834,11 @@ SaveConsoleTitleAndIcon(void) return; // Extract the first icon contained in the Vim executable. - if (mch_icon_load((HANDLE *)&g_hVimIcon) == FAIL || g_hVimIcon == NULL) + if ( +# ifdef FEAT_LIBCALL + mch_icon_load((HANDLE *)&g_hVimIcon) == FAIL || +# endif + g_hVimIcon == NULL) g_hVimIcon = ExtractIcon(NULL, (LPCSTR)exe_name, 0); if (g_hVimIcon != NULL) g_fCanChangeIcon = TRUE; diff --git a/src/version.c b/src/version.c index 29483f3060..cd340b5268 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 436, /**/ 435, /**/ From 71b6d3397649fed68ef587aa863fcbdf5fdb057a Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 10 Sep 2022 13:13:14 +0100 Subject: [PATCH 17/28] Update runtime files --- .github/CODEOWNERS | 19 +++- runtime/doc/builtin.txt | 2 +- runtime/doc/eval.txt | 8 +- runtime/doc/options.txt | 2 +- runtime/doc/tags | 3 + runtime/doc/tagsrch.txt | 11 +- runtime/doc/todo.txt | 23 ++-- runtime/doc/userfunc.txt | 7 +- runtime/doc/version9.txt | 6 +- runtime/doc/vim9.txt | 30 +++++- runtime/filetype.vim | 2 +- runtime/ftplugin/gitattributes.vim | 13 +++ runtime/ftplugin/gitignore.vim | 13 +++ runtime/ftplugin/jsonnet.vim | 17 +++ runtime/ftplugin/lua.vim | 38 +++---- runtime/ftplugin/lynx.vim | 29 +++++ runtime/ftplugin/sh.vim | 51 +++++---- runtime/ftplugin/vim.vim | 12 +-- runtime/ftplugin/zimbu.vim | 4 +- runtime/ftplugin/zsh.vim | 2 +- runtime/indent/json.vim | 3 + runtime/syntax/gitattributes.vim | 63 +++++++++++ runtime/syntax/gitignore.vim | 29 +++++ runtime/syntax/lua.vim | 70 +++++++------ runtime/syntax/vim.vim | 18 ++-- runtime/syntax/zsh.vim | 163 +++++++++++++++++++++++++---- 26 files changed, 498 insertions(+), 140 deletions(-) create mode 100644 runtime/ftplugin/gitattributes.vim create mode 100644 runtime/ftplugin/gitignore.vim create mode 100644 runtime/ftplugin/jsonnet.vim create mode 100644 runtime/ftplugin/lynx.vim create mode 100644 runtime/syntax/gitattributes.vim create mode 100644 runtime/syntax/gitignore.vim diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1cd351fe78..2375b35adc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -69,6 +69,10 @@ runtime/compiler/perlcritic.vim @petdance @dkearns runtime/compiler/php.vim @dkearns runtime/compiler/podchecker.vim @petdance @dkearns runtime/compiler/powershell.vim @heaths +runtime/compiler/raco.vim @benknoble +runtime/compiler/racomake.vim @benknoble +runtime/compiler/racosetup.vim @benknoble +runtime/compiler/racotest.vim @benknoble runtime/compiler/rake.vim @tpope @dkearns runtime/compiler/rhino.vim @dkearns runtime/compiler/rspec.vim @tpope @dkearns @@ -111,6 +115,7 @@ runtime/ftplugin/cucumber.vim @tpope runtime/ftplugin/desktop.vim @e-kwsm runtime/ftplugin/dosbatch.vim @mrdubya runtime/ftplugin/eiffel.vim @dkearns +runtime/ftplugin/elixir.vim @mhanberg runtime/ftplugin/expect.vim @dkearns runtime/ftplugin/erlang.vim @hcs42 runtime/ftplugin/eruby.vim @tpope @dkearns @@ -123,8 +128,10 @@ runtime/ftplugin/gdb.vim @xeyownt runtime/ftplugin/gdscript.vim @habamax runtime/ftplugin/gdshader.vim @habamax runtime/ftplugin/git.vim @tpope +runtime/ftplugin/gitattributes.vim @ObserverOfTime runtime/ftplugin/gitcommit.vim @tpope runtime/ftplugin/gitconfig.vim @tpope +runtime/ftplugin/gitignore.vim @ObserverOfTime runtime/ftplugin/gitrebase.vim @tpope runtime/ftplugin/gitsendemail.vim @tpope runtime/ftplugin/go.vim @dbarnett @@ -135,6 +142,7 @@ runtime/ftplugin/html.vim @dkearns runtime/ftplugin/i3config.vim @hiqua runtime/ftplugin/icon.vim @dkearns runtime/ftplugin/indent.vim @dkearns +runtime/ftplugin/j.vim @glts runtime/ftplugin/javascript.vim @dkearns runtime/ftplugin/javascriptreact.vim @dkearns runtime/ftplugin/jsonc.vim @izhakjakov @@ -143,6 +151,7 @@ runtime/ftplugin/kconfig.vim @chrisbra runtime/ftplugin/less.vim @genoma runtime/ftplugin/liquid.vim @tpope runtime/ftplugin/lua.vim @dkearns +runtime/ftplugin/lynx.vim @dkearns runtime/ftplugin/m3build.vim @dkearns runtime/ftplugin/m3quake.vim @dkearns runtime/ftplugin/markdown.vim @tpope @@ -164,6 +173,7 @@ runtime/ftplugin/ps1xml.vim @heaths runtime/ftplugin/python.vim @tpict runtime/ftplugin/qb64.vim @dkearns runtime/ftplugin/r.vim @jalvesaq +runtime/ftplugin/racket.vim @benknoble runtime/ftplugin/rhelp.vim @jalvesaq runtime/ftplugin/rmd.vim @jalvesaq runtime/ftplugin/rnoweb.vim @jalvesaq @@ -175,6 +185,7 @@ runtime/ftplugin/sass.vim @tpope runtime/ftplugin/scala.vim @derekwyatt runtime/ftplugin/scss.vim @tpope runtime/ftplugin/sdoc.vim @gpanders +runtime/ftplugin/sh.vim @dkearns runtime/ftplugin/solution.vim @dkearns runtime/ftplugin/spec.vim @ignatenkobrain runtime/ftplugin/swayconfig.vim @jamespeapen @@ -219,6 +230,7 @@ runtime/indent/gitolite.vim @sitaramc runtime/indent/go.vim @dbarnett runtime/indent/haml.vim @tpope runtime/indent/idlang.vim @dkearns +runtime/indent/j.vim @glts runtime/indent/java.vim @xuhdev runtime/indent/javascript.vim @bounceme runtime/indent/json.vim @elzr @@ -240,6 +252,7 @@ runtime/indent/prolog.vim @dkearns runtime/indent/ps1.vim @heaths runtime/indent/qb64.vim @dkearns runtime/indent/r.vim @jalvesaq +runtime/indent/racket.vim @benknoble runtime/indent/readline.vim @dkearns runtime/indent/rhelp.vim @jalvesaq runtime/indent/rmd.vim @jalvesaq @@ -321,8 +334,10 @@ runtime/syntax/gdresource.vim @habamax runtime/syntax/gdscript.vim @habamax runtime/syntax/gdshader.vim @habamax runtime/syntax/git.vim @tpope +runtime/syntax/gitattributes.vim @ObserverOfTime runtime/syntax/gitcommit.vim @tpope runtime/syntax/gitconfig.vim @tpope +runtime/syntax/gitignore.vim @ObserverOfTime runtime/syntax/gitolite.vim @sitaramc runtime/syntax/gitrebase.vim @tpope runtime/syntax/go.vim @bhcleek @@ -336,6 +351,7 @@ runtime/syntax/html.vim @dkearns runtime/syntax/i3config.vim @hiqua runtime/syntax/icon.vim @dkearns runtime/syntax/indent.vim @dkearns +runtime/syntax/j.vim @glts runtime/syntax/jargon.vim @h3xx runtime/syntax/java.vim @fleiner runtime/syntax/jsonc.vim @izhakjakov @@ -377,6 +393,7 @@ runtime/syntax/ps1xml.vim @heaths runtime/syntax/psl.vim @danielkho runtime/syntax/qb64.vim @dkearns runtime/syntax/r.vim @jalvesaq +runtime/syntax/racket.vim @benknoble runtime/syntax/raml.vim @in3d runtime/syntax/ratpoison.vim @trapd00r runtime/syntax/rc.vim @chrisbra @@ -404,7 +421,7 @@ runtime/syntax/sshconfig.vim @Jakuje runtime/syntax/sshdconfig.vim @Jakuje runtime/syntax/sudoers.vim @e-kwsm runtime/syntax/svn.vim @hdima -runtime/syntax/swayconfig.vim @jamespeapen +runtime/syntax/swayconfig.vim @jamespeapen runtime/syntax/systemverilog.vim @Kocha runtime/syntax/tags.vim @cecamp runtime/syntax/tap.vim @petdance diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 01263402fa..3448ed5855 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -1,4 +1,4 @@ -*builtin.txt* For Vim version 9.0. Last change: 2022 Jun 27 +*builtin.txt* For Vim version 9.0. Last change: 2022 Sep 10 VIM REFERENCE MANUAL by Bram Moolenaar diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 741f70ad64..e99e9baa0a 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 9.0. Last change: 2022 Jun 17 +*eval.txt* For Vim version 9.0. Last change: 2022 Sep 09 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1718,6 +1718,9 @@ Recommendation: don't do this. Notice how execute() is used to execute an Ex command. That's ugly though. In Vim9 script you can use a command block, see |inline-function|. +Although you can use the loop variable of a `for` command, it must still exist +when the closure is called, otherwise you get an error. *E1302* + Lambda expressions have internal names like '42'. If you get an error for a lambda expression, you can find what it is with the following command: > :function 42 @@ -3397,7 +3400,8 @@ text... it will show for three seconds and avoid a |hit-enter| prompt. If you want to hide it before that, press Esc in Normal mode (when it would - otherwise beep). + otherwise beep). If it disappears too soon you can + use `:messages` to see the text. The message window is available when Vim was compiled with the +timer and the +popupwin features. diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 1b9ae38db6..b60abc271d 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 9.0. Last change: 2022 Jun 27 +*options.txt* For Vim version 9.0. Last change: 2022 Sep 09 VIM REFERENCE MANUAL by Bram Moolenaar diff --git a/runtime/doc/tags b/runtime/doc/tags index 9ff4218366..b38f1cc516 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -4332,7 +4332,10 @@ E1295 textprop.txt /*E1295* E1296 textprop.txt /*E1296* E1297 vim9.txt /*E1297* E1298 vim9.txt /*E1298* +E1299 tagsrch.txt /*E1299* E13 message.txt /*E13* +E1300 userfunc.txt /*E1300* +E1302 eval.txt /*E1302* E131 userfunc.txt /*E131* E132 userfunc.txt /*E132* E133 userfunc.txt /*E133* diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt index 4c49e44d02..e7a522feba 100644 --- a/runtime/doc/tagsrch.txt +++ b/runtime/doc/tagsrch.txt @@ -889,13 +889,16 @@ like |CTRL-]|. The function used for generating the taglist is specified by setting the 'tagfunc' option. The function will be called with three arguments: - a:pattern The tag identifier or pattern used during the tag search. - a:flags String containing flags to control the function behavior. - a:info Dict containing the following entries: + pattern The tag identifier or pattern used during the tag search. + flags String containing flags to control the function behavior. + info Dict containing the following entries: buf_ffname Full filename which can be used for priority. user_data Custom data String, if stored in the tag stack previously by tagfunc. +Note that in a legacy function "a:" needs to be prepended to the argument name +when using it. + Currently up to three flags may be passed to the tag function: 'c' The function was invoked by a normal command being processed (mnemonic: the tag function may use the context around the @@ -931,6 +934,8 @@ If the function returns |v:null| instead of a List, a standard tag lookup will be performed instead. It is not allowed to change the tagstack from inside 'tagfunc'. *E986* +It is not allowed to close a window or change window from inside 'tagfunc'. +*E1299* The following is a hypothetical example of a function used for 'tagfunc'. It uses the output of |taglist()| to generate the result: a list of tags in the diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 71b8b0f07c..b22c2564f2 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 9.0. Last change: 2022 Jun 27 +*todo.txt* For Vim version 9.0. Last change: 2022 Sep 10 VIM REFERENCE MANUAL by Bram Moolenaar @@ -38,17 +38,14 @@ browser use: https://github.com/vim/vim/issues/1234 *known-bugs* -------------------- Known bugs and current work ----------------------- +Use :defer command: + - Use "D" flag of writefile() and mkdir() in tests. + (testdir/test_c*.vim done) + When using :echomessage do use msg_row and msg_col, but save and restore. -How to test any failure? - -Improve :defer command: - - Use "D" flag of writefile() in tests. - - test "defer func()->funcouter()" fails (or use "funcouter") - - test "defer func().arg" fails - - test partial fails - - check arguments at :defer command - - Also when function does "qa!" or "cq"? +How to test any failure? If nothing fails perhaps it's OK alrady. +Drop Windows XP? #11089 Further Vim9 improvements, possibly after launch: - Use Vim9 for more runtime files. @@ -277,6 +274,7 @@ Adding "10" to 'spellsuggest' causes spell suggestions to become very slow. Also, z= in German on a long word can take a very long time, but CTRL-C to interrupt does not work. Where to add ui_breakcheck()? New English spell files also have very slow suggestions. +French spell files don't work correctly. #4916 Make "g>" and "g<" in Visual mode move the text right or left. Also for a block selection. #8558 @@ -2648,6 +2646,11 @@ Better 'rightleft' or BIDI support: Spell checking: +- List of common misspellings in English: + https://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines + German: + https://de.wikipedia.org/wiki/Wikipedia:Liste_von_Tippfehlern/F%C3%BCr_Maschinen + There are other languages. - [s does not find missing capital at start of the line. #10838 Probably because the dot at the end of the previous line isn't seen. - When 'cursorline' is set and the first word should have SpellCap diff --git a/runtime/doc/userfunc.txt b/runtime/doc/userfunc.txt index f6377009b8..24e3fd7daf 100644 --- a/runtime/doc/userfunc.txt +++ b/runtime/doc/userfunc.txt @@ -1,4 +1,4 @@ -*userfunc.txt* For Vim version 9.0. Last change: 2022 Jun 17 +*userfunc.txt* For Vim version 9.0. Last change: 2022 Sep 09 VIM REFERENCE MANUAL by Bram Moolenaar @@ -23,7 +23,7 @@ commands can be executed with the |:normal| command. The function name must start with an uppercase letter, to avoid confusion with builtin functions. To prevent from using the same name in different scripts -make them script-local. If you do use a global function the avoid obvious, +make them script-local. If you do use a global function then avoid obvious, short names. A good habit is to start the function name with the name of the script, e.g., "HTMLcolor()". @@ -427,7 +427,8 @@ GetArg()->TheFunc()` does not work, it may work in a later version. Errors are reported but do not cause aborting execution of deferred functions. -No range is accepted. +No range is accepted. The function can be a partial with extra arguments, but +not with a dictionary. *E1300* ============================================================================== diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt index 4e6b1cbf13..9ec13872ab 100644 --- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -72,7 +72,7 @@ Command line completion in a popup menu ~ Before there was the 'wildmenu' option, which uses the space of one line above the statusline to show matches. Only a few matches fit there. -Now a popup menu can be used by setting "wildoptions' to "pum". This allows +Now a popup menu can be used by setting 'wildoptions' to "pum". This allows for showing many more matches. This requires redrawing more of the display, but since computers are fast enough that is not a problem. @@ -336,7 +336,7 @@ Hide cursor when sleeping using |:sleep!|. Add "multispace" to 'listchars' to show two or more spaces no matter where they appear. Add "leadmultispace" to 'listchars' to show two or more leading spaces. Add "lead" to 'listchars' to set the character used to show leading -spaces. Support specifying a character using the hexdecimal notation in +spaces. Support specifying a character using the hexadecimal notation in 'listchars' (\x, \u and \U). Make 'listchars', 'virtualedit' and 'thesaurusfunc' global-local options. @@ -28248,7 +28248,7 @@ Files: runtime/doc/repeat.txt, src/scriptfile.c, src/vim9script.c, src/proto/vim9script.pro, src/testdir/test_source.vim Patch 8.2.4608 -Problem: getcompletion() does not work properly when 'wildoptions +Problem: getcompletion() does not work properly when 'wildoptions' contains "fuzzy". Solution: Do not use addstar(). (Yegappan Lakshmanan, closes #9992, closes #9986) diff --git a/runtime/doc/vim9.txt b/runtime/doc/vim9.txt index aba0f0051e..ce9cbdf3b0 100644 --- a/runtime/doc/vim9.txt +++ b/runtime/doc/vim9.txt @@ -1,4 +1,4 @@ -*vim9.txt* For Vim version 9.0. Last change: 2022 Jun 25 +*vim9.txt* For Vim version 9.0. Last change: 2022 Sep 10 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1311,7 +1311,7 @@ Make sure to define the breakpoint before compiling the outer function. The "inloop" variable will exist only once, all closures put in the list refer to the same instance, which in the end will have the value 4. This is efficient, also when looping many times. If you do want a separate context -for each closure call a function to define it: > +for each closure, call a function to define it: > def GetClosure(i: number): func var infunc = i return () => infunc @@ -1327,6 +1327,30 @@ for each closure call a function to define it: > In some situations, especially when calling a Vim9 closure from legacy context, the evaluation will fail. *E1248* +Note that at the script level the loop variable will be invalid after the +loop, also when used in a closure that is called later, e.g. with a timer. +This will generate error |E1302|: > + for n in range(4) + timer_start(500 * n, (_) => { + echowin n + }) + endfor + +You need to create a closure to store the current value of "n", so that it is +evaluated at the time the closure is created: > + def GetClosure(nr: number): func + return (_) => { + echowindow nr + } + enddef + + for n in range(4) + timer_start(500 * n, GetClosure(n)) + endfor + +Using `echowindow` is useful in a timer, the messages go into a popup and will +not interfere with what the user is doing when it triggers. + Converting a function from legacy to Vim9 ~ *convert_legacy_function_to_vim9* @@ -1618,7 +1642,7 @@ type, it can not be used in Vim9 script. *E1211* *E1217* *E1218* *E1219* *E1220* *E1221* *E1222* *E1223* *E1224* *E1225* *E1226* *E1227* *E1228* *E1238* *E1250* *E1251* *E1252* *E1253* - *E1256* *E1297* *E1298* + *E1256* *E1297* *E1298* *E1301* Types are checked for most builtin functions to make it easier to spot mistakes. diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 0223402a4b..d88f0256b1 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1,7 +1,7 @@ " Vim support file to detect file types " " Maintainer: Bram Moolenaar -" Last Change: 2022 Jul 5 +" Last Change: 2022 Sep 09 " Listen very carefully, I will say this only once if exists("did_load_filetypes") diff --git a/runtime/ftplugin/gitattributes.vim b/runtime/ftplugin/gitattributes.vim new file mode 100644 index 0000000000..2025d009d2 --- /dev/null +++ b/runtime/ftplugin/gitattributes.vim @@ -0,0 +1,13 @@ +" Vim filetype plugin +" Language: git attributes +" Maintainer: ObserverOfTime +" Last Change: 2022 Sep 08 + +if exists('b:did_ftplugin') + finish +endif +let b:did_ftplugin = 1 + +setl comments=:# commentstring=#\ %s + +let b:undo_ftplugin = 'setl com< cms<' diff --git a/runtime/ftplugin/gitignore.vim b/runtime/ftplugin/gitignore.vim new file mode 100644 index 0000000000..3502dd2717 --- /dev/null +++ b/runtime/ftplugin/gitignore.vim @@ -0,0 +1,13 @@ +" Vim filetype plugin +" Language: git ignore +" Maintainer: ObserverOfTime +" Last Change: 2022 Sep 10 + +if exists('b:did_ftplugin') + finish +endif +let b:did_ftplugin = 1 + +setl comments=:# commentstring=#\ %s + +let b:undo_ftplugin = 'setl com< cms<' diff --git a/runtime/ftplugin/jsonnet.vim b/runtime/ftplugin/jsonnet.vim new file mode 100644 index 0000000000..1e621e1867 --- /dev/null +++ b/runtime/ftplugin/jsonnet.vim @@ -0,0 +1,17 @@ +" Vim filetype plugin +" Language: Jsonnet +" Maintainer: Cezary Drożak +" URL: https://github.com/google/vim-jsonnet +" Last Change: 2022-09-08 + +" Only do this when not done yet for this buffer +if exists("b:did_ftplugin") + finish +endif + +" Don't load another plugin for this buffer +let b:did_ftplugin = 1 + +setlocal commentstring=//\ %s + +let b:undo_ftplugin = "setlocal commentstring<" diff --git a/runtime/ftplugin/lua.vim b/runtime/ftplugin/lua.vim index 2604257594..aaa61f71d9 100644 --- a/runtime/ftplugin/lua.vim +++ b/runtime/ftplugin/lua.vim @@ -1,46 +1,46 @@ " Vim filetype plugin file. -" Language: Lua +" Language: Lua " Maintainer: Doug Kearns " Previous Maintainer: Max Ischenko -" Last Change: 2021 Nov 15 +" Contributor: Dorai Sitaram +" Last Change: 2022 Sep 05 -" Only do this when not done yet for this buffer if exists("b:did_ftplugin") finish endif - -" Don't load another plugin for this buffer let b:did_ftplugin = 1 let s:cpo_save = &cpo set cpo&vim -" Set 'formatoptions' to break comment lines but not other lines, and insert -" the comment leader when hitting or using "o". +setlocal comments=:-- +setlocal commentstring=--\ %s setlocal formatoptions-=t formatoptions+=croql -setlocal comments=:-- -setlocal commentstring=--%s +let &l:define = '\:' . - \ '\<\%(return\|else\|elseif\)\>:' . - \ '\,' . - \ '\:\,' . - \ '\%(--\)\=\[\(=*\)\[:]\1]' - let b:undo_ftplugin .= " | unlet! b:match_words b:match_ignorecase" + \ '\<\%(do\|function\|if\)\>:' .. + \ '\<\%(return\|else\|elseif\)\>:' .. + \ '\,' .. + \ '\:\,' .. + \ '\%(--\)\=\[\(=*\)\[:]\1]' + let b:undo_ftplugin ..= " | unlet! b:match_words b:match_ignorecase" endif if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") - let b:browsefilter = "Lua Source Files (*.lua)\t*.lua\n" . - \ "All Files (*.*)\t*.*\n" - let b:undo_ftplugin .= " | unlet! b:browsefilter" + let b:browsefilter = "Lua Source Files (*.lua)\t*.lua\n" .. + \ "All Files (*.*)\t*.*\n" + let b:undo_ftplugin ..= " | unlet! b:browsefilter" endif let &cpo = s:cpo_save unlet s:cpo_save + +" vim: nowrap sw=2 sts=2 ts=8 noet: diff --git a/runtime/ftplugin/lynx.vim b/runtime/ftplugin/lynx.vim new file mode 100644 index 0000000000..b76c69f0ae --- /dev/null +++ b/runtime/ftplugin/lynx.vim @@ -0,0 +1,29 @@ +" Vim filetype plugin file +" Language: Lynx Web Browser Configuration +" Maintainer: Doug Kearns +" Last Change: 2022 Sep 09 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let s:cpo_save = &cpo +set cpo&vim + +setlocal comments=:# +setlocal commentstring=#\ %s +setlocal formatoptions-=t formatoptions+=croql + +let b:undo_ftplugin = "setl cms< com< fo<" + +if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") + let b:browsefilter = "Lynx Configuration Files (lynx.cfg .lynxrc)\tlynx.cfg;.lynxrc\n" .. + \ "All Files (*.*)\t*.*\n" + let b:undo_ftplugin ..= " | unlet! b:browsefilter" +endif + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: nowrap sw=2 sts=2 ts=8 noet: diff --git a/runtime/ftplugin/sh.vim b/runtime/ftplugin/sh.vim index 93a46f63e2..b6fdb8f3e2 100644 --- a/runtime/ftplugin/sh.vim +++ b/runtime/ftplugin/sh.vim @@ -1,12 +1,12 @@ " Vim filetype plugin file -" Language: sh -" -" This runtime file is looking for a new maintainer. -" -" Former maintainer: Dan Sharp -" Last Changed: 20 Jan 2009 +" Language: sh +" Maintainer: Doug Kearns +" Previous Maintainer: Dan Sharp +" Last Change: 2022 Sep 07 -if exists("b:did_ftplugin") | finish | endif +if exists("b:did_ftplugin") + finish +endif let b:did_ftplugin = 1 " Make sure the continuation lines below do not cause problems in @@ -14,28 +14,35 @@ let b:did_ftplugin = 1 let s:save_cpo = &cpo set cpo-=C -setlocal commentstring=#%s +setlocal comments=:# +setlocal commentstring=#\ %s +setlocal formatoptions-=t formatoptions+=croql + +let b:undo_ftplugin = "setl com< cms< fo<" " Shell: thanks to Johannes Zellner -if exists("loaded_matchit") - let s:sol = '\%(;\s*\|^\s*\)\@<=' " start of line - let b:match_words = - \ s:sol.'if\>:' . s:sol.'elif\>:' . s:sol.'else\>:' . s:sol. 'fi\>,' . - \ s:sol.'\%(for\|while\)\>:' . s:sol. 'done\>,' . - \ s:sol.'case\>:' . s:sol. 'esac\>' +if exists("loaded_matchit") && !exists("b:match_words") + let b:match_ignorecase = 0 + let s:sol = '\%(;\s*\|^\s*\)\@<=' " start of line + let b:match_words = + \ s:sol .. 'if\>:' .. s:sol.'elif\>:' .. s:sol.'else\>:' .. s:sol .. 'fi\>,' .. + \ s:sol .. '\%(for\|while\)\>:' .. s:sol .. 'done\>,' .. + \ s:sol .. 'case\>:' .. s:sol .. 'esac\>' + unlet s:sol + let b:undo_ftplugin ..= " | unlet! b:match_ignorecase b:match_words" endif " Change the :browse e filter to primarily show shell-related files. -if has("gui_win32") - let b:browsefilter="Bourne Shell Scripts (*.sh)\t*.sh\n" . - \ "Korn Shell Scripts (*.ksh)\t*.ksh\n" . - \ "Bash Shell Scripts (*.bash)\t*.bash\n" . - \ "All Files (*.*)\t*.*\n" +if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") + let b:browsefilter = "Bourne Shell Scripts (*.sh)\t*.sh\n" .. + \ "Korn Shell Scripts (*.ksh)\t*.ksh\n" .. + \ "Bash Shell Scripts (*.bash)\t*.bash\n" .. + \ "All Files (*.*)\t*.*\n" + let b:undo_ftplugin ..= " | unlet! b:browsefilter" endif -" Undo the stuff we changed. -let b:undo_ftplugin = "setlocal cms< | unlet! b:browsefilter b:match_words" - " Restore the saved compatibility options. let &cpo = s:save_cpo unlet s:save_cpo + +" vim: nowrap sw=2 sts=2 ts=8 noet: diff --git a/runtime/ftplugin/vim.vim b/runtime/ftplugin/vim.vim index 772bfa0429..60934d731d 100644 --- a/runtime/ftplugin/vim.vim +++ b/runtime/ftplugin/vim.vim @@ -1,7 +1,7 @@ " Vim filetype plugin " Language: Vim " Maintainer: Bram Moolenaar -" Last Change: 2022 Aug 4 +" Last Change: 2022 Sep 09 " Only do this when not done yet for this buffer if exists("b:did_ftplugin") @@ -48,17 +48,17 @@ setlocal isk+=# " Use :help to lookup the keyword under the cursor with K. setlocal keywordprg=:help +" Comments starts with # in Vim9 script. We have to guess which one to use. if "\n" .. getline(1, 10)->join("\n") =~# '\n\s*vim9\%[script]\>' - " Set 'comments' to format dashed lists in comments - setlocal com=sO:#\ -,mO:#\ \ ,eO:##,:# - " Comments starts with # in Vim9 script setlocal commentstring=#%s else - setlocal com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" - " Comments starts with a double quote in legacy script setlocal commentstring=\"%s endif +" Set 'comments' to format dashed lists in comments, both in Vim9 and legacy +" script. +setlocal com=sO:#\ -,mO:#\ \ ,eO:##,:#,sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" + " set 'include' to recognize import commands setlocal include=\\v^\\s*import\\s*(autoload)? diff --git a/runtime/ftplugin/zimbu.vim b/runtime/ftplugin/zimbu.vim index c966498c90..9d9fa6f406 100644 --- a/runtime/ftplugin/zimbu.vim +++ b/runtime/ftplugin/zimbu.vim @@ -1,7 +1,7 @@ " Vim filetype plugin file " Language: Zimbu " Maintainer: Bram Moolenaar -" Last Change: 2021 Nov 12 +" Last Change: 2022 Sep 07 " Only do this when not done yet for this buffer if exists("b:did_ftplugin") @@ -28,7 +28,7 @@ endif " Set 'comments' to format dashed lists in comments. " And to keep Zudocu comment characters. -setlocal comments=sO:#\ -,mO:#\ \ ,:#=,:#-,:#%,:# +setlocal comments=sO:#\ -,mO:#\ \ ,exO:#/,s:/*,m:\ ,ex:*/,:#=,:#-,:#%,:# setlocal errorformat^=%f\ line\ %l\ col\ %c:\ %m,ERROR:\ %m diff --git a/runtime/ftplugin/zsh.vim b/runtime/ftplugin/zsh.vim index 34410f1c62..0ca8077305 100644 --- a/runtime/ftplugin/zsh.vim +++ b/runtime/ftplugin/zsh.vim @@ -2,7 +2,7 @@ " Language: Zsh shell script " Maintainer: Christian Brabandt " Previous Maintainer: Nikolai Weibull -" Latest Revision: 2020-09-01 +" Latest Revision: 2021-04-03 " License: Vim (see :h license) " Repository: https://github.com/chrisbra/vim-zsh diff --git a/runtime/indent/json.vim b/runtime/indent/json.vim index 09c7d7a85a..510f7e8f42 100644 --- a/runtime/indent/json.vim +++ b/runtime/indent/json.vim @@ -3,6 +3,7 @@ " Maintainer: Eli Parra https://github.com/elzr/vim-json " Last Change: 2020 Aug 30 " https://github.com/jakar/vim-json/commit/20b650e22aa750c4ab6a66aa646bdd95d7cd548a#diff-e81fc111b2052e306d126bd9989f7b7c +" 2022 Sep 07: b:undo_indent added by Doug Kearns " Original Author: Rogerz Zhang http://github.com/rogerz/vim-json " Acknowledgement: Based off of vim-javascript maintained by Darrick Wiebe " http://www.vim.org/scripts/script.php?script_id=2765 @@ -22,6 +23,8 @@ setlocal nosmartindent setlocal indentexpr=GetJSONIndent(v:lnum) setlocal indentkeys=0{,0},0),0[,0],!^F,o,O,e +let b:undo_indent = "setl inde< indk< si<" + " Only define the function once. if exists("*GetJSONIndent") finish diff --git a/runtime/syntax/gitattributes.vim b/runtime/syntax/gitattributes.vim new file mode 100644 index 0000000000..b6d997f45d --- /dev/null +++ b/runtime/syntax/gitattributes.vim @@ -0,0 +1,63 @@ +" Vim syntax file +" Language: git attributes +" Maintainer: ObserverOfTime +" Filenames: .gitattributes, *.git/info/attributes +" Last Change: 2022 Sep 09 + +if exists('b:current_syntax') + finish +endif + +let s:cpo_save = &cpoptions +set cpoptions&vim + +" Comment +syn keyword gitattributesTodo contained TODO FIXME XXX +syn match gitattributesComment /^\s*#.*/ contains=gitattributesTodo + +" Pattern +syn match gitattributesPattern /^\s*#\@!\(".\+"\|\S\+\)/ skipwhite + \ nextgroup=gitattributesAttrPrefixed,gitattributesAttrAssigned skipwhite + \ contains=gitattributesGlob,gitattributesRange,gitattributesSeparator +syn match gitattributesGlob /\\\@1 +" Filenames: .gitignore, *.git/info/exclude +" Last Change: 2022 Sep 10 + +if exists('b:current_syntax') + finish +endif + +" Comment +syn keyword gitignoreTodo contained TODO FIXME XXX +syn match gitignoreComment /^#.*/ contains=gitignoreTodo + +" Pattern +syn match gitignorePattern /^#\@!.*$/ contains=gitignoreNegation,gitignoreGlob,gitignoreRange,gitignoreSeparator +syn match gitignoreNegation /^!/ contained +syn match gitignoreGlob /\\\@1 -" First Author: Carlos Augusto Teixeira Mendes -" Last Change: 2022 Mar 31 -" Options: lua_version = 4 or 5 -" lua_subversion = 0 (4.0, 5.0) or 1 (5.1) or 2 (5.2) -" default 5.2 +" Language: Lua 4.0, Lua 5.0, Lua 5.1 and Lua 5.2 +" Maintainer: Marcus Aurelius Farias +" First Author: Carlos Augusto Teixeira Mendes +" Last Change: 2022 Mar 31 +" Options: lua_version = 4 or 5 +" lua_subversion = 0 (4.0, 5.0) or 1 (5.1) or 2 (5.2) +" default 5.2 " quit when a syntax file was already loaded if exists("b:current_syntax") @@ -33,11 +33,11 @@ syn sync minlines=100 syn keyword luaTodo contained TODO FIXME XXX syn match luaComment "--.*$" contains=luaTodo,@Spell if lua_version == 5 && lua_subversion == 0 - syn region luaComment matchgroup=luaComment start="--\[\[" end="\]\]" contains=luaTodo,luaInnerComment,@Spell + syn region luaComment matchgroup=luaCommentDelimiter start="--\[\[" end="\]\]" contains=luaTodo,luaInnerComment,@Spell syn region luaInnerComment contained transparent start="\[\[" end="\]\]" elseif lua_version > 5 || (lua_version == 5 && lua_subversion >= 1) " Comments in Lua 5.1: --[[ ... ]], [=[ ... ]=], [===[ ... ]===], etc. - syn region luaComment matchgroup=luaComment start="--\[\z(=*\)\[" end="\]\z1\]" contains=luaTodo,@Spell + syn region luaComment matchgroup=luaCommentDelimiter start="--\[\z(=*\)\[" end="\]\z1\]" contains=luaTodo,@Spell endif " First line may start with #! @@ -99,18 +99,18 @@ if lua_version < 5 elseif lua_version == 5 if lua_subversion == 0 syn match luaSpecial contained #\\[\\abfnrtv'"[\]]\|\\[[:digit:]]\{,3}# - syn region luaString2 matchgroup=luaString start=+\[\[+ end=+\]\]+ contains=luaString2,@Spell + syn region luaString2 matchgroup=luaStringDelimiter start=+\[\[+ end=+\]\]+ contains=luaString2,@Spell else if lua_subversion == 1 syn match luaSpecial contained #\\[\\abfnrtv'"]\|\\[[:digit:]]\{,3}# else " Lua 5.2 syn match luaSpecial contained #\\[\\abfnrtvz'"]\|\\x[[:xdigit:]]\{2}\|\\[[:digit:]]\{,3}# endif - syn region luaString2 matchgroup=luaString start="\[\z(=*\)\[" end="\]\z1\]" contains=@Spell + syn region luaString2 matchgroup=luaStringDelimiter start="\[\z(=*\)\[" end="\]\z1\]" contains=@Spell endif endif -syn region luaString start=+'+ end=+'+ skip=+\\\\\|\\'+ contains=luaSpecial,@Spell -syn region luaString start=+"+ end=+"+ skip=+\\\\\|\\"+ contains=luaSpecial,@Spell +syn region luaString matchgroup=luaStringDelimiter start=+'+ end=+'+ skip=+\\\\\|\\'+ contains=luaSpecial,@Spell +syn region luaString matchgroup=luaStringDelimiter start=+"+ end=+"+ skip=+\\\\\|\\"+ contains=luaSpecial,@Spell " integer number syn match luaNumber "\<\d\+\>" @@ -333,27 +333,29 @@ endif " Define the default highlighting. " Only when an item doesn't have highlighting yet -hi def link luaStatement Statement -hi def link luaRepeat Repeat -hi def link luaFor Repeat -hi def link luaString String -hi def link luaString2 String -hi def link luaNumber Number -hi def link luaOperator Operator -hi def link luaIn Operator -hi def link luaConstant Constant -hi def link luaCond Conditional -hi def link luaElse Conditional -hi def link luaFunction Function -hi def link luaComment Comment -hi def link luaTodo Todo -hi def link luaTable Structure -hi def link luaError Error -hi def link luaParenError Error -hi def link luaBraceError Error -hi def link luaSpecial SpecialChar -hi def link luaFunc Identifier -hi def link luaLabel Label +hi def link luaStatement Statement +hi def link luaRepeat Repeat +hi def link luaFor Repeat +hi def link luaString String +hi def link luaString2 String +hi def link luaStringDelimiter luaString +hi def link luaNumber Number +hi def link luaOperator Operator +hi def link luaIn Operator +hi def link luaConstant Constant +hi def link luaCond Conditional +hi def link luaElse Conditional +hi def link luaFunction Function +hi def link luaComment Comment +hi def link luaCommentDelimiter luaComment +hi def link luaTodo Todo +hi def link luaTable Structure +hi def link luaError Error +hi def link luaParenError Error +hi def link luaBraceError Error +hi def link luaSpecial SpecialChar +hi def link luaFunc Identifier +hi def link luaLabel Label let b:current_syntax = "lua" diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim index 694b3a7d95..f00e448234 100644 --- a/runtime/syntax/vim.vim +++ b/runtime/syntax/vim.vim @@ -1,8 +1,8 @@ " Vim syntax file " Language: Vim 9.0 script " Maintainer: Charles E. Campbell -" Last Change: September 03, 2022 -" Version: 9.0-03 +" Last Change: September 09, 2022 +" Version: 9.0-04 " URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_VIM " Automatically generated keyword lists: {{{1 @@ -19,13 +19,13 @@ syn keyword vimTodo contained COMBAK FIXME TODO XXX syn cluster vimCommentGroup contains=vimTodo,@Spell " regular vim commands {{{2 -syn keyword vimCommand contained a ar[gs] argl[ocal] ba[ll] bl[ast] brea[k] buffers ca caf[ter] cbo[ttom] cex[pr] cgete[xpr] cl[ist] cn[ext] colo[rscheme] cons[t] cs d[elete] delel delf[unction] dif[fupdate] difft[his] dli[st] ds[earch] echoc[onsole] elsei[f] endf[unction] enum exu[sage] fin[d] foldc[lose] go[to] ha[rdcopy] hid[e] if in iuna[bbrev] keepalt la[st] lan[guage] lbo[ttom] ld[o] lfdo lgrepa[dd] lma lo[adview] lop[en] lua m[ove] mes[sages] mod[e] nbs[tart] nor omapc[lear] packl[oadall] popu[p] profd[el] ptf[irst] pts[elect] py3f[ile] pyx r[ead] redrawt[abline] ri[ght] rundo sIl sal[l] sbf[irst] sc scp se[t] sg sgn sie sip sme snoremenu spelli[nfo] spr[evious] sri star[tinsert] sts[elect] sus[pend] syncbind tabN[ext] tabl[ast] tabr[ewind] tcld[o] tj[ump] tlu tno[remap] tu[nmenu] undol[ist] v vie[w] vne[w] win[size] wq xmapc[lear] xr[estore] -syn keyword vimCommand contained ab arga[dd] argu[ment] bad[d] bm[odified] breaka[dd] bun[load] cabc[lear] cal[l] cc cf[ile] changes cla[st] cnew[er] com cope[n] cscope debug delep dell diffg[et] dig[raphs] do dsp[lit] echoe[rr] em[enu] endfo[r] eval f[ile] fina[lly] foldd[oopen] gr[ep] helpc[lose] his[tory] ij[ump] inor j[oin] keepj[umps] lab[ove] lat lc[d] le[ft] lfir[st] lh[elpgrep] lmak[e] loadk lp[revious] luado ma[rk] mk[exrc] mz[scheme] new nore on[ly] pc[lose] pp[op] promptf[ind] ptj[ump] pu[t] py[thon] pyxdo rec[over] reg[isters] rightb[elow] rv[iminfo] sIn san[dbox] sbl[ast] scI scr[iptnames] setf[iletype] sgI sgp sig sir smenu so[urce] spellr[are] sr srl startg[replace] substitutepattern sv[iew] syntime tabc[lose] tabm[ove] tabs tclf[ile] tl[ast] tlunmenu to[pleft] tunma[p] unh[ide] var vim9[cmd] vs[plit] winc[md] wqa[ll] xme xunme -syn keyword vimCommand contained abc[lear] argd[elete] as[cii] balt bn[ext] breakd[el] bw[ipeout] cabo[ve] cat[ch] ccl[ose] cfdo chd[ir] class cnf[ile] comc[lear] cp[revious] cstag debugg[reedy] deletel delm[arks] diffo[ff] dir doau e[dit] echom[sg] en[dif] endinterface ex files fini[sh] folddoc[losed] grepa[dd] helpf[ind] hor[izontal] il[ist] interface ju[mps] keepp[atterns] lad[dexpr] later lch[dir] lefta[bove] lg[etfile] lhi[story] lmapc[lear] loadkeymap lpf[ile] luafile mak[e] mks[ession] mzf[ile] nmapc[lear] nos[wapfile] opt[ions] pe[rl] pre[serve] promptr[epl] ptl[ast] pw[d] pydo pyxfile red[o] res[ize] ru[ntime] sI sIp sav[eas] sbm[odified] sce scripte[ncoding] setg[lobal] sgc sgr sign sl[eep] smile sor[t] spellr[epall] srI srn startr[eplace] substituterepeat sw[apname] t tabd[o] tabn[ext] tags te[aroff] tlm tm[enu] tp[revious] type unl ve[rsion] vim9s[cript] wN[ext] windo wundo xmenu xunmenu -syn keyword vimCommand contained abo[veleft] argded[upe] au bd[elete] bo[tright] breakl[ist] cN[ext] cad[dbuffer] cb[uffer] cd cfir[st] che[ckpath] cle[arjumps] cnor comp[iler] cpf[ile] cun def deletep delp diffp[atch] disa[ssemble] doaut ea echon endclass endt[ry] exi[t] filet fir[st] foldo[pen] gui helpg[rep] i imapc[lear] intro k lN[ext] laddb[uffer] lb[uffer] lcl[ose] leg[acy] lgetb[uffer] ll lne[xt] loc[kmarks] lr[ewind] lv[imgrep] marks mksp[ell] n[ext] noa nu[mber] ownsyntax ped[it] prev[ious] ps[earch] ptn[ext] py3 pyf[ile] q[uit] redi[r] ret[ab] rub[y] sIc sIr sbN[ext] sbn[ext] scg scriptv[ersion] setl[ocal] sge sh[ell] sil[ent] sla[st] sn[ext] sp[lit] spellr[rare] src srp static sun[hide] sy tN[ext] tabe[dit] tabnew tc[d] ter[minal] tlmenu tma[p] tr[ewind] u[ndo] unlo[ckvar] verb[ose] vim[grep] w[rite] winp[os] wv[iminfo] xnoreme xwininfo -syn keyword vimCommand contained abstract argdo bN[ext] bel[owright] bp[revious] bro[wse] cNf[ile] cadde[xpr] cbe[fore] cdo cg[etfile] checkt[ime] clo[se] co[py] con[tinue] cq[uit] cuna[bbrev] defc[ompile] deletl dep diffpu[t] dj[ump] dp earlier echow[indow] enddef endw[hile] exp filetype fix[del] for gvim helpt[ags] ia imp is[earch] kee[pmarks] lNf[ile] laddf[ile] lbe[fore] lcs lex[pr] lgete[xpr] lla[st] lnew[er] lockv[ar] ls lvimgrepa[dd] mat[ch] mkv[imrc] nb[key] noautocmd o[pen] p[rint] perld[o] pro ptN[ext] ptp[revious] py3do python3 qa[ll] redr[aw] retu[rn] rubyd[o] sIe sN[ext] sb[uffer] sbp[revious] sci scs sf[ind] sgi si sim[alt] sm[agic] sno[magic] spe[llgood] spellu[ndo] sre[wind] st[op] stj[ump] sunme syn ta[g] tabf[ind] tabo[nly] tch[dir] tf[irst] tln tmapc[lear] try una[bbreviate] uns[ilent] vert[ical] vimgrepa[dd] wa[ll] wn[ext] x[it] xnoremenu y[ank] -syn keyword vimCommand contained addd arge[dit] b[uffer] bf[irst] br[ewind] bufdo c[hange] caddf[ile] cbel[ow] ce[nter] cgetb[uffer] chi[story] cmapc[lear] col[der] conf[irm] cr[ewind] cw[indow] delc[ommand] deletp di[splay] diffs[plit] dl dr[op] ec el[se] endenum ene[w] export filt[er] fo[ld] fu[nction] h[elp] hi iabc[lear] import isp[lit] keepa l[ist] laf[ter] lbel[ow] lcscope lf[ile] lgr[ep] lli[st] lnf[ile] lol[der] lt[ag] lw[indow] menut[ranslate] mkvie[w] nbc[lose] noh[lsearch] ol[dfiles] pa[ckadd] po[p] prof[ile] pta[g] ptr[ewind] py3f[ile] pythonx quita[ll] redraws[tatus] rew[ind] rubyf[ile] sIg sa[rgument] sba[ll] sbr[ewind] scl scscope sfir[st] sgl sic sin sm[ap] snoreme spelld[ump] spellw[rong] srg sta[g] stopi[nsert] sunmenu sync tab tabfir[st] tabp[revious] tcl th[row] tlnoremenu tn[ext] ts[elect] undoj[oin] up[date] vi[sual] viu[sage] wh[ile] wp[revious] xa[ll] xprop z[^.=] -syn keyword vimCommand contained al[l] argg[lobal] +syn keyword vimCommand contained a ar[gs] argl[ocal] bad[d] bn[ext] breakl[ist] cNf[ile] cadde[xpr] cbe[fore] cdo cg[etfile] checkt[ime] clo[se] co[py] con[tinue] cq[uit] cuna[bbrev] defc[ompile] deletl dep diffpu[t] dj[ump] dp earlier echow[indow] enddef endinterface ex files fini[sh] folddoc[losed] go[to] ha[rdcopy] hid[e] if in iuna[bbrev] keepalt la[st] lan[guage] lbo[ttom] ld[o] lfdo lgrepa[dd] lma lo[adview] lop[en] lua m[ove] mes[sages] mod[e] nbs[tart] nor omapc[lear] packl[oadall] popu[p] profd[el] ptf[irst] pts[elect] py3f[ile] pyx r[ead] redrawt[abline] ri[ght] rundo sIl sal[l] sbf[irst] sc scp se[t] sg sgn sie sip sme snoremenu spelli[nfo] spr[evious] sri star[tinsert] sts[elect] sus[pend] syncbind tabN[ext] tabl[ast] tabr[ewind] tcld[o] tj[ump] tlu tno[remap] tu[nmenu] undol[ist] v vie[w] vne[w] win[size] wq xmapc[lear] xr[estore] +syn keyword vimCommand contained ab arga[dd] argu[ment] balt bo[tright] bro[wse] c[hange] caddf[ile] cbel[ow] ce[nter] cgetb[uffer] chi[story] cmapc[lear] col[der] conf[irm] cr[ewind] cw[indow] delc[ommand] deletp di[splay] diffs[plit] dl dr[op] ec el[se] endenum endt[ry] exi[t] filet fir[st] foldo[pen] gr[ep] helpc[lose] his[tory] ij[ump] inor j[oin] keepj[umps] lab[ove] lat lc[d] le[ft] lfir[st] lh[elpgrep] lmak[e] loadk lp[revious] luado ma[rk] mk[exrc] mz[scheme] new nore on[ly] pc[lose] pp[op] promptf[ind] ptj[ump] pu[t] py[thon] pyxdo rec[over] reg[isters] rightb[elow] rv[iminfo] sIn san[dbox] sbl[ast] scI scr[iptnames] setf[iletype] sgI sgp sig sir smenu so[urce] spellr[are] sr srl startg[replace] substitutepattern sv[iew] syntime tabc[lose] tabm[ove] tabs tclf[ile] tl[ast] tlunmenu to[pleft] tunma[p] unh[ide] var vim9[cmd] vs[plit] winc[md] wqa[ll] xme xunme +syn keyword vimCommand contained abc[lear] argd[elete] as[cii] bd[elete] bp[revious] bufdo ca caf[ter] cbo[ttom] cex[pr] cgete[xpr] cl[ist] cn[ext] colo[rscheme] cons[t] cs d[elete] delel delfunction dif[fupdate] difft[his] dli[st] ds[earch] echoc[onsole] elsei[f] endfo[r] endw[hile] exp filetype fix[del] for grepa[dd] helpf[ind] hor[izontal] il[ist] interface ju[mps] keepp[atterns] lad[dexpr] later lch[dir] lefta[bove] lg[etfile] lhi[story] lmapc[lear] loadkeymap lpf[ile] luafile mak[e] mks[ession] mzf[ile] nmapc[lear] nos[wapfile] opt[ions] pe[rl] pre[serve] promptr[epl] ptl[ast] pw[d] pydo pyxfile red[o] res[ize] ru[ntime] sI sIp sav[eas] sbm[odified] sce scripte[ncoding] setg[lobal] sgc sgr sign sl[eep] smile sor[t] spellr[epall] srI srn startr[eplace] substituterepeat sw[apname] t tabd[o] tabn[ext] tags te[aroff] tlm tm[enu] tp[revious] type unl ve[rsion] vim9s[cript] wN[ext] windo wundo xmenu xunmenu +syn keyword vimCommand contained abo[veleft] argded[upe] au bel[owright] br[ewind] buffers cabc[lear] call cc cf[ile] changes cla[st] cnew[er] com cope[n] cscope debug delep dell diffg[et] dig[raphs] do dsp[lit] echoe[rr] em[enu] endfun ene[w] export filt[er] fo[ld] fun gui helpg[rep] i imapc[lear] intro k lN[ext] laddb[uffer] lb[uffer] lcl[ose] leg[acy] lgetb[uffer] ll lne[xt] loc[kmarks] lr[ewind] lv[imgrep] marks mksp[ell] n[ext] noa nu[mber] ownsyntax ped[it] prev[ious] ps[earch] ptn[ext] py3 pyf[ile] q[uit] redi[r] ret[ab] rub[y] sIc sIr sbN[ext] sbn[ext] scg scriptv[ersion] setl[ocal] sge sh[ell] sil[ent] sla[st] sn[ext] sp[lit] spellr[rare] src srp static sun[hide] sy tN[ext] tabe[dit] tabnew tc[d] ter[minal] tlmenu tma[p] tr[ewind] u[ndo] unlo[ckvar] verb[ose] vim[grep] w[rite] winp[os] wv[iminfo] xnoreme xwininfo +syn keyword vimCommand contained abstract argdo bN[ext] bf[irst] brea[k] bun[load] cabo[ve] cat[ch] ccl[ose] cfdo chd[ir] class cnf[ile] comc[lear] cp[revious] cstag debugg[reedy] deletel delm[arks] diffo[ff] dir doau e[dit] echom[sg] en[dif] endfunc enum exu[sage] fin[d] foldc[lose] func gvim helpt[ags] ia imp is[earch] kee[pmarks] lNf[ile] laddf[ile] lbe[fore] lcs lex[pr] lgete[xpr] lla[st] lnew[er] lockv[ar] ls lvimgrepa[dd] mat[ch] mkv[imrc] nb[key] noautocmd o[pen] p[rint] perld[o] pro ptN[ext] ptp[revious] py3do python3 qa[ll] redr[aw] return rubyd[o] sIe sN[ext] sb[uffer] sbp[revious] sci scs sf[ind] sgi si sim[alt] sm[agic] sno[magic] spe[llgood] spellu[ndo] sre[wind] st[op] stj[ump] sunme syn ta[g] tabf[ind] tabo[nly] tch[dir] tf[irst] tln tmapc[lear] try una[bbreviate] uns[ilent] vert[ical] vimgrepa[dd] wa[ll] wn[ext] x[it] xnoremenu y[ank] +syn keyword vimCommand contained addd arge[dit] b[uffer] bl[ast] breaka[dd] bw[ipeout] cad[dbuffer] cb[uffer] cd cfir[st] che[ckpath] cle[arjumps] cnor comp[iler] cpf[ile] cun def deletep delp diffp[atch] disa[ssemble] doaut ea echon endclass endfunction eval f[ile] fina[lly] foldd[oopen] function h[elp] hi iabc[lear] import isp[lit] keepa l[ist] laf[ter] lbel[ow] lcscope lf[ile] lgr[ep] lli[st] lnf[ile] lol[der] lt[ag] lw[indow] menut[ranslate] mkvie[w] nbc[lose] noh[lsearch] ol[dfiles] pa[ckadd] po[p] prof[ile] pta[g] ptr[ewind] py3f[ile] pythonx quita[ll] redraws[tatus] rew[ind] rubyf[ile] sIg sa[rgument] sba[ll] sbr[ewind] scl scscope sfir[st] sgl sic sin sm[ap] snoreme spelld[ump] spellw[rong] srg sta[g] stopi[nsert] sunmenu sync tab tabfir[st] tabp[revious] tcl th[row] tlnoremenu tn[ext] ts[elect] undoj[oin] up[date] vi[sual] viu[sage] wh[ile] wp[revious] xa[ll] xprop z[^.=] +syn keyword vimCommand contained al[l] argg[lobal] ba[ll] bm[odified] breakd[el] cN[ext] syn match vimCommand contained "\" syn keyword vimStdPlugin contained Arguments Asm Break Cfilter Clear Continue DiffOrig Evaluate Finish Gdb Lfilter Man N[ext] Over P[rint] Program Run S Source Step Stop Termdebug TermdebugCommand TOhtml Until Winbar XMLent XMLns diff --git a/runtime/syntax/zsh.vim b/runtime/syntax/zsh.vim index bab89b916e..69671c59ca 100644 --- a/runtime/syntax/zsh.vim +++ b/runtime/syntax/zsh.vim @@ -2,7 +2,7 @@ " Language: Zsh shell script " Maintainer: Christian Brabandt " Previous Maintainer: Nikolai Weibull -" Latest Revision: 2020-11-21 +" Latest Revision: 2022-07-26 " License: Vim (see :h license) " Repository: https://github.com/chrisbra/vim-zsh @@ -19,9 +19,9 @@ function! s:ContainedGroup() " vim-pandoc syntax defines the @langname cluster for embedded syntax languages " However, if no syntax is defined yet, `syn list @zsh` will return " "No syntax items defined", so make sure the result is actually a valid syn cluster - for cluster in ['markdownHighlightzsh', 'zsh'] + for cluster in ['markdownHighlight_zsh', 'zsh'] try - " markdown syntax defines embedded clusters as @markdownhighlight, + " markdown syntax defines embedded clusters as @markdownhighlight_, " pandoc just uses @, so check both for both clusters let a=split(execute('syn list @'. cluster), "\n") if len(a) == 2 && a[0] =~# '^---' && a[1] =~? cluster @@ -48,17 +48,28 @@ syn match zshPOSIXQuoted '\\u[0-9a-fA-F]\{1,4}' syn match zshPOSIXQuoted '\\U[1-9a-fA-F]\{1,8}' syn region zshString matchgroup=zshStringDelimiter start=+"+ end=+"+ - \ contains=zshQuoted,@zshDerefs,@zshSubst fold + \ contains=zshQuoted,@zshDerefs,@zshSubstQuoted fold syn region zshString matchgroup=zshStringDelimiter start=+'+ end=+'+ fold syn region zshPOSIXString matchgroup=zshStringDelimiter start=+\$'+ \ skip=+\\[\\']+ end=+'+ contains=zshPOSIXQuoted,zshQuoted syn match zshJobSpec '%\(\d\+\|?\=\w\+\|[%+-]\)' +syn match zshNumber '[+-]\=\<\d\+\>' +syn match zshNumber '[+-]\=\<0x\x\+\>' +syn match zshNumber '[+-]\=\<0\o\+\>' +syn match zshNumber '[+-]\=\d\+#[-+]\=\w\+\>' +syn match zshNumber '[+-]\=\d\+\.\d\+\>' + syn keyword zshPrecommand noglob nocorrect exec command builtin - time syn keyword zshDelimiter do done end -syn keyword zshConditional if then elif else fi case in esac select +syn keyword zshConditional if then elif else fi esac select + +syn keyword zshCase case nextgroup=zshCaseWord skipwhite +syn match zshCaseWord /\S\+/ nextgroup=zshCaseIn skipwhite contained transparent +syn keyword zshCaseIn in nextgroup=zshCasePattern skipwhite skipnl contained +syn match zshCasePattern /\S[^)]*)/ contained syn keyword zshRepeat while until repeat @@ -73,9 +84,13 @@ syn match zshFunction '^\s*\k\+\ze\s*()' syn match zshOperator '||\|&&\|;\|&!\=' -syn match zshRedir '\d\=\(<\|<>\|<<<\|<&\s*[0-9p-]\=\)' -syn match zshRedir '\d\=\(>\|>>\|>&\s*[0-9p-]\=\|&>\|>>&\|&>>\)[|!]\=' -syn match zshRedir '|&\=' + " <<<, <, <>, and variants. +syn match zshRedir '\d\=\(<<<\|<&\s*[0-9p-]\=\|<>\?\)' + " >, >>, and variants. +syn match zshRedir '\d\=\(>&\s*[0-9p-]\=\|&>>\?\|>>\?&\?\)[|!]\=' + " | and |&, but only if it's not preceeded or + " followed by a | to avoid matching ||. +syn match zshRedir '|\@1/ +syn keyword zshOption nextgroup=zshOption,zshComment skipwhite contained + \ auto_cd no_auto_cd autocd noautocd auto_pushd no_auto_pushd autopushd noautopushd cdable_vars + \ no_cdable_vars cdablevars nocdablevars cd_silent no_cd_silent cdsilent nocdsilent chase_dots + \ no_chase_dots chasedots nochasedots chase_links no_chase_links chaselinks nochaselinks posix_cd + \ posixcd no_posix_cd noposixcd pushd_ignore_dups no_pushd_ignore_dups pushdignoredups + \ nopushdignoredups pushd_minus no_pushd_minus pushdminus nopushdminus pushd_silent no_pushd_silent + \ pushdsilent nopushdsilent pushd_to_home no_pushd_to_home pushdtohome nopushdtohome + \ always_last_prompt no_always_last_prompt alwayslastprompt noalwayslastprompt always_to_end + \ no_always_to_end alwaystoend noalwaystoend auto_list no_auto_list autolist noautolist auto_menu + \ no_auto_menu automenu noautomenu auto_name_dirs no_auto_name_dirs autonamedirs noautonamedirs + \ auto_param_keys no_auto_param_keys autoparamkeys noautoparamkeys auto_param_slash + \ no_auto_param_slash autoparamslash noautoparamslash auto_remove_slash no_auto_remove_slash + \ autoremoveslash noautoremoveslash bash_auto_list no_bash_auto_list bashautolist nobashautolist + \ complete_aliases no_complete_aliases completealiases nocompletealiases complete_in_word + \ no_complete_in_word completeinword nocompleteinword glob_complete no_glob_complete globcomplete + \ noglobcomplete hash_list_all no_hash_list_all hashlistall nohashlistall list_ambiguous + \ no_list_ambiguous listambiguous nolistambiguous list_beep no_list_beep listbeep nolistbeep + \ list_packed no_list_packed listpacked nolistpacked list_rows_first no_list_rows_first listrowsfirst + \ nolistrowsfirst list_types no_list_types listtypes nolisttypes menu_complete no_menu_complete + \ menucomplete nomenucomplete rec_exact no_rec_exact recexact norecexact bad_pattern no_bad_pattern + \ badpattern nobadpattern bare_glob_qual no_bare_glob_qual bareglobqual nobareglobqual brace_ccl + \ no_brace_ccl braceccl nobraceccl case_glob no_case_glob caseglob nocaseglob case_match + \ no_case_match casematch nocasematch case_paths no_case_paths casepaths nocasepaths csh_null_glob + \ no_csh_null_glob cshnullglob nocshnullglob equals no_equals noequals extended_glob no_extended_glob + \ extendedglob noextendedglob force_float no_force_float forcefloat noforcefloat glob no_glob noglob + \ glob_assign no_glob_assign globassign noglobassign glob_dots no_glob_dots globdots noglobdots + \ glob_star_short no_glob_star_short globstarshort noglobstarshort glob_subst no_glob_subst globsubst + \ noglobsubst hist_subst_pattern no_hist_subst_pattern histsubstpattern nohistsubstpattern + \ ignore_braces no_ignore_braces ignorebraces noignorebraces ignore_close_braces + \ no_ignore_close_braces ignoreclosebraces noignoreclosebraces ksh_glob no_ksh_glob kshglob nokshglob + \ magic_equal_subst no_magic_equal_subst magicequalsubst nomagicequalsubst mark_dirs no_mark_dirs + \ markdirs nomarkdirs multibyte no_multibyte nomultibyte nomatch no_nomatch nonomatch null_glob + \ no_null_glob nullglob nonullglob numeric_glob_sort no_numeric_glob_sort numericglobsort + \ nonumericglobsort rc_expand_param no_rc_expand_param rcexpandparam norcexpandparam rematch_pcre + \ no_rematch_pcre rematchpcre norematchpcre sh_glob no_sh_glob shglob noshglob unset no_unset nounset + \ warn_create_global no_warn_create_global warncreateglobal nowarncreateglobal warn_nested_var + \ no_warn_nested_var warnnestedvar no_warnnestedvar append_history no_append_history appendhistory + \ noappendhistory bang_hist no_bang_hist banghist nobanghist extended_history no_extended_history + \ extendedhistory noextendedhistory hist_allow_clobber no_hist_allow_clobber histallowclobber + \ nohistallowclobber hist_beep no_hist_beep histbeep nohistbeep hist_expire_dups_first + \ no_hist_expire_dups_first histexpiredupsfirst nohistexpiredupsfirst hist_fcntl_lock + \ no_hist_fcntl_lock histfcntllock nohistfcntllock hist_find_no_dups no_hist_find_no_dups + \ histfindnodups nohistfindnodups hist_ignore_all_dups no_hist_ignore_all_dups histignorealldups + \ nohistignorealldups hist_ignore_dups no_hist_ignore_dups histignoredups nohistignoredups + \ hist_ignore_space no_hist_ignore_space histignorespace nohistignorespace hist_lex_words + \ no_hist_lex_words histlexwords nohistlexwords hist_no_functions no_hist_no_functions + \ histnofunctions nohistnofunctions hist_no_store no_hist_no_store histnostore nohistnostore + \ hist_reduce_blanks no_hist_reduce_blanks histreduceblanks nohistreduceblanks hist_save_by_copy + \ no_hist_save_by_copy histsavebycopy nohistsavebycopy hist_save_no_dups no_hist_save_no_dups + \ histsavenodups nohistsavenodups hist_verify no_hist_verify histverify nohistverify + \ inc_append_history no_inc_append_history incappendhistory noincappendhistory + \ inc_append_history_time no_inc_append_history_time incappendhistorytime noincappendhistorytime + \ share_history no_share_history sharehistory nosharehistory all_export no_all_export allexport + \ noallexport global_export no_global_export globalexport noglobalexport global_rcs no_global_rcs + \ globalrcs noglobalrcs rcs no_rcs norcs aliases no_aliases noaliases clobber no_clobber noclobber + \ clobber_empty no_clobber_empty clobberempty noclobberempty correct no_correct nocorrect correct_all + \ no_correct_all correctall nocorrectall dvorak no_dvorak nodvorak flow_control no_flow_control + \ flowcontrol noflowcontrol ignore_eof no_ignore_eof ignoreeof noignoreeof interactive_comments + \ no_interactive_comments interactivecomments nointeractivecomments hash_cmds no_hash_cmds hashcmds + \ nohashcmds hash_dirs no_hash_dirs hashdirs nohashdirs hash_executables_only + \ no_hash_executables_only hashexecutablesonly nohashexecutablesonly mail_warning no_mail_warning + \ mailwarning nomailwarning path_dirs no_path_dirs pathdirs nopathdirs path_script no_path_script + \ pathscript nopathscript print_eight_bit no_print_eight_bit printeightbit noprinteightbit + \ print_exit_value no_print_exit_value printexitvalue noprintexitvalue rc_quotes no_rc_quotes + \ rcquotes norcquotes rm_star_silent no_rm_star_silent rmstarsilent normstarsilent rm_star_wait + \ no_rm_star_wait rmstarwait normstarwait short_loops no_short_loops shortloops noshortloops + \ short_repeat no_short_repeat shortrepeat noshortrepeat sun_keyboard_hack no_sun_keyboard_hack + \ sunkeyboardhack nosunkeyboardhack auto_continue no_auto_continue autocontinue noautocontinue + \ auto_resume no_auto_resume autoresume noautoresume bg_nice no_bg_nice bgnice nobgnice check_jobs + \ no_check_jobs checkjobs nocheckjobs check_running_jobs no_check_running_jobs checkrunningjobs + \ nocheckrunningjobs hup no_hup nohup long_list_jobs no_long_list_jobs longlistjobs nolonglistjobs + \ monitor no_monitor nomonitor notify no_notify nonotify posix_jobs posixjobs no_posix_jobs + \ noposixjobs prompt_bang no_prompt_bang promptbang nopromptbang prompt_cr no_prompt_cr promptcr + \ nopromptcr prompt_sp no_prompt_sp promptsp nopromptsp prompt_percent no_prompt_percent + \ promptpercent nopromptpercent prompt_subst no_prompt_subst promptsubst nopromptsubst + \ transient_rprompt no_transient_rprompt transientrprompt notransientrprompt alias_func_def + \ no_alias_func_def aliasfuncdef noaliasfuncdef c_bases no_c_bases cbases nocbases c_precedences + \ no_c_precedences cprecedences nocprecedences debug_before_cmd no_debug_before_cmd debugbeforecmd + \ nodebugbeforecmd err_exit no_err_exit errexit noerrexit err_return no_err_return errreturn + \ noerrreturn eval_lineno no_eval_lineno evallineno noevallineno exec no_exec noexec function_argzero + \ no_function_argzero functionargzero nofunctionargzero local_loops no_local_loops localloops + \ nolocalloops local_options no_local_options localoptions nolocaloptions local_patterns + \ no_local_patterns localpatterns nolocalpatterns local_traps no_local_traps localtraps nolocaltraps + \ multi_func_def no_multi_func_def multifuncdef nomultifuncdef multios no_multios nomultios + \ octal_zeroes no_octal_zeroes octalzeroes nooctalzeroes pipe_fail no_pipe_fail pipefail nopipefail + \ source_trace no_source_trace sourcetrace nosourcetrace typeset_silent no_typeset_silent + \ typesetsilent notypesetsilent typeset_to_unset no_typeset_to_unset typesettounset notypesettounset + \ verbose no_verbose noverbose xtrace no_xtrace noxtrace append_create no_append_create appendcreate + \ noappendcreate bash_rematch no_bash_rematch bashrematch nobashrematch bsd_echo no_bsd_echo bsdecho + \ nobsdecho continue_on_error no_continue_on_error continueonerror nocontinueonerror + \ csh_junkie_history no_csh_junkie_history cshjunkiehistory nocshjunkiehistory csh_junkie_loops + \ no_csh_junkie_loops cshjunkieloops nocshjunkieloops csh_junkie_quotes no_csh_junkie_quotes + \ cshjunkiequotes nocshjunkiequotes csh_nullcmd no_csh_nullcmd cshnullcmd nocshnullcmd ksh_arrays + \ no_ksh_arrays ksharrays noksharrays ksh_autoload no_ksh_autoload kshautoload nokshautoload + \ ksh_option_print no_ksh_option_print kshoptionprint nokshoptionprint ksh_typeset no_ksh_typeset + \ kshtypeset nokshtypeset ksh_zero_subscript no_ksh_zero_subscript kshzerosubscript + \ nokshzerosubscript posix_aliases no_posix_aliases posixaliases noposixaliases posix_argzero + \ no_posix_argzero posixargzero noposixargzero posix_builtins no_posix_builtins posixbuiltins + \ noposixbuiltins posix_identifiers no_posix_identifiers posixidentifiers noposixidentifiers + \ posix_strings no_posix_strings posixstrings noposixstrings posix_traps no_posix_traps posixtraps + \ noposixtraps sh_file_expansion no_sh_file_expansion shfileexpansion noshfileexpansion sh_nullcmd + \ no_sh_nullcmd shnullcmd noshnullcmd sh_option_letters no_sh_option_letters shoptionletters + \ noshoptionletters sh_word_split no_sh_word_split shwordsplit noshwordsplit traps_async + \ no_traps_async trapsasync notrapsasync interactive no_interactive nointeractive login no_login + \ nologin privileged no_privileged noprivileged restricted no_restricted norestricted shin_stdin + \ no_shin_stdin shinstdin noshinstdin single_command no_single_command singlecommand nosinglecommand + \ beep no_beep nobeep combining_chars no_combining_chars combiningchars nocombiningchars emacs + \ no_emacs noemacs overstrike no_overstrike nooverstrike single_line_zle no_single_line_zle + \ singlelinezle nosinglelinezle vi no_vi novi zle no_zle nozle brace_expand no_brace_expand + \ braceexpand nobraceexpand dot_glob no_dot_glob dotglob nodotglob hash_all no_hash_all hashall + \ nohashall hist_append no_hist_append histappend nohistappend hist_expand no_hist_expand histexpand + \ nohistexpand log no_log nolog mail_warn no_mail_warn mailwarn nomailwarn one_cmd no_one_cmd onecmd + \ noonecmd physical no_physical nophysical prompt_vars no_prompt_vars promptvars nopromptvars stdin + \ no_stdin nostdin track_all no_track_all trackall notrackall syn case match syn keyword zshTypes float integer local typeset declare private readonly @@ -150,15 +275,12 @@ syn keyword zshTypes float integer local typeset declare private read " XXX: this may be too much " syn match zshSwitches '\s\zs--\=[a-zA-Z0-9-]\+' -syn match zshNumber '[+-]\=\<\d\+\>' -syn match zshNumber '[+-]\=\<0x\x\+\>' -syn match zshNumber '[+-]\=\<0\o\+\>' -syn match zshNumber '[+-]\=\d\+#[-+]\=\w\+\>' -syn match zshNumber '[+-]\=\d\+\.\d\+\>' - " TODO: $[...] is the same as $((...)), so add that as well. syn cluster zshSubst contains=zshSubst,zshOldSubst,zshMathSubst +syn cluster zshSubstQuoted contains=zshSubstQuoted,zshOldSubst,zshMathSubst exe 'syn region zshSubst matchgroup=zshSubstDelim transparent start=/\$(/ skip=/\\)/ end=/)/ contains='.s:contained. ' fold' +exe 'syn region zshSubstQuoted matchgroup=zshSubstDelim transparent start=/\$(/ skip=/\\)/ end=/)/ contains='.s:contained. ' fold' +syn region zshSubstQuoted matchgroup=zshSubstDelim start='\${' skip='\\}' end='}' contains=@zshSubst,zshBrackets,zshQuoted fold syn region zshParentheses transparent start='(' skip='\\)' end=')' fold syn region zshGlob start='(#' end=')' syn region zshMathSubst matchgroup=zshSubstDelim transparent @@ -201,6 +323,8 @@ hi def link zshJobSpec Special hi def link zshPrecommand Special hi def link zshDelimiter Keyword hi def link zshConditional Conditional +hi def link zshCase zshConditional +hi def link zshCaseIn zshCase hi def link zshException Exception hi def link zshRepeat Repeat hi def link zshKeyword Keyword @@ -223,6 +347,7 @@ hi def link zshTypes Type hi def link zshSwitches Special hi def link zshNumber Number hi def link zshSubst PreProc +hi def link zshSubstQuoted zshSubst hi def link zshMathSubst zshSubst hi def link zshOldSubst zshSubst hi def link zshSubstDelim zshSubst From 55e9366e32bc0e1056478d1d0ae935f9cf039d6a Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 10 Sep 2022 13:52:26 +0100 Subject: [PATCH 18/28] patch 9.0.0437: no error when custom completion function returns wrong type Problem: No error when a custom completion function returns something else than the expected list. Solution: Give an error. (closes #11100) --- src/errors.h | 2 ++ src/eval.c | 3 +++ src/testdir/test_usercommands.vim | 4 ++-- src/version.c | 2 ++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/errors.h b/src/errors.h index 43baa6a1ad..d1cf4b457f 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3333,4 +3333,6 @@ EXTERN char e_string_number_list_or_blob_required_for_argument_nr[] INIT(= N_("E1301: String, Number, List or Blob required for argument %d")); EXTERN char e_script_variable_was_deleted[] INIT(= N_("E1302: Script variable was deleted")); +EXTERN char e_custom_list_completion_function_does_not_return_list_but_str[] + INIT(= N_("E1303: Custom list completion function does not return a List but a %s")); #endif diff --git a/src/eval.c b/src/eval.c index db8b4e6c98..f208ab1009 100644 --- a/src/eval.c +++ b/src/eval.c @@ -842,6 +842,7 @@ call_func_retstr( * Call Vim script function "func" and return the result as a List. * Uses "argv" and "argc" as call_func_retstr(). * Returns NULL when there is something wrong. + * Gives an error when the returned value is not a list. */ void * call_func_retlist( @@ -856,6 +857,8 @@ call_func_retlist( if (rettv.v_type != VAR_LIST) { + semsg(_(e_custom_list_completion_function_does_not_return_list_but_str), + vartype_name(rettv.v_type)); clear_tv(&rettv); return NULL; } diff --git a/src/testdir/test_usercommands.vim b/src/testdir/test_usercommands.vim index 91d8bfd062..8a41004060 100644 --- a/src/testdir/test_usercommands.vim +++ b/src/testdir/test_usercommands.vim @@ -666,7 +666,7 @@ func Test_usercmd_custom() return "a\nb\n" endfunc command -nargs=* -complete=customlist,T1 TCmd1 - call feedkeys(":TCmd1 \\\"\", 'xt') + call assert_fails('call feedkeys(":TCmd1 \\\"\", "xt")', 'E1303: Custom list completion function does not return a List but a string') call assert_equal('"TCmd1 ', @:) delcommand TCmd1 delfunc T1 @@ -675,7 +675,7 @@ func Test_usercmd_custom() return {} endfunc command -nargs=* -complete=customlist,T2 TCmd2 - call feedkeys(":TCmd2 \\\"\", 'xt') + call assert_fails('call feedkeys(":TCmd2 \\\"\", "xt")', 'E1303: Custom list completion function does not return a List but a dict') call assert_equal('"TCmd2 ', @:) delcommand TCmd2 delfunc T2 diff --git a/src/version.c b/src/version.c index cd340b5268..2d9b3ad208 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 437, /**/ 436, /**/ From 04e0ed1ddf399d609dbcb7dbf19e531da1fe6172 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 10 Sep 2022 20:00:56 +0100 Subject: [PATCH 19/28] patch 9.0.0438: cannot put virtual text above a line Problem: Cannot put virtual text above a line. Solution: Add the "above" value for "text_align". --- runtime/doc/textprop.txt | 1 + src/charset.c | 51 ++------ src/drawline.c | 120 +++++++++++++----- src/misc2.c | 31 +++-- src/move.c | 14 +- src/proto/charset.pro | 1 - src/structs.h | 15 ++- .../dumps/Test_prop_with_text_above_1.dump | 9 ++ src/testdir/test_textprop.vim | 20 +++ src/textprop.c | 37 ++++-- src/version.c | 2 + 11 files changed, 198 insertions(+), 103 deletions(-) create mode 100644 src/testdir/dumps/Test_prop_with_text_above_1.dump diff --git a/runtime/doc/textprop.txt b/runtime/doc/textprop.txt index 996cdd1978..8d7c0ecf39 100644 --- a/runtime/doc/textprop.txt +++ b/runtime/doc/textprop.txt @@ -153,6 +153,7 @@ prop_add({lnum}, {col}, {props}) the text wraps to the next screen line) below in the next screen line + above just above the line When omitted "after" is used. Only one "right" property can fit in each line, if there are two ore more these will go in a diff --git a/src/charset.c b/src/charset.c index d26a696c74..acf60999db 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1069,40 +1069,6 @@ lbr_chartabsize_adv(chartabsize_T *cts) return retval; } -#if defined(FEAT_PROP_POPUP) || defined(PROTO) -/* - * Return the cell size of virtual text after truncation. - */ - int -textprop_size_after_trunc( - win_T *wp, - int below, - int added, - char_u *text, - int *n_used_ptr) -{ - int space = below ? wp->w_width : added; - int len = (int)STRLEN(text); - int strsize = 0; - int n_used; - - // if the remaining size is to small wrap - // anyway and use the next line - if (space < PROP_TEXT_MIN_CELLS) - space += wp->w_width; - for (n_used = 0; n_used < len; n_used += (*mb_ptr2len)(text + n_used)) - { - int clen = ptr2cells(text + n_used); - - if (strsize + clen > space) - break; - strsize += clen; - } - *n_used_ptr = n_used; - return strsize; -} -#endif - /* * Return the screen size of the character indicated by "cts". * "cts->cts_cur_text_width" is set to the extra size for a text property that @@ -1142,6 +1108,7 @@ win_lbr_chartabsize( #if defined(FEAT_PROP_POPUP) cts->cts_cur_text_width = 0; + cts->cts_first_char = 0; #endif #if defined(FEAT_LINEBREAK) || defined(FEAT_PROP_POPUP) @@ -1194,9 +1161,12 @@ win_lbr_chartabsize( if (tp->tp_id < 0 && ((tp->tp_col - 1 >= col && tp->tp_col - 1 < col + charlen) - || (tp->tp_col == MAXCOL && (s[0] == NUL || s[1] == NUL) - && cts->cts_with_trailing)) - && -tp->tp_id - 1 < gap->ga_len) + || (tp->tp_col == MAXCOL + && ((tp->tp_flags & TP_FLAG_ALIGN_ABOVE) + ? col == 0 + : (s[0] == NUL || s[1] == NUL) + && cts->cts_with_trailing))) + && tp->tp_id - 1 < gap->ga_len) { char_u *p = ((char_u **)gap->ga_data)[-tp->tp_id - 1]; @@ -1218,6 +1188,8 @@ win_lbr_chartabsize( else cells = vim_strsize(p); cts->cts_cur_text_width += cells; + if (tp->tp_flags & TP_FLAG_ALIGN_ABOVE) + cts->cts_first_char += cells; cts->cts_start_incl = tp->tp_flags & TP_FLAG_START_INCL; size += cells; if (*s == TAB) @@ -1564,6 +1536,11 @@ getvcol( #endif break; } +#ifdef FEAT_PROP_POPUP + if (cursor == &wp->w_virtcol && cts.cts_ptr == cts.cts_line) + // do not count the virtual text above for w_curswant + wp->w_virtcol_first_char = cts.cts_first_char; +#endif if (posptr != NULL && cts.cts_ptr >= posptr) // character at pos->col diff --git a/src/drawline.c b/src/drawline.c index 6c298b6f48..56d42e2a7f 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -278,6 +278,38 @@ get_sign_display_info( #endif #if defined(FEAT_PROP_POPUP) || defined(PROTO) +/* + * Return the cell size of virtual text after truncation. + */ + static int +textprop_size_after_trunc( + win_T *wp, + int flags, // TP_FLAG_ALIGN_* + int added, + char_u *text, + int *n_used_ptr) +{ + int space = (flags & (TP_FLAG_ALIGN_BELOW | TP_FLAG_ALIGN_ABOVE)) + ? wp->w_width : added; + int len = (int)STRLEN(text); + int strsize = 0; + int n_used; + + // if the remaining size is to small wrap anyway and use the next line + if (space < PROP_TEXT_MIN_CELLS) + space += wp->w_width; + for (n_used = 0; n_used < len; n_used += (*mb_ptr2len)(text + n_used)) + { + int clen = ptr2cells(text + n_used); + + if (strsize + clen > space) + break; + strsize += clen; + } + *n_used_ptr = n_used; + return strsize; +} + /* * Take care of padding, right-align and truncation of virtual text after a * line. @@ -297,6 +329,7 @@ text_prop_position( int *n_attr_skip) // cells to skip attr, NULL if not used { int right = (tp->tp_flags & TP_FLAG_ALIGN_RIGHT); + int above = (tp->tp_flags & TP_FLAG_ALIGN_ABOVE); int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW); int wrap = (tp->tp_flags & TP_FLAG_WRAP); int padding = tp->tp_col == MAXCOL && tp->tp_len > 1 @@ -304,36 +337,45 @@ text_prop_position( int col_with_padding = vcol + (below ? 0 : padding); int col_off = 0; int room = wp->w_width - col_with_padding; - int added = room; + int before = room; // spaces before the text + int after = 0; // spaces after the text int n_used = *n_extra; char_u *l = NULL; int strsize = vim_strsize(*p_extra); - int cells = wrap ? strsize - : textprop_size_after_trunc(wp, below, added, *p_extra, &n_used); + int cells = wrap ? strsize : textprop_size_after_trunc(wp, + tp->tp_flags, before, *p_extra, &n_used); - if (wrap || right || below || padding > 0 || n_used < *n_extra) + if (wrap || right || above || below || padding > 0 || n_used < *n_extra) { - // Right-align: fill with spaces - if (right) - added -= cells; - if (added < 0 - || !(right || below) - || (below - ? (col_with_padding == 0 || !wp->w_p_wrap) - : (n_used < *n_extra))) + if (above) { - if (right && (wrap || room < PROP_TEXT_MIN_CELLS)) + before = 0; + after = wp->w_width - cells; + } + else + { + // Right-align: fill with before + if (right) + before -= cells; + if (before < 0 + || !(right || below) + || (below + ? (col_with_padding == 0 || !wp->w_p_wrap) + : (n_used < *n_extra))) { - // right-align on next line instead of wrapping if possible - col_off = win_col_off(wp) + win_col_off2(wp); - added = wp->w_width - col_off - strsize + room; - if (added < 0) - added = 0; + if (right && (wrap || room < PROP_TEXT_MIN_CELLS)) + { + // right-align on next line instead of wrapping if possible + col_off = win_col_off(wp) + win_col_off2(wp); + before = wp->w_width - col_off - strsize + room; + if (before < 0) + before = 0; + else + n_used = *n_extra; + } else - n_used = *n_extra; + before = 0; } - else - added = 0; } // With 'nowrap' add one to show the "extends" character if needed (it @@ -346,15 +388,15 @@ text_prop_position( // add 1 for NUL, 2 for when '…' is used if (n_attr != NULL) - l = alloc(n_used + added + padding + 3); + l = alloc(n_used + before + after + padding + 3); if (n_attr == NULL || l != NULL) { int off = 0; if (n_attr != NULL) { - vim_memset(l, ' ', added); - off += added; + vim_memset(l, ' ', before); + off += before; if (padding > 0) { vim_memset(l + off, ' ', padding); @@ -365,8 +407,8 @@ text_prop_position( } else { - off = added + padding + n_used; - cells += added + padding; + off = before + after + padding + n_used; + cells += before + after + padding; } if (n_attr != NULL) { @@ -385,10 +427,16 @@ text_prop_position( // change last character to '>' *lp = '>'; } + else if (after > 0) + { + vim_memset(l + off, ' ', after); + l[off + after] = NUL; + } + *p_extra = l; - *n_extra = n_used + added + padding; + *n_extra = n_used + before + after + padding; *n_attr = mb_charlen(*p_extra); - *n_attr_skip = added + padding + col_off; + *n_attr_skip = before + padding + col_off; } } } @@ -1694,11 +1742,14 @@ win_line( // text prop can show. while (text_prop_next < text_prop_count && (text_props[text_prop_next].tp_col == MAXCOL - ? (*ptr == NUL + ? ((*ptr == NUL && (wp->w_p_wrap || wlv.row == startrow || (text_props[text_prop_next].tp_flags & TP_FLAG_ALIGN_BELOW))) + || (bcol == 0 && + (text_props[text_prop_next].tp_flags + & TP_FLAG_ALIGN_ABOVE))) : bcol >= text_props[text_prop_next].tp_col - 1)) { if (text_props[text_prop_next].tp_col == MAXCOL @@ -1773,6 +1824,8 @@ win_line( { int right = (tp->tp_flags & TP_FLAG_ALIGN_RIGHT); + int above = (tp->tp_flags + & TP_FLAG_ALIGN_ABOVE); int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW); int wrap = (tp->tp_flags & TP_FLAG_WRAP); @@ -1797,18 +1850,15 @@ win_line( // don't combine char attr after EOL text_prop_flags &= ~PT_FLAG_COMBINE; #ifdef FEAT_LINEBREAK - if (below || right || !wrap) + if (above || below || right || !wrap) { // no 'showbreak' before "below" text property - // or after "right" text property + // or after "above" or "right" text property need_showbreak = FALSE; dont_use_showbreak = TRUE; } #endif - // Keep in sync with where - // textprop_size_after_trunc() is called in - // win_lbr_chartabsize(). - if ((right || below || !wrap || padding > 0) + if ((right || above || below || !wrap || padding > 0) && wp->w_width > 2) { char_u *prev_p_extra = wlv.p_extra; diff --git a/src/misc2.c b/src/misc2.c index 84adafab66..165a08080c 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -85,7 +85,7 @@ getviscol2(colnr_T col, colnr_T coladd UNUSED) } /* - * Try to advance the Cursor to the specified screen column. + * Try to advance the Cursor to the specified screen column "wantcol". * If virtual editing: fine tune the cursor position. * Note that all virtual positions off the end of a line should share * a curwin->w_cursor.col value (n.b. this is equal to STRLEN(line)), @@ -94,29 +94,30 @@ getviscol2(colnr_T col, colnr_T coladd UNUSED) * return OK if desired column is reached, FAIL if not */ int -coladvance(colnr_T wcol) +coladvance(colnr_T wantcol) { - int rc = getvpos(&curwin->w_cursor, wcol); + int rc = getvpos(&curwin->w_cursor, wantcol); - if (wcol == MAXCOL || rc == FAIL) + if (wantcol == MAXCOL || rc == FAIL) curwin->w_valid &= ~VALID_VIRTCOL; else if (*ml_get_cursor() != TAB) { // Virtcol is valid when not on a TAB curwin->w_valid |= VALID_VIRTCOL; - curwin->w_virtcol = wcol; + curwin->w_virtcol = wantcol; } return rc; } /* - * Return in "pos" the position of the cursor advanced to screen column "wcol". + * Return in "pos" the position of the cursor advanced to screen column + * "wantcol". * return OK if desired column is reached, FAIL if not */ int -getvpos(pos_T *pos, colnr_T wcol) +getvpos(pos_T *pos, colnr_T wantcol) { - return coladvance2(pos, FALSE, virtual_active(), wcol); + return coladvance2(pos, FALSE, virtual_active(), wantcol); } static int @@ -156,8 +157,8 @@ coladvance2( } else { - int width = curwin->w_width - win_col_off(curwin); - chartabsize_T cts; + int width = curwin->w_width - win_col_off(curwin); + chartabsize_T cts; if (finetune && curwin->w_p_wrap @@ -183,6 +184,9 @@ coladvance2( init_chartabsize_arg(&cts, curwin, pos->lnum, 0, line, line); while (cts.cts_vcol <= wcol && *cts.cts_ptr != NUL) { +#ifdef FEAT_PROP_POPUP + int at_start = cts.cts_ptr == cts.cts_line; +#endif // Count a tab for what it's worth (if list mode not on) #ifdef FEAT_LINEBREAK csize = win_lbr_chartabsize(&cts, &head); @@ -191,6 +195,11 @@ coladvance2( csize = lbr_chartabsize_adv(&cts); #endif cts.cts_vcol += csize; +#ifdef FEAT_PROP_POPUP + if (at_start) + // do not count the columns for virtual text above + cts.cts_vcol -= cts.cts_first_char; +#endif } col = cts.cts_vcol; idx = (int)(cts.cts_ptr - line); @@ -2400,7 +2409,7 @@ update_mouseshape(int shape_idx) /* * Change directory to "new_dir". Search 'cdpath' for relative directory - * names, otherwise just mch_chdir(). + * names. */ int vim_chdir(char_u *new_dir) diff --git a/src/move.c b/src/move.c index 089ffca399..9ec7798b9f 100644 --- a/src/move.c +++ b/src/move.c @@ -476,7 +476,11 @@ update_curswant(void) if (curwin->w_set_curswant) { validate_virtcol(); - curwin->w_curswant = curwin->w_virtcol; + curwin->w_curswant = curwin->w_virtcol +#ifdef FEAT_PROP_POPUP + - curwin->w_virtcol_first_char +#endif + ; curwin->w_set_curswant = FALSE; } } @@ -835,6 +839,9 @@ validate_virtcol_win(win_T *wp) check_cursor_moved(wp); if (!(wp->w_valid & VALID_VIRTCOL)) { +#ifdef FEAT_PROP_POPUP + wp->w_virtcol_first_char = 0; +#endif getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL); #ifdef FEAT_SYN_HL redraw_for_cursorcolumn(wp); @@ -982,6 +989,11 @@ curs_columns( if (!(curwin->w_valid & VALID_CROW)) curs_rows(curwin); +#ifdef FEAT_PROP_POPUP + // will be set by getvvcol() but not reset + curwin->w_virtcol_first_char = 0; +#endif + /* * Compute the number of virtual columns. */ diff --git a/src/proto/charset.pro b/src/proto/charset.pro index 6bc8eab990..c7d5767954 100644 --- a/src/proto/charset.pro +++ b/src/proto/charset.pro @@ -34,7 +34,6 @@ void init_chartabsize_arg(chartabsize_T *cts, win_T *wp, linenr_T lnum, colnr_T void clear_chartabsize_arg(chartabsize_T *cts); int lbr_chartabsize(chartabsize_T *cts); int lbr_chartabsize_adv(chartabsize_T *cts); -int textprop_size_after_trunc(win_T *wp, int below, int added, char_u *text, int *n_used_ptr); int win_lbr_chartabsize(chartabsize_T *cts, int *headp); void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end); colnr_T getvcol_nolist(pos_T *posp); diff --git a/src/structs.h b/src/structs.h index 6e29785d3d..c12f8e45af 100644 --- a/src/structs.h +++ b/src/structs.h @@ -813,12 +813,13 @@ typedef struct textprop_S #define TP_FLAG_CONT_PREV 0x2 // property was continued from prev line // without these text is placed after the end of the line -#define TP_FLAG_ALIGN_RIGHT 0x10 // virtual text is right-aligned -#define TP_FLAG_ALIGN_BELOW 0x20 // virtual text on next screen line +#define TP_FLAG_ALIGN_RIGHT 0x010 // virtual text is right-aligned +#define TP_FLAG_ALIGN_ABOVE 0x020 // virtual text above the line +#define TP_FLAG_ALIGN_BELOW 0x040 // virtual text on next screen line -#define TP_FLAG_WRAP 0x40 // virtual text wraps - when missing +#define TP_FLAG_WRAP 0x080 // virtual text wraps - when missing // text is truncated -#define TP_FLAG_START_INCL 0x80 // "start_incl" copied from proptype +#define TP_FLAG_START_INCL 0x100 // "start_incl" copied from proptype #define PROP_TEXT_MIN_CELLS 4 // minimun number of cells to use for // the text, even when truncating @@ -3678,6 +3679,11 @@ struct window_S // more than one screen line or when // w_leftcol is non-zero +#ifdef FEAT_PROP_POPUP + colnr_T w_virtcol_first_char; // offset for w_virtcol when there are + // virtual text properties above the + // line +#endif /* * w_wrow and w_wcol specify the cursor position in the window. * This is related to positions in the window, not in the display or @@ -4607,6 +4613,7 @@ typedef struct { textprop_T *cts_text_props; // text props (allocated) char cts_has_prop_with_text; // TRUE if if a property inserts text int cts_cur_text_width; // width of current inserted text + int cts_first_char; // width text props above the line int cts_with_trailing; // include size of trailing props with // last character int cts_start_incl; // prop has true "start_incl" arg diff --git a/src/testdir/dumps/Test_prop_with_text_above_1.dump b/src/testdir/dumps/Test_prop_with_text_above_1.dump new file mode 100644 index 0000000000..cc68f5e50c --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_above_1.dump @@ -0,0 +1,9 @@ +|f+0&#ffff4012|i|r|s|t| |t|h|i|n|g| |a|b|o|v|e| @42 +|s+0&#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| @41 +|o+0&#ffffff0|n|e| |t|w|o| @52 +|t|h|r>e@1| |f|o|u|r| @49 +|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @46 +|f+0&#ffffff0|i|v|e| |s|i|x| @51 +|~+0#4040ff13&| @58 +|~| @58 +| +0#0000000&@41|2|,|4| @10|A|l@1| diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index 21d751fb14..d89f84cedd 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -2848,6 +2848,26 @@ func Test_props_with_text_below_nowrap() call delete('XscriptPropsBelowNowrap') endfunc +func Test_props_with_text_above() + CheckRunVimInTerminal + + let lines =<< trim END + call setline(1, ['one two', 'three four', 'five six']) + call prop_type_add('above1', #{highlight: 'Search'}) + call prop_type_add('above2', #{highlight: 'DiffChange'}) + call prop_add(1, 0, #{type: 'above1', text: 'first thing above', text_align: 'above'}) + call prop_add(1, 0, #{type: 'above2', text: 'second thing above', text_align: 'above'}) + call prop_add(3, 0, #{type: 'above1', text: 'another thing', text_align: 'above'}) + + normal gglllj + END + call writefile(lines, 'XscriptPropsWithTextAbove', 'D') + let buf = RunVimInTerminal('-S XscriptPropsWithTextAbove', #{rows: 9, cols: 60}) + call VerifyScreenDump(buf, 'Test_prop_with_text_above_1', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_props_with_text_override() CheckRunVimInTerminal diff --git a/src/textprop.c b/src/textprop.c index 5f5c6a2aa2..ff96833f6c 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -497,6 +497,8 @@ prop_add_common( } if (STRCMP(p, "right") == 0) flags |= TP_FLAG_ALIGN_RIGHT; + else if (STRCMP(p, "above") == 0) + flags |= TP_FLAG_ALIGN_ABOVE; else if (STRCMP(p, "below") == 0) flags |= TP_FLAG_ALIGN_BELOW; else if (STRCMP(p, "after") != 0) @@ -673,6 +675,21 @@ count_props(linenr_T lnum, int only_starting, int last_line) static textprop_T *text_prop_compare_props; static buf_T *text_prop_compare_buf; +/* Score for sorting on position of the text property: 0: above, + * 1: after (default), 2: right, 3: below (comes last) + */ + static int +text_prop_order(int flags) +{ + if (flags & TP_FLAG_ALIGN_ABOVE) + return 0; + if (flags & TP_FLAG_ALIGN_RIGHT) + return 2; + if (flags & TP_FLAG_ALIGN_BELOW) + return 3; + return 1; +} + /* * Function passed to qsort() to sort text properties. * Return 1 if "s1" has priority over "s2", -1 if the other way around, zero if @@ -694,21 +711,13 @@ text_prop_compare(const void *s1, const void *s2) col2 = tp2->tp_col; if (col1 == MAXCOL && col2 == MAXCOL) { - int flags1 = 0; - int flags2 = 0; + int order1 = text_prop_order(tp1->tp_flags); + int order2 = text_prop_order(tp2->tp_flags); - // both props add text are after the line, order on 0: after (default), - // 1: right, 2: below (comes last) - if (tp1->tp_flags & TP_FLAG_ALIGN_RIGHT) - flags1 = 1; - if (tp1->tp_flags & TP_FLAG_ALIGN_BELOW) - flags1 = 2; - if (tp2->tp_flags & TP_FLAG_ALIGN_RIGHT) - flags2 = 1; - if (tp2->tp_flags & TP_FLAG_ALIGN_BELOW) - flags2 = 2; - if (flags1 != flags2) - return flags1 < flags2 ? 1 : -1; + // both props add text before or after the line, sort on order where it + // is added + if (order1 != order2) + return order1 < order2 ? 1 : -1; } // property that inserts text has priority over one that doesn't diff --git a/src/version.c b/src/version.c index 2d9b3ad208..ac89e77c08 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 438, /**/ 437, /**/ From 88b79cb7d47e2e1fee1baf4016c50b861e6b21c4 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 10 Sep 2022 22:32:14 +0100 Subject: [PATCH 20/28] patch 9.0.0439: cursor wrong if inserting before line with virtual text above Problem: Cursor wrong if inserting before line with virtual text above. Solution: Add the width of the "above" virtual text to the cursor position. (issue #11084) --- src/charset.c | 3 +++ src/testdir/dumps/Test_prop_with_text_above_2.dump | 9 +++++++++ src/testdir/dumps/Test_prop_with_text_above_3.dump | 9 +++++++++ src/testdir/test_textprop.vim | 5 +++++ src/version.c | 2 ++ 5 files changed, 28 insertions(+) create mode 100644 src/testdir/dumps/Test_prop_with_text_above_2.dump create mode 100644 src/testdir/dumps/Test_prop_with_text_above_3.dump diff --git a/src/charset.c b/src/charset.c index acf60999db..a19e55b628 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1576,6 +1576,9 @@ getvcol( if (((State & MODE_INSERT) == 0 || cts.cts_start_incl) && !on_NUL) // cursor is after inserted text, unless on the NUL vcol += cts.cts_cur_text_width; + else + // insertion also happens after the "above" virtual text + vcol += cts.cts_first_char; #endif *cursor = vcol + head; // cursor at start } diff --git a/src/testdir/dumps/Test_prop_with_text_above_2.dump b/src/testdir/dumps/Test_prop_with_text_above_2.dump new file mode 100644 index 0000000000..7f45faf118 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_above_2.dump @@ -0,0 +1,9 @@ +|f+0&#ffff4012|i|r|s|t| |t|h|i|n|g| |a|b|o|v|e| @42 +|s+0&#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| @41 +>o+0&#ffffff0|n|e| |t|w|o| @52 +|t|h|r|e@1| |f|o|u|r| @49 +|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @46 +|f+0&#ffffff0|i|v|e| |s|i|x| @51 +|~+0#4040ff13&| @58 +|~| @58 +|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@29|1|,|1|-|1|2|1| @6|A|l@1| diff --git a/src/testdir/dumps/Test_prop_with_text_above_3.dump b/src/testdir/dumps/Test_prop_with_text_above_3.dump new file mode 100644 index 0000000000..8a4b1d4917 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_above_3.dump @@ -0,0 +1,9 @@ +|f+0&#ffff4012|i|r|s|t| |t|h|i|n|g| |a|b|o|v|e| @42 +|s+0&#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| @41 +|i+0&#ffffff0|n|s|e|r|t|e|d> |o|n|e| |t|w|o| @43 +|t|h|r|e@1| |f|o|u|r| @49 +|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @46 +|f+0&#ffffff0|i|v|e| |s|i|x| @51 +|~+0#4040ff13&| @58 +|~| @58 +| +0#0000000&@41|1|,|9|-|1|2|9| @6|A|l@1| diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index d89f84cedd..f97772ce63 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -2865,6 +2865,11 @@ func Test_props_with_text_above() let buf = RunVimInTerminal('-S XscriptPropsWithTextAbove', #{rows: 9, cols: 60}) call VerifyScreenDump(buf, 'Test_prop_with_text_above_1', {}) + call term_sendkeys(buf, "ggI") + call VerifyScreenDump(buf, 'Test_prop_with_text_above_2', {}) + call term_sendkeys(buf, "inserted \") + call VerifyScreenDump(buf, 'Test_prop_with_text_above_3', {}) + call StopVimInTerminal(buf) endfunc diff --git a/src/version.c b/src/version.c index ac89e77c08..3345c21c43 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 439, /**/ 438, /**/ From f5fec05c7fd0df4c934a838e82882e601dc920cb Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 11 Sep 2022 11:49:22 +0100 Subject: [PATCH 21/28] patch 9.0.0440: crash when using mkdir() with "R" flag in compiled function Problem: Crash when using mkdir() with "R" flag in compiled function. Solution: Reserve a variable for deferred function calls. Handle more than one argument. --- src/testdir/test_vim9_func.vim | 60 +++++++++++----------------------- src/version.c | 2 ++ src/vim9execute.c | 14 +++++--- src/vim9expr.c | 7 ++-- 4 files changed, 35 insertions(+), 48 deletions(-) diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 70a71ea932..4d6e226892 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -29,7 +29,7 @@ def TestCompilingError() enddef defcompile END - writefile(lines, 'XTest_compile_error') + writefile(lines, 'XTest_compile_error', 'D') var buf = g:RunVimInTerminal('-S XTest_compile_error', {rows: 10, wait_for_ruler: 0}) g:WaitForAssert(() => assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing', @@ -37,12 +37,11 @@ def TestCompilingError() # clean up g:StopVimInTerminal(buf) - delete('XTest_compile_error') enddef def TestCompilingErrorInTry() var dir = 'Xcompdir/autoload' - mkdir(dir, 'p') + mkdir(dir, 'pR') var lines =<< trim END vim9script @@ -62,7 +61,7 @@ def TestCompilingErrorInTry() endtry END lines[1] = 'set rtp=' .. getcwd() .. '/Xcompdir' - writefile(lines, 'XTest_compile_error') + writefile(lines, 'XTest_compile_error', 'D') var buf = g:RunVimInTerminal('-S XTest_compile_error', {rows: 10, wait_for_ruler: 0}) g:WaitForAssert(() => assert_match('Error detected while compiling command line.*function script#OnlyCompiled.*Invalid command: invalid', @@ -70,8 +69,6 @@ def TestCompilingErrorInTry() # clean up g:StopVimInTerminal(buf) - delete('XTest_compile_error') - delete('Xcompdir', 'rf') enddef def Test_comment_error() @@ -171,7 +168,7 @@ enddef def Test_autoload_name_mismatch() var dir = 'Xnamedir/autoload' - mkdir(dir, 'p') + mkdir(dir, 'pR') var lines =<< trim END vim9script @@ -190,12 +187,11 @@ def Test_autoload_name_mismatch() v9.CheckScriptFailure(lines, 'E117:', 1) &rtp = save_rtp - delete('Xnamedir', 'rf') enddef def Test_autoload_names() var dir = 'Xandir/autoload' - mkdir(dir, 'p') + mkdir(dir, 'pR') var lines =<< trim END func foobar#function() @@ -218,12 +214,11 @@ def Test_autoload_names() v9.CheckDefAndScriptSuccess(lines) &rtp = save_rtp - delete('Xandir', 'rf') enddef def Test_autoload_error_in_script() var dir = 'Xaedir/autoload' - mkdir(dir, 'p') + mkdir(dir, 'pR') var lines =<< trim END func scripterror#function() @@ -264,7 +259,6 @@ def Test_autoload_error_in_script() assert_equal('yes', g:called_function) &rtp = save_rtp - delete('Xaedir', 'rf') enddef def s:CallRecursive(n: number): number @@ -1298,7 +1292,7 @@ def Test_call_wrong_args() enddef defcompile END - writefile(lines, 'Xscript') + writefile(lines, 'Xscript', 'D') didCatch = false try source Xscript @@ -1308,8 +1302,6 @@ def Test_call_wrong_args() didCatch = true endtry assert_true(didCatch) - - delete('Xscript') enddef def Test_call_funcref_wrong_args() @@ -2306,9 +2298,8 @@ def Test_vim9script_call() 'morelines', name) END - writefile(lines, 'Xcall.vim') + writefile(lines, 'Xcall.vim', 'D') source Xcall.vim - delete('Xcall.vim') enddef def Test_vim9script_call_fail_decl() @@ -2343,9 +2334,8 @@ def Test_vim9script_call_fail_const() enddef defcompile END - writefile(lines, 'Xcall_const.vim') + writefile(lines, 'Xcall_const.vim', 'D') assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc') - delete('Xcall_const.vim') lines =<< trim END const g:Aconst = 77 @@ -2385,11 +2375,9 @@ def Test_delfunc() delfunc g:GoneSoon CallGoneSoon() END - writefile(lines, 'XToDelFunc') + writefile(lines, 'XToDelFunc', 'D') assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') - - delete('XToDelFunc') enddef func Test_free_dict_while_in_funcstack() @@ -2454,10 +2442,8 @@ def Test_vim9script_func() endfunc Func('text') END - writefile(lines, 'XVim9Func') + writefile(lines, 'XVim9Func', 'D') so XVim9Func - - delete('XVim9Func') enddef let s:funcResult = 0 @@ -2700,7 +2686,7 @@ def Test_error_reporting() enddef defcompile END - writefile(lines, 'Xdef') + writefile(lines, 'Xdef', 'D') try source Xdef assert_report('should have failed') @@ -2749,8 +2735,6 @@ def Test_error_reporting() v:throwpoint->assert_match('_Func, line 3$') endtry delfunc! g:Func - - delete('Xdef') enddef def Test_deleted_function() @@ -3421,14 +3405,12 @@ def s:TreeWalk(dir: string): list enddef def Test_closure_in_map() - mkdir('XclosureDir/tdir', 'p') + mkdir('XclosureDir/tdir', 'pR') writefile(['111'], 'XclosureDir/file1') writefile(['222'], 'XclosureDir/file2') writefile(['333'], 'XclosureDir/tdir/file3') TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}]) - - delete('XclosureDir', 'rf') enddef def Test_invalid_function_name() @@ -3532,12 +3514,11 @@ func Test_partial_call_fails() var it = Iter(l) echo it.__next__() END - call writefile(lines, 'XpartialCall') + call writefile(lines, 'XpartialCall', 'D') try source XpartialCall catch /E1248:/ endtry - call delete('XpartialCall') endfunc def Test_cmd_modifier() @@ -3631,9 +3612,9 @@ def Test_did_emsg_reset() nno call Func() feedkeys("\\e", 'xt') END - writefile(lines, 'XemsgReset') + writefile(lines, 'XemsgReset', 'D') assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2) - delete('XemsgReset') + nunmap au! BufWinLeave enddef @@ -3698,7 +3679,7 @@ def Test_cmdmod_silent_restored() END # can't use CheckScriptFailure, it ignores the :silent! var fname = 'Xdefsilent' - writefile(lines, fname) + writefile(lines, fname, 'D') var caught = 'no' try exe 'source ' .. fname @@ -3707,7 +3688,6 @@ def Test_cmdmod_silent_restored() assert_match('Func, line 4', v:throwpoint) endtry assert_equal('yes', caught) - delete(fname) enddef def Test_cmdmod_silent_nested() @@ -3809,7 +3789,7 @@ def Run_Test_opfunc_error() feedkeys('g@l', 'n') feedkeys('llll') END - call writefile(lines, 'XTest_opfunc_error') + call writefile(lines, 'XTest_opfunc_error', 'D') var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0}) g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6))) @@ -3817,7 +3797,6 @@ def Run_Test_opfunc_error() # clean up g:StopVimInTerminal(buf) - delete('XTest_opfunc_error') enddef " this was crashing on exit @@ -3890,14 +3869,13 @@ def Test_script_local_other_script() function s:close_cb(...) endfunction END - lines->writefile('Xlegacy.vim') + lines->writefile('Xlegacy.vim', 'D') source Xlegacy.vim g:LegacyJob() g:LegacyJob() g:LegacyJob() delfunc g:LegacyJob - delete('Xlegacy.vim') enddef def Test_check_func_arg_types() diff --git a/src/version.c b/src/version.c index 3345c21c43..02e55d96dd 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 440, /**/ 439, /**/ diff --git a/src/vim9execute.c b/src/vim9execute.c index d4d1ad6995..cbf9af7ad3 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -932,11 +932,17 @@ defer_command(int var_idx, int argcount, ectx_T *ectx) return FAIL; func_tv = STACK_TV_BOT(-argcount - 1); - // TODO: check type is a funcref + if (func_tv->v_type != VAR_FUNC && func_tv->v_type != VAR_PARTIAL) + { + semsg(_(e_expected_str_but_got_str), + "function or partial", + vartype_name(func_tv->v_type)); + return FAIL; + } list_set_item(l, 0, func_tv); - for (i = 1; i <= argcount; ++i) - list_set_item(l, i, STACK_TV_BOT(-argcount + i - 1)); + for (i = 0; i < argcount; ++i) + list_set_item(l, i + 1, STACK_TV_BOT(-argcount + i)); ectx->ec_stack.ga_len -= argcount + 1; return OK; } @@ -962,7 +968,7 @@ add_defer_function(char_u *name, int argcount, typval_T *argvars) return FAIL; } - l = add_defer_item(dfunc->df_defer_var_idx - 1, 1, current_ectx); + l = add_defer_item(dfunc->df_defer_var_idx - 1, argcount, current_ectx); if (l == NULL) { vim_free(name); diff --git a/src/vim9expr.c b/src/vim9expr.c index a8d88a2f28..3da556cb10 100644 --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -833,10 +833,11 @@ compile_call( } } - if (STRCMP(name, "writefile") == 0 && argcount > 2) + if ((STRCMP(name, "writefile") == 0 && argcount > 2) + || (STRCMP(name, "mkdir") == 0 && argcount > 1)) { - // May have the "D" flag, reserve a variable for a deferred - // function call. + // May have the "D" or "R" flag, reserve a variable for a + // deferred function call. if (get_defer_var_idx(cctx) == 0) idx = -1; } From c069edeab28bdd7289d7096cd92804cb54841557 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 11 Sep 2022 12:01:04 +0100 Subject: [PATCH 22/28] patch 9.0.0441: closure in for loop test fails on some systems Problem: Closure in for loop test fails on some systems. Solution: Do not wait for the ruler to show up. (issue #11106) --- src/testdir/test_vim9_func.vim | 2 +- src/version.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 4d6e226892..a1c58a2048 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -2939,7 +2939,7 @@ def Run_Test_closure_in_for_loop_fails() writefile(lines, 'XTest_closure_fails', 'D') # Check that an error shows - var buf = g:RunVimInTerminal('-S XTest_closure_fails', {'rows': 6}) + var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0}) g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {}) # clean up diff --git a/src/version.c b/src/version.c index 02e55d96dd..b7bc80a1f2 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 441, /**/ 440, /**/ From 79f8b8494cd4f738f25272ece94d8b524b99cb09 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 11 Sep 2022 13:31:01 +0100 Subject: [PATCH 23/28] patch 9.0.0442: virtual text "above" doesn't handel line numbers Problem: Virtual text "above" doesn't handel line numbers. Solution: Take the left column offset into account. (issue #11084) Also make padding work. --- src/drawline.c | 8 +++++--- src/testdir/dumps/Test_prop_with_text_above_1.dump | 2 +- src/testdir/dumps/Test_prop_with_text_above_2.dump | 2 +- src/testdir/dumps/Test_prop_with_text_above_3.dump | 2 +- src/testdir/dumps/Test_prop_with_text_above_4.dump | 9 +++++++++ src/testdir/test_textprop.vim | 5 ++++- src/version.c | 2 ++ 7 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 src/testdir/dumps/Test_prop_with_text_above_4.dump diff --git a/src/drawline.c b/src/drawline.c index 56d42e2a7f..7f9660349b 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -350,7 +350,7 @@ text_prop_position( if (above) { before = 0; - after = wp->w_width - cells; + after = wp->w_width - cells - win_col_off(wp) - padding; } else { @@ -436,6 +436,8 @@ text_prop_position( *p_extra = l; *n_extra = n_used + before + after + padding; *n_attr = mb_charlen(*p_extra); + if (above) + *n_attr -= padding; *n_attr_skip = before + padding + col_off; } } @@ -1858,8 +1860,8 @@ win_line( dont_use_showbreak = TRUE; } #endif - if ((right || above || below || !wrap || padding > 0) - && wp->w_width > 2) + if ((right || above || below || !wrap + || padding > 0) && wp->w_width > 2) { char_u *prev_p_extra = wlv.p_extra; int start_line; diff --git a/src/testdir/dumps/Test_prop_with_text_above_1.dump b/src/testdir/dumps/Test_prop_with_text_above_1.dump index cc68f5e50c..6f2b09d616 100644 --- a/src/testdir/dumps/Test_prop_with_text_above_1.dump +++ b/src/testdir/dumps/Test_prop_with_text_above_1.dump @@ -2,7 +2,7 @@ |s+0&#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| @41 |o+0&#ffffff0|n|e| |t|w|o| @52 |t|h|r>e@1| |f|o|u|r| @49 -|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @46 +@3|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @43 |f+0&#ffffff0|i|v|e| |s|i|x| @51 |~+0#4040ff13&| @58 |~| @58 diff --git a/src/testdir/dumps/Test_prop_with_text_above_2.dump b/src/testdir/dumps/Test_prop_with_text_above_2.dump index 7f45faf118..7c84c73c49 100644 --- a/src/testdir/dumps/Test_prop_with_text_above_2.dump +++ b/src/testdir/dumps/Test_prop_with_text_above_2.dump @@ -2,7 +2,7 @@ |s+0&#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| @41 >o+0&#ffffff0|n|e| |t|w|o| @52 |t|h|r|e@1| |f|o|u|r| @49 -|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @46 +@3|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @43 |f+0&#ffffff0|i|v|e| |s|i|x| @51 |~+0#4040ff13&| @58 |~| @58 diff --git a/src/testdir/dumps/Test_prop_with_text_above_3.dump b/src/testdir/dumps/Test_prop_with_text_above_3.dump index 8a4b1d4917..a7277c2e37 100644 --- a/src/testdir/dumps/Test_prop_with_text_above_3.dump +++ b/src/testdir/dumps/Test_prop_with_text_above_3.dump @@ -2,7 +2,7 @@ |s+0&#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| @41 |i+0&#ffffff0|n|s|e|r|t|e|d> |o|n|e| |t|w|o| @43 |t|h|r|e@1| |f|o|u|r| @49 -|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @46 +@3|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @43 |f+0&#ffffff0|i|v|e| |s|i|x| @51 |~+0#4040ff13&| @58 |~| @58 diff --git a/src/testdir/dumps/Test_prop_with_text_above_4.dump b/src/testdir/dumps/Test_prop_with_text_above_4.dump new file mode 100644 index 0000000000..1ab0b69fd6 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_above_4.dump @@ -0,0 +1,9 @@ +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|1| |f+0#0000000#ffff4012|i|r|s|t| |t|h|i|n|g| |a|b|o|v|e| @36 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|s+0#0000000#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| @35 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|i+0#0000000&|n|s|e|r|t|e|d> |o|n|e| |t|w|o| @37 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|2| |t+0#0000000&|h|r|e@1| |f|o|u|r| @43 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|3| | +0#0000000&@2|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @37 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|f+0#0000000&|i|v|e| |s|i|x| @45 +|~+0#4040ff13&| @58 +|~| @58 +| +0#0000000&@41|1|,|9|-|1@1|7| @6|A|l@1| diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index f97772ce63..6e3ca3b1d1 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -2857,7 +2857,7 @@ func Test_props_with_text_above() call prop_type_add('above2', #{highlight: 'DiffChange'}) call prop_add(1, 0, #{type: 'above1', text: 'first thing above', text_align: 'above'}) call prop_add(1, 0, #{type: 'above2', text: 'second thing above', text_align: 'above'}) - call prop_add(3, 0, #{type: 'above1', text: 'another thing', text_align: 'above'}) + call prop_add(3, 0, #{type: 'above1', text: 'another thing', text_align: 'above', text_padding_left: 3}) normal gglllj END @@ -2870,6 +2870,9 @@ func Test_props_with_text_above() call term_sendkeys(buf, "inserted \") call VerifyScreenDump(buf, 'Test_prop_with_text_above_3', {}) + call term_sendkeys(buf, ":set number signcolumn=yes\") + call VerifyScreenDump(buf, 'Test_prop_with_text_above_4', {}) + call StopVimInTerminal(buf) endfunc diff --git a/src/version.c b/src/version.c index b7bc80a1f2..9d4f39be90 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 442, /**/ 441, /**/ From cce82a55b8105560a2ef724999c856966337b48e Mon Sep 17 00:00:00 2001 From: Gabriele Musco Date: Sun, 11 Sep 2022 13:37:37 +0100 Subject: [PATCH 24/28] patch 9.0.0443: blueprint files are not recognized Problem: Blueprint files are not recognized. Solution: Add a pattern for blueprint files. (Gabriele Musco, closes #11107) --- runtime/filetype.vim | 6 ++++-- src/testdir/test_filetype.vim | 1 + src/version.c | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/runtime/filetype.vim b/runtime/filetype.vim index d88f0256b1..deca7dc71a 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -874,11 +874,11 @@ au BufNewFile,BufRead *.htt,*.htb setf httest " i3 au BufNewFile,BufRead */i3/config setf i3config -au BufNewFile,BufRead */.i3/config setf i3config +au BufNewFile,BufRead */.i3/config setf i3config " sway au BufNewFile,BufRead */sway/config setf swayconfig -au BufNewFile,BufRead */.sway/config setf swayconfig +au BufNewFile,BufRead */.sway/config setf swayconfig " Icon au BufNewFile,BufRead *.icn setf icon @@ -2579,6 +2579,8 @@ au BufNewFile,BufRead *.txt \| setf text \| endif +" Blueprint markup files +au BufNewFile,BufRead *.blp setf blueprint " Use the filetype detect plugins. They may overrule any of the previously " detected filetypes. diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index e42b8a0da5..b8fccb2b89 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -88,6 +88,7 @@ let s:filename_checks = { \ 'bindzone': ['named.root', '/bind/db.file', '/named/db.file', 'any/bind/db.file', 'any/named/db.file'], \ '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'], \ 'blank': ['file.bl'], + \ 'blueprint': ['file.blp'], \ 'bsdl': ['file.bsd', 'file.bsdl'], \ 'bst': ['file.bst'], \ 'bzl': ['file.bazel', 'file.bzl', 'WORKSPACE'], diff --git a/src/version.c b/src/version.c index 9d4f39be90..26c1697c33 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 443, /**/ 442, /**/ From 9510d22463055f56548ff461ccbc54caa1ba1a2f Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 11 Sep 2022 15:14:05 +0100 Subject: [PATCH 25/28] patch 9.0.0444: trying to declare g:variable gives confusing error Problem: Trying to declare g:variable gives confusing error. Solution: Give a better error message. (closes #11108) --- src/errors.h | 2 ++ src/eval.c | 6 +++++- src/evalvars.c | 15 +++++++++++++-- src/ex_docmd.c | 4 ++-- src/proto/evalvars.pro | 1 + src/testdir/test_vim9_assign.vim | 32 ++++++++++++++++++++++---------- src/testdir/test_vim9_cmd.vim | 4 ++-- src/testdir/test_vim9_script.vim | 5 ++--- src/version.c | 2 ++ 9 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/errors.h b/src/errors.h index d1cf4b457f..5f0fdcb8a8 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3335,4 +3335,6 @@ EXTERN char e_script_variable_was_deleted[] INIT(= N_("E1302: Script variable was deleted")); EXTERN char e_custom_list_completion_function_does_not_return_list_but_str[] INIT(= N_("E1303: Custom list completion function does not return a List but a %s")); +EXTERN char e_cannot_use_type_with_this_variable_str[] + INIT(= N_("E1304: Cannot use type with this variable: %s")); #endif diff --git a/src/eval.c b/src/eval.c index f208ab1009..5d93b7e50c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1031,12 +1031,16 @@ get_lval( { char_u *tp = skipwhite(p + 1); + if (is_scoped_variable(name)) + { + semsg(_(e_cannot_use_type_with_this_variable_str), name); + return NULL; + } if (tp == p + 1 && !quiet) { semsg(_(e_white_space_required_after_str_str), ":", p); return NULL; } - if (!SCRIPT_ID_VALID(current_sctx.sc_sid)) { semsg(_(e_using_type_not_in_script_context_str), p); diff --git a/src/evalvars.c b/src/evalvars.c index facafc7dd2..7de785bc4b 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -602,6 +602,18 @@ list_script_vars(int *first) "s:", FALSE, first); } +/* + * Return TRUE if "name" starts with "g:", "w:", "t:" or "b:". + * But only when an identifier character follows. + */ + int +is_scoped_variable(char_u *name) +{ + return vim_strchr((char_u *)"gwbt", name[0]) != NULL + && name[1] == ':' + && eval_isnamec(name[2]); +} + /* * Evaluate one Vim expression {expr} in string "p" and append the * resulting string to "gap". "p" points to the opening "{". @@ -3679,8 +3691,7 @@ set_var_const( vim9_declare_error(name); goto failed; } - if ((flags & ASSIGN_FOR_LOOP) && name[1] == ':' - && vim_strchr((char_u *)"gwbt", name[0]) != NULL) + if ((flags & ASSIGN_FOR_LOOP) && is_scoped_variable(name)) // Do not make g:var, w:var, b:var or t:var final. flags &= ~ASSIGN_FINAL; diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 0024c99c63..0e5e1db5ec 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3761,11 +3761,11 @@ find_ex_command( } } - // Recognize using a type for a w:, b:, t: or g: variable: + // Recognize trying to use a type for a w:, b:, t: or g: variable: // "w:varname: number = 123". if (eap->cmd[1] == ':' && *p == ':') { - eap->cmdidx = CMD_eval; + eap->cmdidx = CMD_var; return eap->cmd; } } diff --git a/src/proto/evalvars.pro b/src/proto/evalvars.pro index 253af6de6c..b8b0053422 100644 --- a/src/proto/evalvars.pro +++ b/src/proto/evalvars.pro @@ -13,6 +13,7 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr); int get_spellword(list_T *list, char_u **pp); void prepare_vimvar(int idx, typval_T *save_tv); void restore_vimvar(int idx, typval_T *save_tv); +int is_scoped_variable(char_u *name); char_u *eval_one_expr_in_str(char_u *p, garray_T *gap, int evaluate); list_T *heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile); void ex_var(exarg_T *eap); diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 58dde3f1fe..11d7425e65 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -1597,13 +1597,31 @@ def Test_assignment_failure() v9.CheckDefFailure(['var name: dict") + term_sendkeys(buf, ":vim9cmd echo islocked('somevar: string')\") g:VerifyScreenDump(buf, 'Test_misplaced_type', {}) g:StopVimInTerminal(buf) - delete('XTest_misplaced_type') enddef " Ensure echo doesn't crash when stringifying empty variables. diff --git a/src/version.c b/src/version.c index 26c1697c33..8fee9776ec 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 444, /**/ 443, /**/ From 29ab524358ba429bcf6811710afc97a978641f0b Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Sun, 11 Sep 2022 16:59:53 +0100 Subject: [PATCH 26/28] patch 9.0.0445: when opening/closing window text moves up/down Problem: When opening/closing window text moves up/down. Solution: Add the 'splitscroll' option. When off text will keep its position as much as possible. --- runtime/doc/options.txt | 12 +++ runtime/doc/quickref.txt | 1 + runtime/optwin.vim | 2 + src/move.c | 3 +- src/option.h | 1 + src/optiondefs.h | 3 + src/structs.h | 2 + src/testdir/test_window_cmd.vim | 128 ++++++++++++++++++++++++++++ src/version.c | 2 + src/window.c | 143 ++++++++++++++++++++++++++++++-- 10 files changed, 287 insertions(+), 10 deletions(-) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index b60abc271d..336d4497d5 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -7499,6 +7499,18 @@ A jump table for the options with a short description can be found at |Q_op|. When on, splitting a window will put the new window right of the current one. |:vsplit| + *'splitscroll'* *'spsc'* *'nosplitscroll'* *'nospsc'* +'splitscroll' 'spsc' boolean (default on) + global + The value of this option determines the scroll behavior when opening, + closing or resizing horizontal splits. When "on", splitting a window + horizontally will keep the same relative cursor position in the old and + new window, as well windows that are resized. When "off", scrolling + will be avoided to stabilize the window content. Instead, the cursor + position will be changed when necessary. In this case, the jumplist + will be populated with the previous cursor position. Scrolling cannot + be guaranteed to be avoided when 'wrap' is enabled. + *'startofline'* *'sol'* *'nostartofline'* *'nosol'* 'startofline' 'sol' boolean (default on) global diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt index 67fc28e17a..2cc2358e9c 100644 --- a/runtime/doc/quickref.txt +++ b/runtime/doc/quickref.txt @@ -919,6 +919,7 @@ Short explanation of each option: *option-list* 'spellsuggest' 'sps' method(s) used to suggest spelling corrections 'splitbelow' 'sb' new window from split is below the current one 'splitright' 'spr' new window is put right of the current one +'splitscroll' 'spsc' determines scroll behavior when splitting windows 'startofline' 'sol' commands move cursor to first non-blank in line 'statusline' 'stl' custom format for the status line 'suffixes' 'su' suffixes that are ignored with multiple match diff --git a/runtime/optwin.vim b/runtime/optwin.vim index c83b06b31a..6b9b5fec95 100644 --- a/runtime/optwin.vim +++ b/runtime/optwin.vim @@ -515,6 +515,8 @@ call AddOption("splitbelow", gettext("a new window is put below the current call BinOptionG("sb", &sb) call AddOption("splitright", gettext("a new window is put right of the current one")) call BinOptionG("spr", &spr) +call AddOption("splitscroll", gettext("determines scroll behavior when spliting windows")) +call BinOptionG("spsc", &spsc) call AddOption("scrollbind", gettext("this window scrolls together with other bound windows")) call append("$", "\t" .. s:local_to_window) call BinOptionL("scb") diff --git a/src/move.c b/src/move.c index 9ec7798b9f..8660d89055 100644 --- a/src/move.c +++ b/src/move.c @@ -981,7 +981,8 @@ curs_columns( /* * First make sure that w_topline is valid (after moving the cursor). */ - update_topline(); + if (p_spsc) + update_topline(); /* * Next make sure that w_cline_row is valid. diff --git a/src/option.h b/src/option.h index ab34e82a7a..97b7a6c511 100644 --- a/src/option.h +++ b/src/option.h @@ -924,6 +924,7 @@ EXTERN char_u *p_spo; // 'spelloptions' EXTERN char_u *p_sps; // 'spellsuggest' #endif EXTERN int p_spr; // 'splitright' +EXTERN int p_spsc; // 'splitscroll' EXTERN int p_sol; // 'startofline' EXTERN char_u *p_su; // 'suffixes' EXTERN char_u *p_sws; // 'swapsync' diff --git a/src/optiondefs.h b/src/optiondefs.h index 2e24cdd9e2..8ec012f0d6 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -2349,6 +2349,9 @@ static struct vimoption options[] = {"splitright", "spr", P_BOOL|P_VI_DEF, (char_u *)&p_spr, PV_NONE, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, + {"splitscroll", "spsc", P_BOOL, + (char_u *)&p_spsc, PV_NONE, + {(char_u *)TRUE, (char_u *)TRUE} SCTX_INIT}, {"startofline", "sol", P_BOOL|P_VI_DEF|P_VIM, (char_u *)&p_sol, PV_NONE, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, diff --git a/src/structs.h b/src/structs.h index c12f8e45af..a477dc71fe 100644 --- a/src/structs.h +++ b/src/structs.h @@ -3570,6 +3570,8 @@ struct window_S int w_winrow; // first row of window in screen int w_height; // number of rows in window, excluding // status/command/winbar line(s) + int w_prev_winrow; // previous winrow used for 'splitscroll' + int w_prev_height; // previous height used for 'splitscroll' int w_status_height; // number of status lines (0 or 1) int w_wincol; // Leftmost column of window in screen. diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim index e38c8a8107..a75286fae3 100644 --- a/src/testdir/test_window_cmd.vim +++ b/src/testdir/test_window_cmd.vim @@ -1631,5 +1631,133 @@ func Test_win_equal_last_status() set laststatus& endfunc +" Ensure no scrolling happens with 'nosplitscroll' with and without a +" winbar, tabline, for each possible value of 'laststatus', 'scrolloff', +" 'equalalways', and regardless of the cursor position. +func Test_splitscroll_with_splits() + set nowrap + set nosplitscroll + let gui = has("gui_running") + inoremap c :copen + for winbar in [0, 1] + for sb in [0, 1] + for ea in [0, 1] + for tab in [0, 1] + for so in [0, 5] + for ls in range(0, 2) + for pos in ["H", "M", "L"] + let tabline = (gui ? 0 : (tab ? 1 : 0)) + let winbar_sb = (sb ? winbar : 0) + execute 'set scrolloff=' . so + execute 'set laststatus=' . ls + execute 'set ' . (ea ? 'equalalways' : 'noequalalways') + execute 'set ' . (sb ? 'splitbelow' : 'nosplitbelow') + execute tab ? 'tabnew' : '' + execute winbar ? 'nnoremenu 1.10 WinBar.Test :echo' : '' + call setline(1, range(1, 256)) + execute 'norm gg' . pos + " No scroll for vertical split and quit + vsplit | quit + call assert_equal(1, line("w0")) + + " No scroll for horizontal split + split | redraw! | wincmd k + call assert_equal(1, line("w0")) + + " No scroll when resizing windows + resize +2 + call assert_equal(1, line("w0")) + wincmd j + call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + + " No scroll when dragging statusline + call win_move_statusline(1, -3) + call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + wincmd k + call assert_equal(1, line("w0")) + + " No scroll when changing shellsize + set lines+=2 + call assert_equal(1, line("w0")) + wincmd j + call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + set lines-=2 + call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + wincmd k + call assert_equal(1, line("w0")) + + " No scroll when equalizing windows + wincmd = + call assert_equal(1, line("w0")) + wincmd j + call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + wincmd k + call assert_equal(1, line("w0")) + + " No scroll in windows split multiple times + vsplit | split | 4wincmd w + call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + 1wincmd w | quit | wincmd l | split + call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + wincmd j + call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + + " No scroll in small window + 2wincmd w | only | 5split | wincmd k + call assert_equal(1, line("w0")) + wincmd j + call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + + " No scroll for vertical split + quit | vsplit | wincmd l + call assert_equal(1, line("w0")) + wincmd h + call assert_equal(1, line("w0")) + + " No scroll in windows split and quit multiple times + quit | split | split | quit + call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + + " No scroll for new buffer + 1wincmd w | only | copen | wincmd k + call assert_equal(1, line("w0")) + only + call assert_equal(1, line("w0")) + above copen | wincmd j + call assert_equal(win_screenpos(0)[0] - tabline, line("w0")) + + " No scroll when opening cmdwin + only | norm ggLq: + call assert_equal(1, line("w0")) + + " Scroll when cursor becomes invalid in insert mode + norm Lic + wincmd k | only + call assert_notequal(1, line("w0")) + + " No scroll when topline not equal to 1 + execute "norm gg5\" | split | wincmd k + call assert_equal(6, line("w0")) + wincmd j + call assert_equal(5 + win_screenpos(0)[0] - tabline - winbar_sb, line("w0")) + only + endfor + endfor + endfor + tabonly! + endfor + endfor + endfor + endfor + + tabnew | tabonly! | %bwipeout! + iunmap c + set wrap& + set scrolloff& + set splitbelow& + set laststatus& + set equalalways& + set splitscroll& +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 8fee9776ec..ec0f00b182 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 445, /**/ 444, /**/ diff --git a/src/window.c b/src/window.c index ff55a3bf9f..cbe01f04ca 100644 --- a/src/window.c +++ b/src/window.c @@ -25,6 +25,8 @@ static frame_T *win_altframe(win_T *win, tabpage_T *tp); static tabpage_T *alt_tabpage(void); static win_T *frame2win(frame_T *frp); static int frame_has_win(frame_T *frp, win_T *wp); +static void win_fix_scroll(int resize); +static void win_fix_cursor(int normal); static void frame_new_height(frame_T *topfrp, int height, int topfirst, int wfh); static int frame_fixed_height(frame_T *frp); static int frame_fixed_width(frame_T *frp); @@ -1323,6 +1325,8 @@ win_split_ins( win_equal(wp, TRUE, (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h') : dir == 'h' ? 'b' : 'v'); + else if (!p_spsc) + win_fix_scroll(FALSE); // Don't change the window height/width to 'winheight' / 'winwidth' if a // size was given. @@ -1407,6 +1411,13 @@ win_init(win_T *newp, win_T *oldp, int flags UNUSED) newp->w_prevdir = (oldp->w_prevdir == NULL) ? NULL : vim_strsave(oldp->w_prevdir); + if (!p_spsc) + { + newp->w_botline = oldp->w_botline; + newp->w_prev_height = oldp->w_height - WINBAR_HEIGHT(oldp); + newp->w_prev_winrow = oldp->w_winrow + 2 * WINBAR_HEIGHT(oldp); + } + // copy tagstack and folds for (i = 0; i < oldp->w_tagstacklen; i++) { @@ -1914,6 +1925,8 @@ win_equal( win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current, topframe, dir, 0, tabline_height(), (int)Columns, topframe->fr_height); + if (!p_spsc) + win_fix_scroll(TRUE); } /* @@ -2725,7 +2738,11 @@ win_close(win_T *win, int free_buf) // only resize that frame. Otherwise resize all windows. win_equal(curwin, curwin->w_frame->fr_parent == win_frame, dir); else + { win_comp_pos(); + if (!p_spsc) + win_fix_scroll(FALSE); + } if (close_curwin) { // Pass WEE_ALLOW_PARSE_MESSAGES to decrement dont_parse_messages @@ -4912,7 +4929,8 @@ win_enter_ext(win_T *wp, int flags) // Might need to scroll the old window before switching, e.g., when the // cursor was moved. - update_topline(); + if (p_spsc) + update_topline(); // may have to copy the buffer options when 'cpo' contains 'S' if (wp->w_buffer != curbuf) @@ -4927,7 +4945,10 @@ win_enter_ext(win_T *wp, int flags) check_cursor(); if (!virtual_active()) curwin->w_cursor.coladd = 0; - changed_line_abv_curs(); // assume cursor position needs updating + if (p_spsc) // assume cursor position needs updating. + changed_line_abv_curs(); + else + win_fix_cursor(TRUE); // Now it is OK to parse messages again, which may be needed in // autocommands. @@ -5458,6 +5479,9 @@ shell_new_rows(void) compute_cmdrow(); curtab->tp_ch_used = p_ch; + if (!p_spsc) + win_fix_scroll(TRUE); + #if 0 // Disabled: don't want making the screen smaller make a window larger. if (p_ea) @@ -5662,6 +5686,9 @@ win_setheight_win(int height, win_T *win) msg_row = row; msg_col = 0; + if (!p_spsc) + win_fix_scroll(TRUE); + redraw_all_later(UPD_NOT_VALID); } @@ -6190,6 +6217,9 @@ win_drag_status_line(win_T *dragwin, int offset) p_ch = MAX(Rows - cmdline_row, 1); curtab->tp_ch_used = p_ch; + if (!p_spsc) + win_fix_scroll(TRUE); + redraw_all_later(UPD_SOME_VALID); showmode(); } @@ -6316,6 +6346,97 @@ set_fraction(win_T *wp) + FRACTION_MULT / 2) / (long)wp->w_height; } +/* + * Handle scroll position for 'nosplitscroll'. Replaces scroll_to_fraction() + * call from win_new_height(). Instead we iterate over all windows in a + * tabpage and calculate the new scroll/cursor position. + * TODO: Ensure this also works with wrapped lines. + * Requires topline to be able to be set to a bufferline with some + * offset(row-wise scrolling/smoothscroll). + */ + static void +win_fix_scroll(int resize) +{ + win_T *wp; + linenr_T lnum; + + FOR_ALL_WINDOWS(wp) + { + // Skip when window height has not changed or when + // buffer has less lines than the window height. + if (wp->w_height != wp->w_prev_height + && wp->w_height < wp->w_buffer->b_ml.ml_line_count) + { + // Determine botline needed to avoid scrolling and set cursor. + if (wp->w_winrow != wp->w_prev_winrow) + { + lnum = wp->w_cursor.lnum; + wp->w_cursor.lnum = MIN(wp->w_buffer->b_ml.ml_line_count, + wp->w_botline - 1 + (wp->w_prev_height + ? (wp->w_winrow - wp->w_prev_winrow) + + (wp->w_height - wp->w_prev_height) + : -WINBAR_HEIGHT(wp))); + // Bring the new cursor position to the bottom of the screen. + wp->w_fraction = FRACTION_MULT; + scroll_to_fraction(wp, wp->w_prev_height); + wp->w_cursor.lnum = lnum; + } + invalidate_botline_win(wp); + validate_botline_win(wp); + } + wp->w_prev_height = wp->w_height; + wp->w_prev_winrow = wp->w_winrow; + } + // Ensure cursor is valid when not in normal mode or when resized. + if (!(get_real_state() & (MODE_NORMAL|MODE_CMDLINE))) + win_fix_cursor(FALSE); + else if (resize) + win_fix_cursor(TRUE); +} + +/* + * Make sure the cursor position is valid for 'nosplitscroll'. + * If it is not, put the cursor position in the jumplist and move it. + * If we are not in normal mode, scroll to make valid instead. + */ + static void +win_fix_cursor(int normal) +{ + int top = FALSE; + win_T *wp = curwin; + long so = get_scrolloff_value(); + linenr_T nlnum = 0; + + if (wp->w_buffer->b_ml.ml_line_count < wp->w_height) + return; + + so = MIN(wp->w_height / 2, so); + // Check if cursor position is above topline or below botline. + if (wp->w_cursor.lnum < (wp->w_topline + so) && wp->w_topline != 1) + top = nlnum = MIN(wp->w_topline + so, wp->w_buffer->b_ml.ml_line_count); + else if (wp->w_cursor.lnum > (wp->w_botline - so - 1) + && (wp->w_botline - wp->w_buffer->b_ml.ml_line_count) != 1) + nlnum = MAX(wp->w_botline - so - 1, 1); + // If cursor was invalid scroll or change cursor. + if (nlnum) + { + if (normal) + { // Make sure cursor is closer to topline than botline. + if (so == wp->w_height / 2 + && nlnum - wp->w_topline > wp->w_botline - 1 - nlnum) + nlnum--; + setmark('\''); // save cursor position + wp->w_cursor.lnum = nlnum; // change to avoid scrolling + curs_columns(TRUE); // validate w_wrow + } + else + { // Ensure cursor stays visible if we are not in normal mode. + wp->w_fraction = top ? 0 : FRACTION_MULT; + scroll_to_fraction(wp, wp->w_prev_height); + } + } +} + /* * Set the height of a window. * "height" excludes any window toolbar. @@ -6336,7 +6457,7 @@ win_new_height(win_T *wp, int height) if (wp->w_height > 0) { - if (wp == curwin) + if (wp == curwin && p_spsc) // w_wrow needs to be valid. When setting 'laststatus' this may // call win_new_height() recursively. validate_cursor(); @@ -6352,7 +6473,7 @@ win_new_height(win_T *wp, int height) // There is no point in adjusting the scroll position when exiting. Some // values might be invalid. - if (!exiting) + if (!exiting && p_spsc) scroll_to_fraction(wp, prev_height); } @@ -6466,7 +6587,7 @@ scroll_to_fraction(win_T *wp, int prev_height) if (wp == curwin) { - if (get_scrolloff_value()) + if (p_spsc && get_scrolloff_value()) update_topline(); curs_columns(FALSE); // validate w_wrow } @@ -6488,11 +6609,15 @@ win_new_width(win_T *wp, int width) wp->w_width = width; wp->w_lines_valid = 0; changed_line_abv_curs_win(wp); - invalidate_botline_win(wp); - if (wp == curwin) + // Handled in win_fix_scroll() + if (p_spsc) { - update_topline(); - curs_columns(TRUE); // validate w_wrow + invalidate_botline_win(wp); + if (wp == curwin) + { + update_topline(); + curs_columns(TRUE); // validate w_wrow + } } redraw_win_later(wp, UPD_NOT_VALID); wp->w_redr_status = TRUE; From 87e74d0e03c6c0267546b2e3a49316f3e84d9794 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 11 Sep 2022 20:12:15 +0100 Subject: [PATCH 27/28] patch 9.0.0446: message window may be positioned too low Problem: Message window may be positioned too low. Solution: Compute cmdline_row before computing the position. --- src/popupwin.c | 7 ++++++- src/testdir/dumps/Test_echowindow_5.dump | 8 ++++++++ src/version.c | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/testdir/dumps/Test_echowindow_5.dump diff --git a/src/popupwin.c b/src/popupwin.c index a33fa5f8b7..d02196ef50 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -1301,9 +1301,14 @@ popup_adjust_position(win_T *wp) wp->w_winrow = Rows - 1; } if (wp->w_popup_pos == POPPOS_BOTTOM) - // assume that each buffer line takes one screen line + { + // Assume that each buffer line takes one screen line, and one line + // for the top border. First make sure cmdline_row is valid, + // calling update_screen() will set it only later. + compute_cmdrow(); wp->w_winrow = MAX(cmdline_row - wp->w_buffer->b_ml.ml_line_count - 1, 0); + } if (!use_wantcol) center_hor = TRUE; diff --git a/src/testdir/dumps/Test_echowindow_5.dump b/src/testdir/dumps/Test_echowindow_5.dump new file mode 100644 index 0000000000..a87640c867 --- /dev/null +++ b/src/testdir/dumps/Test_echowindow_5.dump @@ -0,0 +1,8 @@ +>s+0&#ffffff0|o|m|e| |t|e|x|t| @65 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|═+0#e000002&@74 +|m|e|s@1|a|g|e| @67 +|o+0#0000000&|n|e| @71 +|t|w|o| @53|1|,|1| @10|A|l@1| diff --git a/src/version.c b/src/version.c index ec0f00b182..8da83dbc80 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 446, /**/ 445, /**/ From cf0995d7d7301e36c81cafa14e68782f1d3be2ad Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 11 Sep 2022 21:36:17 +0100 Subject: [PATCH 28/28] patch 9.0.0447: using :echowin while at the hit-enter prompt causes problems Problem: Using :echowin while at the hit-enter prompt causes problems. Solution: Do not prompt for :echowin. Postpone showing the message window. Start the timer when the window is displayed. --- src/ex_getln.c | 3 ++- src/message.c | 4 +++ src/popupwin.c | 27 ++++++++++++++++++-- src/screen.c | 8 +++--- src/testdir/dumps/Test_echowindow_6.dump | 8 ++++++ src/testdir/dumps/Test_echowindow_7.dump | 8 ++++++ src/testdir/test_messages.vim | 32 ++++++++++++++++++++++++ src/version.c | 2 ++ 8 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 src/testdir/dumps/Test_echowindow_6.dump create mode 100644 src/testdir/dumps/Test_echowindow_7.dump diff --git a/src/ex_getln.c b/src/ex_getln.c index d425b3effb..f9226de6e4 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -3890,7 +3890,8 @@ redrawcmd(void) void compute_cmdrow(void) { - if (exmode_active || msg_scrolled != 0) + // ignore "msg_scrolled" in update_screen(), it will be reset soon. + if (exmode_active || (msg_scrolled != 0 && !updating_screen)) cmdline_row = Rows - 1; else cmdline_row = W_WINROW(lastwin) + lastwin->w_height diff --git a/src/message.c b/src/message.c index e401882d1a..b68c089747 100644 --- a/src/message.c +++ b/src/message.c @@ -1157,6 +1157,10 @@ wait_return(int redraw) // need_wait_return to do it later. if (msg_silent != 0) return; +#ifdef HAS_MESSAGE_WINDOW + if (in_echowindow) + return; +#endif /* * When inside vgetc(), we can't wait for a typed character at all. diff --git a/src/popupwin.c b/src/popupwin.c index d02196ef50..fce4a2b811 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -31,6 +31,13 @@ static poppos_entry_T poppos_entries[] = { #ifdef HAS_MESSAGE_WINDOW // Window used for ":echowindow" static win_T *message_win = NULL; + +// Flag set when a message is added to the message window, timer is started +// when the message window is drawn. This might be after pressing Enter at the +// hit-enter prompt. +static int start_message_win_timer = FALSE; + +static void may_start_message_win_timer(win_T *wp); #endif static void popup_adjust_position(win_T *wp); @@ -4268,6 +4275,11 @@ update_popups(void (*win_update)(win_T *wp)) // Back to the normal zindex. screen_zindex = 0; + +#ifdef HAS_MESSAGE_WINDOW + // if this was the message window popup may start the timer now + may_start_message_win_timer(wp); +#endif } #if defined(FEAT_SEARCH_EXTRA) @@ -4513,8 +4525,18 @@ popup_show_message_win(void) popup_update_color(message_win, TYPE_MESSAGE_WIN); popup_show(message_win); } + start_message_win_timer = TRUE; + } +} + + static void +may_start_message_win_timer(win_T *wp) +{ + if (wp == message_win && start_message_win_timer) + { if (message_win->w_popup_timer != NULL) timer_start(message_win->w_popup_timer); + start_message_win_timer = FALSE; } } @@ -4552,8 +4574,9 @@ end_echowindow(void) { in_echowindow = FALSE; - // show the message window now - redraw_cmd(FALSE); + if ((State & MODE_HITRETURN) == 0) + // show the message window now + redraw_cmd(FALSE); // do not overwrite messages // TODO: only for message window diff --git a/src/screen.c b/src/screen.c index 12377d56bf..27f4848378 100644 --- a/src/screen.c +++ b/src/screen.c @@ -3038,18 +3038,18 @@ screenclear2(int doclear) screen_cleared = TRUE; // can use contents of ScreenLines now win_rest_invalid(firstwin); // redraw all regular windows -#ifdef FEAT_PROP_POPUP - popup_redraw_all(); // redraw all popup windows -#endif redraw_cmdline = TRUE; redraw_tabline = TRUE; if (must_redraw == UPD_CLEAR) // no need to clear again must_redraw = UPD_NOT_VALID; + msg_scrolled = 0; // compute_cmdrow() uses this compute_cmdrow(); +#ifdef FEAT_PROP_POPUP + popup_redraw_all(); // redraw all popup windows +#endif msg_row = cmdline_row; // put cursor on last line for messages msg_col = 0; screen_start(); // don't know where cursor is now - msg_scrolled = 0; // can't scroll back msg_didany = FALSE; msg_didout = FALSE; } diff --git a/src/testdir/dumps/Test_echowindow_6.dump b/src/testdir/dumps/Test_echowindow_6.dump new file mode 100644 index 0000000000..3bf63038a0 --- /dev/null +++ b/src/testdir/dumps/Test_echowindow_6.dump @@ -0,0 +1,8 @@ +|~+0#4040ff13#ffffff0| @73 +|~| @73 +|~| @73 +|~| @73 +|o+0#0000000&|n|e| @71 +|t|w|o| @71 +|t|h|r|e@1| @69 +|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_echowindow_7.dump b/src/testdir/dumps/Test_echowindow_7.dump new file mode 100644 index 0000000000..774495f479 --- /dev/null +++ b/src/testdir/dumps/Test_echowindow_7.dump @@ -0,0 +1,8 @@ +>s+0&#ffffff0|o|m|e| |t|e|x|t| @65 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|═+0#e000002&@74 +|l|a|t|e|r| |m|e|s@1|a|g|e| @61 +| +0#0000000&@74 +@57|1|,|1| @10|A|l@1| diff --git a/src/testdir/test_messages.vim b/src/testdir/test_messages.vim index 4a2deae1e6..6dc9a5b801 100644 --- a/src/testdir/test_messages.vim +++ b/src/testdir/test_messages.vim @@ -401,6 +401,28 @@ func Test_echowindow() echowindow 'line' n endfor endfunc + + def TwoMessages() + popup_clear() + set cmdheight=2 + redraw + timer_start(100, (_) => { + echowin 'message' + }) + echo 'one' + echo 'two' + enddef + + def ThreeMessages() + popup_clear() + redraw + timer_start(100, (_) => { + echowin 'later message' + }) + echo 'one' + echo 'two' + echo 'three' + enddef END call writefile(lines, 'XtestEchowindow') let buf = RunVimInTerminal('-S XtestEchowindow', #{rows: 8}) @@ -415,6 +437,16 @@ func Test_echowindow() call term_sendkeys(buf, ":call ManyMessages()\") call VerifyScreenDump(buf, 'Test_echowindow_4', {}) + call term_sendkeys(buf, ":call TwoMessages()\") + call VerifyScreenDump(buf, 'Test_echowindow_5', {}) + + call term_sendkeys(buf, ":call ThreeMessages()\") + sleep 120m + call VerifyScreenDump(buf, 'Test_echowindow_6', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_echowindow_7', {}) + " clean up call StopVimInTerminal(buf) call delete('XtestEchowindow') diff --git a/src/version.c b/src/version.c index 8da83dbc80..da11368ed5 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 447, /**/ 446, /**/