diff options
Diffstat (limited to 'src')
281 files changed, 8143 insertions, 2392 deletions
diff --git a/src/GvimExt/Make_ming.mak b/src/GvimExt/Make_ming.mak index 85017d8..06ec7b6 100644 --- a/src/GvimExt/Make_ming.mak +++ b/src/GvimExt/Make_ming.mak @@ -29,7 +29,7 @@ LDFLAGS += -static-libgcc -static-libstdc++ endif ifeq ($(CROSS),yes) -DEL = rm +DEL = rm -f ifeq ($(MINGWOLD),yes) CXXFLAGS := -O2 -fvtable-thunks else @@ -38,7 +38,7 @@ endif else CXXFLAGS := -O2 ifneq (sh.exe, $(SHELL)) -DEL = rm +DEL = rm -f else DEL = del endif diff --git a/src/GvimExt/Make_mvc.mak b/src/GvimExt/Make_mvc.mak index 7068d8f..132a584 100644 --- a/src/GvimExt/Make_mvc.mak +++ b/src/GvimExt/Make_mvc.mak @@ -19,25 +19,24 @@ WINVER = 0x0601 NODEBUG = 1 !endif -!ifdef PROCESSOR_ARCHITECTURE -# On Windows NT -! ifndef CPU +!ifndef CPU CPU = i386 -! if !defined(PLATFORM) && defined(TARGET_CPU) +! ifndef PLATFORM +! ifdef TARGET_CPU PLATFORM = $(TARGET_CPU) +! elseif defined(VSCMD_ARG_TGT_ARCH) +PLATFORM = $(VSCMD_ARG_TGT_ARCH) ! endif -! ifdef PLATFORM -! if ("$(PLATFORM)" == "x64") || ("$(PLATFORM)" == "X64") +! endif +! ifdef PLATFORM +! if ("$(PLATFORM)" == "x64") || ("$(PLATFORM)" == "X64") CPU = AMD64 -! elseif ("$(PLATFORM)" == "arm64") || ("$(PLATFORM)" == "ARM64") +! elseif ("$(PLATFORM)" == "arm64") || ("$(PLATFORM)" == "ARM64") CPU = ARM64 -! elseif ("$(PLATFORM)" != "x86") && ("$(PLATFORM)" != "X86") -! error *** ERROR Unknown target platform "$(PLATFORM)". Make aborted. -! endif +! elseif ("$(PLATFORM)" != "x86") && ("$(PLATFORM)" != "X86") +! error *** ERROR Unknown target platform "$(PLATFORM)". Make aborted. ! endif ! endif -!else -CPU = i386 !endif !ifdef SDK_INCLUDE_DIR @@ -80,7 +79,6 @@ all: gvimext.dll gvimext.dll: gvimext.obj \ gvimext.res $(link) $(lflags) -dll -def:gvimext.def -base:$(OFFSET) -out:$*.dll $** $(olelibsdll) shell32.lib comctl32.lib -subsystem:$(SUBSYSTEM) - if exist $*.dll.manifest mt -nologo -manifest $*.dll.manifest -outputresource:$*.dll;2 gvimext.obj: gvimext.h @@ -96,4 +94,3 @@ clean: - if exist gvimext.exp del gvimext.exp - if exist gvimext.obj del gvimext.obj - if exist gvimext.res del gvimext.res - - if exist gvimext.dll.manifest del gvimext.dll.manifest diff --git a/src/INSTALL b/src/INSTALL index efa03da..79d7584 100644 --- a/src/INSTALL +++ b/src/INSTALL @@ -178,12 +178,6 @@ There used to be a KDE version of Vim, using Qt libraries, but since it didn't work very well and there was no maintainer it was dropped. -Unix: COMPILING ON LINUX - -On Linux, when using -g to compile (which is default for gcc), the executable -will probably be statically linked. If you don't want this, remove the -g -option from CFLAGS. - Unix: PUTTING vimrc IN /etc Some Linux distributions prefer to put the global vimrc file in /etc, and the diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index 20ed903..8aeba67 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -130,7 +130,6 @@ ifndef STATIC_STDCPLUS STATIC_STDCPLUS=no endif - # Link against the shared version of libwinpthread by default. Set # STATIC_WINPTHREAD to "yes" to link against static version instead. ifndef STATIC_WINPTHREAD @@ -140,6 +139,12 @@ endif # This is used when STATIC_STDCPLUS=yes. HAS_GCC_EH=yes +# Reduce the size of the executables by using the --gc-sections linker +# option. Set USE_GC_SECTIONS to "no" if you see any issues with this. +ifndef USE_GC_SECTIONS +USE_GC_SECTIONS=yes +endif + # If the user doesn't want gettext, undefine it. ifeq (no, $(GETTEXT)) GETTEXT= @@ -179,7 +184,7 @@ ifeq ($(CROSS),yes) ifndef CROSS_COMPILE CROSS_COMPILE = i586-pc-mingw32msvc- endif -DEL = rm +DEL = rm -f MKDIR = mkdir -p DIRSLASH = / else @@ -207,7 +212,7 @@ CROSS_COMPILE = # In this case, unix-like commands can be used. # ifneq (sh.exe, $(SHELL)) -DEL = rm +DEL = rm -f MKDIR = mkdir -p DIRSLASH = / else @@ -386,14 +391,19 @@ endif # Python3 interface: # PYTHON3=[Path to Python3 directory] (Set inside Make_cyg.mak or Make_ming.mak) # DYNAMIC_PYTHON3=yes (to load the Python3 DLL dynamically) -# PYTHON3_VER=[Python3 version, eg 31, 32] (default is 36) +# PYTHON3_VER=[Python3 version, eg 31, 32] (default is 38) ifdef PYTHON3 ifndef DYNAMIC_PYTHON3 DYNAMIC_PYTHON3=yes endif + ifndef DYNAMIC_PYTHON3_STABLE_ABI + ifeq (yes,$(DYNAMIC_PYTHON3)) +DYNAMIC_PYTHON3_STABLE_ABI=yes + endif + endif ifndef PYTHON3_VER -PYTHON3_VER=36 +PYTHON3_VER=38 endif ifeq ($(DYNAMIC_PYTHON3_STABLE_ABI),yes) PYTHON3_NAME=python3 @@ -1001,6 +1011,9 @@ EXELFLAGS += -s endif ifeq ($(COVERAGE),yes) EXELFLAGS += --coverage + else ifndef MZSCHEME +EXELFLAGS += -nostdlib +EXECFLAGS = -DUSE_OWNSTARTUP endif DEFINES += $(DEF_GUI) -DVIMDLL OBJ += $(GUIOBJ) $(CUIOBJ) @@ -1093,6 +1106,16 @@ LIB += -lgcc_eh LIB += -Wl,-Bstatic -lwinpthread -Wl,-Bdynamic endif +# To reduce the file size +ifeq (yes, $(USE_GC_SECTIONS)) +CFLAGS += -ffunction-sections -fno-asynchronous-unwind-tables +CXXFLAGS += -fasynchronous-unwind-tables +LFLAGS += -Wl,--gc-sections + ifeq (yes, $(VIMDLL)) +EXELFLAGS += -Wl,--gc-sections + endif +endif + ifeq (yes, $(MAP)) LFLAGS += -Wl,-Map=$(TARGET).map endif @@ -1122,14 +1145,25 @@ $(EXEOBJG): | $(OUTDIR) $(EXEOBJC): | $(OUTDIR) ifeq ($(VIMDLL),yes) + ifneq ($(findstring -nostdlib,$(EXELFLAGS)),) + # -Wl,--entry needs to be specified when -nostdlib is used. + ifeq ($(ARCH),x86-64) +EXEENTRYC = -Wl,--entry=wmainCRTStartup +EXEENTRYG = -Wl,--entry=wWinMainCRTStartup + else ifeq ($(ARCH),i686) +EXEENTRYC = -Wl,--entry=_wmainCRTStartup +EXEENTRYG = -Wl,--entry=_wWinMainCRTStartup@0 + endif + endif + $(TARGET): $(OBJ) $(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid -lgdi32 $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(SODIUMLIB) $(GVIMEXE): $(EXEOBJG) $(VIMDLLBASE).dll - $(CC) -L. $(EXELFLAGS) -mwindows -o $@ $(EXEOBJG) -l$(VIMDLLBASE) + $(CC) -L. $(EXELFLAGS) -mwindows -o $@ $(EXEOBJG) -l$(VIMDLLBASE) $(EXEENTRYG) $(VIMEXE): $(EXEOBJC) $(VIMDLLBASE).dll - $(CC) -L. $(EXELFLAGS) -o $@ $(EXEOBJC) -l$(VIMDLLBASE) + $(CC) -L. $(EXELFLAGS) -o $@ $(EXEOBJC) -l$(VIMDLLBASE) $(EXEENTRYC) else $(TARGET): $(OBJ) $(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(SODIUMLIB) @@ -1160,10 +1194,13 @@ notags: clean: -$(DEL) $(OUTDIR)$(DIRSLASH)*.o + -$(DEL) $(OUTDIR)$(DIRSLASH)*.gcno + -$(DEL) $(OUTDIR)$(DIRSLASH)*.gcda -$(DEL) $(OUTDIR)$(DIRSLASH)*.res -$(DEL) $(OUTDIR)$(DIRSLASH)pathdef.c -rmdir $(OUTDIR) -$(DEL) $(MAIN_TARGET) vimrun.exe install.exe uninstall.exe + -$(DEL) *.gcno *.gcda -$(DEL) *.map ifdef PERL -$(DEL) if_perl.c @@ -1297,6 +1334,9 @@ $(OUTDIR)/gui_w32.o: gui_w32.c $(INCL) $(GUI_INCL) version.h $(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) $(CC) -c $(CFLAGS) if_cscope.c -o $@ +$(OUTDIR)/if_lua.o: if_lua.c $(INCL) + $(CC) -c $(CFLAGS:-fno-asynchronous-unwind-tables=) if_lua.c -o $@ + $(OUTDIR)/if_mzsch.o: if_mzsch.c $(INCL) $(MZSCHEME_INCL) $(MZ_EXTRA_DEP) $(CC) -c $(CFLAGS) if_mzsch.c -o $@ @@ -1330,10 +1370,10 @@ $(OUTDIR)/netbeans.o: netbeans.c $(INCL) $(NBDEBUG_INCL) $(NBDEBUG_SRC) $(CC) -c $(CFLAGS) netbeans.c -o $@ $(OUTDIR)/os_w32exec.o: os_w32exe.c $(INCL) - $(CC) -c $(CFLAGS) -UFEAT_GUI_MSWIN os_w32exe.c -o $@ + $(CC) -c $(CFLAGS) -UFEAT_GUI_MSWIN $(EXECFLAGS) os_w32exe.c -o $@ $(OUTDIR)/os_w32exeg.o: os_w32exe.c $(INCL) - $(CC) -c $(CFLAGS) os_w32exe.c -o $@ + $(CC) -c $(CFLAGS) $(EXECFLAGS) os_w32exe.c -o $@ $(OUTDIR)/os_win32.o: os_win32.c $(INCL) $(MZSCHEME_INCL) $(CC) -c $(CFLAGS) os_win32.c -o $@ diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index e58814b..49d8a33 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -80,7 +80,7 @@ # Python3 interface: # PYTHON3=[Path to Python3 directory] # DYNAMIC_PYTHON3=yes (to load the Python3 DLL dynamically) -# PYTHON3_VER=[Python3 version, eg 30, 31] (default is 36) +# PYTHON3_VER=[Python3 version, eg 30, 31] (default is 38) # # Ruby interface: # RUBY=[Path to Ruby directory] @@ -127,15 +127,20 @@ # # Optimization: OPTIMIZE=[SPACE, SPEED, MAXSPEED] (default is MAXSPEED) # -# Processor Version: CPUNR=[any, i686, sse, sse2, avx, avx2] (default is -# sse2) +# Processor Version: +# For x86: CPUNR=[any, i686, sse, sse2, avx, avx2, avx512] +# For x64: CPUNR=[sse2, avx, avx2, avx512] +# (default is sse2 (both x86 and x64)) # avx is available on Visual C++ 2010 and after. # avx2 is available on Visual C++ 2013 Update 2 and after. +# avx512 is available on Visual C++ 2017 and after. +# For ARM64: +# See: https://learn.microsoft.com/en-us/cpp/build/reference/arch-arm64 # # Version Support: WINVER=[0x0601, 0x0602, 0x0603, 0x0A00] (default is # 0x0601) # Supported versions depends on your target SDK, check SDKDDKVer.h -# See https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt +# See https://learn.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt # # Debug version: DEBUG=yes # Mapfile: MAP=[no, yes or lines] (default is yes) @@ -157,53 +162,56 @@ # you can set DEFINES on the command line, e.g., # nmake -f Make_mvc.mvc "DEFINES=-DEMACS_TAGS" -RM= del /f /q -PS= powershell.exe +RM = del /f /q -PSFLAGS= -NoLogo -NoProfile -Command +# Read MAJOR and MINOR from version.h. +!IF ![for /f "tokens=2,3" %I in (version.h) do \ + @if "%I"=="VIM_VERSION_MAJOR" ( \ + echo MAJOR=%J> .\major.tmp \ + ) else if "%I"=="VIM_VERSION_MINOR" ( \ + echo MINOR=%J> .\minor.tmp && exit \ + )] +!ENDIF -!IF ![$(PS) $(PSFLAGS) try{Out-File -FilePath '.\major.tmp' -InputObject \ - \"MAJOR=$$(((Select-String -Pattern 'VIM_VERSION_MAJOR\s+\d{1,2}' \ - -Path '.\version.h').Line[-2..-1^]-join '').Trim())\"} \ - catch{exit 1}] +!IF EXIST(.\major.tmp) ! INCLUDE .\major.tmp ! IF [$(RM) .\major.tmp] ! ENDIF !ELSE # Change this value for the new version -MAJOR= 9 +MAJOR = 9 !ENDIF -!IF ![$(PS) $(PSFLAGS) try{Out-File -FilePath '.\minor.tmp' -InputObject \ - \"MINOR=$$(((Select-String -Pattern 'VIM_VERSION_MINOR\s+\d{1,2}' \ - -Path '.\version.h').Line[-2..-1^]-join '').Trim())\"} \ - catch{exit 1}] +!IF EXIST(.\minor.tmp) ! INCLUDE .\minor.tmp ! IF [$(RM) .\minor.tmp] ! ENDIF !ELSE # Change this value for the new version -MINOR= 1 +MINOR = 1 !ENDIF -!IF ![$(PS) $(PSFLAGS) try{Out-File -FilePath '.\patchlvl.tmp' -InputObject \ - \"PATCHLEVEL=$$([decimal^]((Get-Content -Path '.\version.c' \ - -TotalCount ((Select-String -Pattern 'static int included_patches' \ - -Path '.\version.c').LineNumber+3))[-1^]).Trim().TrimEnd(','))\"} \ - catch{exit 1}] +# Read PATCHLEVEL from version.c. +!IF ![cmd.exe /V:ON /Q /C "set LINE=0&& set FIND=0&& \ + for /f "tokens=1,3 delims=, " %I in (version.c) do ( \ + set /A LINE+=1 > NUL && \ + if "%J"=="included_patches[^]" ( \ + set /A FIND=LINE+3 > NUL \ + ) else if "!LINE!"=="!FIND!" ( \ + echo PATCHLEVEL=%I> .\patchlvl.tmp && exit \ + ) \ + )"] +!ENDIF +!IF EXIST(.\patchlvl.tmp) ! INCLUDE .\patchlvl.tmp ! IF [$(RM) .\patchlvl.tmp] ! ENDIF !ENDIF - -# Build on Windows NT/XP - -TARGETOS = WINNT - !IFDEF PATCHLEVEL -RCFLAGS= -DVIM_VERSION_PATCHLEVEL=$(PATCHLEVEL) +RCFLAGS = -DVIM_VERSION_PATCHLEVEL=$(PATCHLEVEL) !ENDIF +!message Vim version: $(MAJOR).$(MINOR).$(PATCHLEVEL) !if "$(VIMDLL)" == "yes" @@ -257,38 +265,29 @@ OBJDIR = $(OBJDIR)V OBJDIR = $(OBJDIR)d !endif -!ifdef PROCESSOR_ARCHITECTURE -# We're on Windows NT or using VC 6+ -! ifdef CPU -ASSEMBLY_ARCHITECTURE=$(CPU) -# Using I386 for $ASSEMBLY_ARCHITECTURE doesn't work for VC7. -! if "$(CPU)" == "I386" +!ifdef CPU +! if "$(CPU)" == "I386" CPU = i386 -! endif -! else # !CPU +! endif +!else # !CPU CPU = i386 -! ifndef PLATFORM -! ifdef TARGET_CPU +! ifndef PLATFORM +! ifdef TARGET_CPU PLATFORM = $(TARGET_CPU) -! elseif defined(VSCMD_ARG_TGT_ARCH) +! elseif defined(VSCMD_ARG_TGT_ARCH) PLATFORM = $(VSCMD_ARG_TGT_ARCH) -! endif ! endif -! ifdef PLATFORM -! if ("$(PLATFORM)" == "x64") || ("$(PLATFORM)" == "X64") +! endif +! ifdef PLATFORM +! if ("$(PLATFORM)" == "x64") || ("$(PLATFORM)" == "X64") CPU = AMD64 -! elseif ("$(PLATFORM)" == "arm64") || ("$(PLATFORM)" == "ARM64") +! elseif ("$(PLATFORM)" == "arm64") || ("$(PLATFORM)" == "ARM64") CPU = ARM64 -! elseif ("$(PLATFORM)" != "x86") && ("$(PLATFORM)" != "X86") -! error *** ERROR Unknown target platform "$(PLATFORM)". Make aborted. -! endif -! endif # !PLATFORM -! endif -!else # !PROCESSOR_ARCHITECTURE -# We're on Windows 95 -CPU = i386 -!endif # !PROCESSOR_ARCHITECTURE -ASSEMBLY_ARCHITECTURE=$(CPU) +! elseif ("$(PLATFORM)" != "x86") && ("$(PLATFORM)" != "X86") +! error *** ERROR Unknown target platform "$(PLATFORM)". Make aborted. +! endif +! endif # !PLATFORM +!endif OBJDIR = $(OBJDIR)$(CPU) # Build a retail version by default @@ -303,7 +302,9 @@ MAKEFLAGS_GVIMEXT = DEBUG=yes LINK = link # Check VC version. -!if [echo MSVCVER=_MSC_VER> msvcver.c && $(CC) /EP msvcver.c > msvcver.~ 2> nul] +!if [echo MSVCVER=_MSC_VER> msvcver.c && \ + echo MSVC_FULL=_MSC_FULL_VER>> msvcver.c && \ + $(CC) /EP msvcver.c > msvcver.~ 2> nul] ! message *** ERROR ! message Cannot run Visual C to determine its version. Make sure cl.exe is in your PATH. ! message This can usually be done by running "vcvarsall.bat", located in the bin directory where Visual Studio was installed. @@ -324,19 +325,6 @@ LINK = link MSVC_MAJOR = ($(MSVCVER) / 100 - 5) MSVCRT_VER = ($(MSVCVER) / 100 * 10 - 50) -# Calculate MSVC_FULL. -!if [echo MSVC_FULL=_MSC_FULL_VER> msvcfullver.c && $(CC) /EP msvcfullver.c > msvcfullver.~ 2> nul] -! message *** ERROR -! message Cannot run Visual C to determine its version. Make sure cl.exe is in your PATH. -! message This can usually be done by running "vcvarsall.bat", located in the bin directory where Visual Studio was installed. -! error Make aborted. -!else -! include msvcfullver.~ -! if [del msvcfullver.c msvcfullver.~] -! endif -!endif - - # Calculate MSVCRT_VER !if [(set /a MSVCRT_VER="$(MSVCRT_VER)" > nul) && set MSVCRT_VER > msvcrtver.~] == 0 ! include msvcrtver.~ @@ -344,6 +332,11 @@ MSVCRT_VER = ($(MSVCVER) / 100 * 10 - 50) ! endif !endif +# Show the versions (for debugging). +#!message _MSC_VER=$(MSVCVER) +#!message _MSC_FULL_VER=$(MSVC_FULL) +#!message MSVCRT_VER=$(MSVCRT_VER) + # Base name of the msvcrXX.dll (vcruntimeXXX.dll) MSVCRT_NAME = vcruntime$(MSVCRT_VER) @@ -355,7 +348,7 @@ WINVER = 0x0601 # Use multiprocess build USE_MP = yes -!if "$(FEATURES)"=="" +!if "$(FEATURES)" == "" FEATURES = HUGE !endif @@ -374,7 +367,7 @@ CSCOPE_DEFS = -DFEAT_CSCOPE !endif !ifndef TERMINAL -! if "$(FEATURES)"=="HUGE" +! if "$(FEATURES)" == "HUGE" TERMINAL = yes ! else TERMINAL = no @@ -384,15 +377,15 @@ TERMINAL = no !if "$(TERMINAL)" == "yes" TERM_OBJ = \ $(OBJDIR)/terminal.obj \ - $(OBJDIR)/vterm_encoding.obj \ - $(OBJDIR)/vterm_keyboard.obj \ - $(OBJDIR)/vterm_mouse.obj \ - $(OBJDIR)/vterm_parser.obj \ - $(OBJDIR)/vterm_pen.obj \ - $(OBJDIR)/vterm_screen.obj \ - $(OBJDIR)/vterm_state.obj \ - $(OBJDIR)/vterm_unicode.obj \ - $(OBJDIR)/vterm_vterm.obj + $(OBJDIR)/libvterm/encoding.obj \ + $(OBJDIR)/libvterm/keyboard.obj \ + $(OBJDIR)/libvterm/mouse.obj \ + $(OBJDIR)/libvterm/parser.obj \ + $(OBJDIR)/libvterm/pen.obj \ + $(OBJDIR)/libvterm/screen.obj \ + $(OBJDIR)/libvterm/state.obj \ + $(OBJDIR)/libvterm/unicode.obj \ + $(OBJDIR)/libvterm/vterm.obj TERM_DEFS = -DFEAT_TERMINAL TERM_DEPS = \ libvterm/include/vterm.h \ @@ -403,7 +396,7 @@ TERM_DEPS = \ !endif !ifndef SOUND -! if "$(FEATURES)"=="HUGE" +! if "$(FEATURES)" == "HUGE" SOUND = yes ! else SOUND = no @@ -444,7 +437,7 @@ NETBEANS = $(GUI) !endif !ifndef CHANNEL -! if "$(FEATURES)"=="HUGE" || "$(TERMINAL)"=="yes" +! if "$(FEATURES)" == "HUGE" || "$(TERMINAL)" == "yes" CHANNEL = yes ! else CHANNEL = $(GUI) @@ -538,9 +531,10 @@ CON_LIB = $(CON_LIB) /DELAYLOAD:comdlg32.dll /DELAYLOAD:ole32.dll DelayImp.lib #VIMRUNTIMEDIR = somewhere CFLAGS = -c /W3 /GF /nologo -I. -Iproto -DHAVE_PATHDEF -DWIN32 -DHAVE_STDINT_H \ - $(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \ + $(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) \ $(NBDEBUG_DEFS) $(XPM_DEFS) $(SOD_DEFS) $(SOD_INC) \ - $(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) \ + $(CHANNEL_DEFS) $(DEFINES) \ + -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) \ /source-charset:utf-8 #>>>>> end of choices @@ -548,41 +542,57 @@ CFLAGS = -c /W3 /GF /nologo -I. -Iproto -DHAVE_PATHDEF -DWIN32 -DHAVE_STDINT_H \ DEL_TREE = rmdir /s /q -INTDIR=$(OBJDIR) -OUTDIR=$(OBJDIR) +INTDIR = $(OBJDIR) +OUTDIR = $(OBJDIR) ### Validate CPUNR -!ifndef CPUNR +!if "$(CPU)" == "i386" || "$(CPU)" == "AMD64" +! ifndef CPUNR # default to SSE2 CPUNR = sse2 -!elseif "$(CPUNR)" == "i386" || "$(CPUNR)" == "i486" || "$(CPUNR)" == "i586" +! elseif "$(CPU)" == "i386" \ + && ("$(CPUNR)" == "i386" || "$(CPUNR)" == "i486" || "$(CPUNR)" == "i586") # alias i386, i486 and i586 to i686 -! message *** WARNING CPUNR=$(CPUNR) is not a valid target architecture. -! message Windows 7 is the minimum target OS, with a minimum target -! message architecture of i686. -! message Retargeting to i686 +! message *** WARNING CPUNR=$(CPUNR) is not a valid target architecture. +! message Windows 7 is the minimum target OS, with a minimum target +! message architecture of i686. +! message Retargeting to i686 CPUNR = i686 -!elseif "$(CPUNR)" == "pentium4" +! elseif "$(CPUNR)" == "pentium4" # alias pentium4 to sse2 -! message *** WARNING CPUNR=pentium4 is deprecated in favour of sse2. -! message Retargeting to sse2. +! message *** WARNING CPUNR=pentium4 is deprecated in favour of sse2. +! message Retargeting to sse2. CPUNR = sse2 -!elseif "$(CPUNR)" != "any" && "$(CPUNR)" != "i686" && "$(CPUNR)" != "sse" && "$(CPUNR)" != "sse2" && "$(CPUNR)" != "avx" && "$(CPUNR)" != "avx2" -! error *** ERROR Unknown target architecture "$(CPUNR)". Make aborted. +! elseif ("$(CPU)" != "i386" \ + || ("$(CPUNR)" != "any" && "$(CPUNR)" != "i686" \ + && "$(CPUNR)" != "sse" )) \ + && "$(CPUNR)" != "sse2" && "$(CPUNR)" != "avx" \ + && "$(CPUNR)" != "avx2" && "$(CPUNR)" != "avx512" +! error *** ERROR Unknown target architecture "$(CPUNR)". Make aborted. +! endif +!elseif "$(CPU)" == "ARM64" +# TODO: Validate CPUNR. !endif # Convert processor ID to MVC-compatible number +!if "$(CPU)" == "i386" || "$(CPU)" == "AMD64" # IA32/SSE/SSE2 are only supported on x86 -!if "$(ASSEMBLY_ARCHITECTURE)" == "i386" && ("$(CPUNR)" == "i686" || "$(CPUNR)" == "any") +! if "$(CPU)" == "i386" \ + && ("$(CPUNR)" == "i686" || "$(CPUNR)" == "any") CPUARG = /arch:IA32 -!elseif "$(ASSEMBLY_ARCHITECTURE)" == "i386" && "$(CPUNR)" == "sse" +! elseif "$(CPU)" == "i386" && "$(CPUNR)" == "sse" CPUARG = /arch:SSE -!elseif "$(ASSEMBLY_ARCHITECTURE)" == "i386" && "$(CPUNR)" == "sse2" +! elseif "$(CPU)" == "i386" && "$(CPUNR)" == "sse2" CPUARG = /arch:SSE2 -!elseif "$(CPUNR)" == "avx" +! elseif "$(CPUNR)" == "avx" CPUARG = /arch:AVX -!elseif "$(CPUNR)" == "avx2" +! elseif "$(CPUNR)" == "avx2" CPUARG = /arch:AVX2 +! elseif "$(CPUNR)" == "avx512" +CPUARG = /arch:AVX512 +! endif +!elseif "$(CPU)" == "ARM64" && defined(CPUNR) +CPUARG = /arch:$(CPUNR) !endif # Pass CPUARG to GvimExt, to avoid using version-dependent defaults @@ -590,7 +600,7 @@ MAKEFLAGS_GVIMEXT = $(MAKEFLAGS_GVIMEXT) CPUARG="$(CPUARG)" !if "$(VIMDLL)" == "yes" VIMDLLBASE = vim -! if "$(ASSEMBLY_ARCHITECTURE)" == "i386" +! if "$(CPU)" == "i386" VIMDLLBASE = $(VIMDLLBASE)32 ! else VIMDLLBASE = $(VIMDLLBASE)64 @@ -797,6 +807,13 @@ OBJ = $(OBJ) $(OUTDIR)\os_w32dll.obj $(OUTDIR)\vimd.res EXEOBJC = $(OUTDIR)\os_w32exec.obj $(OUTDIR)\vimc.res EXEOBJG = $(OUTDIR)\os_w32exeg.obj $(OUTDIR)\vimg.res CFLAGS = $(CFLAGS) -DVIMDLL +! ifdef MZSCHEME +EXECFLAGS = +EXELIBC = $(LIBC) +! else +EXECFLAGS = -DUSE_OWNSTARTUP /GS- +EXELIBC = +! endif !else OBJ = $(OBJ) $(OUTDIR)\os_w32exe.obj $(OUTDIR)\vim.res !endif @@ -949,11 +966,9 @@ LUA_LIB = "$(LUA)\lib\lua$(LUA_VER).lib" ! endif !endif -!ifdef PYTHON -! ifdef PYTHON3 -DYNAMIC_PYTHON=yes -DYNAMIC_PYTHON3=yes -! endif +!if defined(PYTHON) && defined(PYTHON3) +DYNAMIC_PYTHON = yes +DYNAMIC_PYTHON3 = yes !endif # PYTHON interface @@ -979,8 +994,13 @@ PYTHON_LIB = "$(PYTHON)\libs\python$(PYTHON_VER).lib" # PYTHON3 interface !ifdef PYTHON3 +! ifndef DYNAMIC_PYTHON3_STABLE_ABI +! if "$(DYNAMIC_PYTHON3)" == "yes" +DYNAMIC_PYTHON3_STABLE_ABI = yes +! endif +! endif ! ifndef PYTHON3_VER -PYTHON3_VER = 36 +PYTHON3_VER = 38 ! endif ! if "$(DYNAMIC_PYTHON3_STABLE_ABI)" == "yes" PYTHON3_NAME = python3 @@ -1018,13 +1038,13 @@ PYTHON3_LIB = "$(PYTHON3)\libs\$(PYTHON3_NAME).lib" MZSCHEME_VER = 3m_a0solc ! endif ! ifndef MZSCHEME_COLLECTS -MZSCHEME_COLLECTS=$(MZSCHEME)\collects +MZSCHEME_COLLECTS = $(MZSCHEME)\collects ! endif CFLAGS = $(CFLAGS) -DFEAT_MZSCHEME -I "$(MZSCHEME)\include" ! if EXIST("$(MZSCHEME)\lib\msvc\libmzsch$(MZSCHEME_VER).lib") -MZSCHEME_MAIN_LIB=mzsch +MZSCHEME_MAIN_LIB = mzsch ! else -MZSCHEME_MAIN_LIB=racket +MZSCHEME_MAIN_LIB = racket ! endif ! if (EXIST("$(MZSCHEME)\lib\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).dll") \ && !EXIST("$(MZSCHEME)\lib\libmzgc$(MZSCHEME_VER).dll")) \ @@ -1062,7 +1082,7 @@ MZSCHEME_LIB = "$(MZSCHEME)\lib\msvc\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).lib" ! endif ! else MZSCHEME_LIB = "$(MZSCHEME)\lib\msvc\libmzgc$(MZSCHEME_VER).lib" \ - "$(MZSCHEME)\lib\msvc\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).lib" + "$(MZSCHEME)\lib\msvc\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).lib" ! endif ! endif MZSCHEME_OBJ = $(OUTDIR)\if_mzsch.obj @@ -1164,7 +1184,8 @@ RUBY_INSTALL_NAME = x64-$(RUBY_MSVCRT_NAME)-ruby$(RUBY_API_VER) ! message Ruby requested (version $(RUBY_VER)) - root dir is "$(RUBY)" CFLAGS = $(CFLAGS) -DFEAT_RUBY RUBY_OBJ = $(OUTDIR)\if_ruby.obj -RUBY_INC = /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)" /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)\$(RUBY_PLATFORM)" +RUBY_INC = /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)" \ + /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)\$(RUBY_PLATFORM)" RUBY_LIB = "$(RUBY)\lib\$(RUBY_INSTALL_NAME).lib" # Do we want to load Ruby dynamically? ! if "$(DYNAMIC_RUBY)" == "yes" @@ -1214,14 +1235,15 @@ LINK_PDB = /PDB:$(VIM).pdb -debug !message # CFLAGS with /Fo$(OUTDIR)/ -CFLAGS_OUTDIR=$(CFLAGS) /Fo$(OUTDIR)/ +CFLAGS_OUTDIR = $(CFLAGS) /Fo$(OUTDIR)/ PATHDEF_SRC = $(OUTDIR)\pathdef.c LINKARGS1 = /nologo LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(LIBC) $(OLE_LIB) \ - $(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \ - $(TCL_LIB) $(SOUND_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(SOD_LIB) $(LINK_PDB) + $(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) \ + $(PYTHON3_LIB) $(RUBY_LIB) $(TCL_LIB) $(SOUND_LIB) \ + $(NETBEANS_LIB) $(XPM_LIB) $(SOD_LIB) $(LINK_PDB) !ifdef NODEBUG # Add /opt:ref to remove unreferenced functions and data even when /DEBUG is @@ -1281,36 +1303,40 @@ all: $(MAIN_TARGET) \ !if "$(VIMDLL)" == "yes" -$(VIMDLLBASE).dll: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \ - $(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \ - $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \ - version.c version.h +$(VIMDLLBASE).dll: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) \ + $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) $(LUA_OBJ) $(PERL_OBJ) \ + $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \ + $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \ + $(XPM_OBJ) version.c version.h $(CC) $(CFLAGS_OUTDIR) version.c $(LINK) @<< -$(LINKARGS1) /dll -out:$(VIMDLLBASE).dll $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) -$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) -$(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) -$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2) +$(LINKARGS1) /dll -out:$(VIMDLLBASE).dll $(OBJ) $(XDIFF_OBJ) +$(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) +$(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ) +$(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2) << $(GVIM).exe: $(OUTDIR) $(EXEOBJG) $(VIMDLLBASE).dll - $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(GVIM).exe $(EXEOBJG) $(VIMDLLBASE).lib $(LIBC) + $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(GVIM).exe \ + $(EXEOBJG) $(VIMDLLBASE).lib $(EXELIBC) $(VIM).exe: $(OUTDIR) $(EXEOBJC) $(VIMDLLBASE).dll - $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM_CON) -out:$(VIM).exe $(EXEOBJC) $(VIMDLLBASE).lib $(LIBC) + $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM_CON) -out:$(VIM).exe \ + $(EXEOBJC) $(VIMDLLBASE).lib $(EXELIBC) !else -$(VIM).exe: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \ - $(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \ - $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \ - version.c version.h +$(VIM).exe: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) \ + $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) $(LUA_OBJ) $(PERL_OBJ) \ + $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \ + $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \ + $(XPM_OBJ) version.c version.h $(CC) $(CFLAGS_OUTDIR) version.c $(LINK) @<< -$(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) -$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) -$(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) -$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2) +$(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ) +$(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) +$(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ) +$(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2) << !endif @@ -1320,18 +1346,20 @@ $(VIM): $(VIM).exe $(OUTDIR): if not exist $(OUTDIR)/nul mkdir $(OUTDIR:/=\) -CFLAGS_INST = /nologo /O2 -DNDEBUG -DWIN32 -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) $(CFLAGS_DEPR) +$(OUTDIR)/libvterm: $(OUTDIR) + if not exist $(OUTDIR)/libvterm/nul mkdir $(OUTDIR:/=\)\libvterm + +CFLAGS_INST = /nologo /O2 -DNDEBUG -DWIN32 -DWINVER=$(WINVER) \ + -D_WIN32_WINNT=$(WINVER) $(CFLAGS_DEPR) !IFDEF PATCHLEVEL -CFLAGS_INST= $(CFLAGS_INST) -DVIM_VERSION_PATCHLEVEL=$(PATCHLEVEL) +CFLAGS_INST = $(CFLAGS_INST) -DVIM_VERSION_PATCHLEVEL=$(PATCHLEVEL) !ENDIF install.exe: dosinst.c dosinst.h version.h - $(CC) $(CFLAGS_INST) dosinst.c kernel32.lib shell32.lib \ + $(CC) $(CFLAGS_INST) /Fe$@ dosinst.c kernel32.lib shell32.lib \ user32.lib ole32.lib advapi32.lib uuid.lib \ -link -subsystem:$(SUBSYSTEM_TOOLS) - - if exist install.exe del install.exe - ren dosinst.exe install.exe uninstall.exe: uninstall.c dosinst.h version.h $(CC) $(CFLAGS_INST) uninstall.c shell32.lib advapi32.lib \ @@ -1366,12 +1394,16 @@ clean: testclean - if exist $(OUTDIR)/nul $(DEL_TREE) $(OUTDIR) - if exist *.obj del *.obj - if exist $(VIM).exe del $(VIM).exe + - if exist $(VIM).exp del $(VIM).exp + - if exist $(VIM).lib del $(VIM).lib - if exist $(VIM).ilk del $(VIM).ilk - if exist $(VIM).pdb del $(VIM).pdb - if exist $(VIM).map del $(VIM).map - if exist $(VIM).ncb del $(VIM).ncb !if "$(VIMDLL)" == "yes" - if exist $(GVIM).exe del $(GVIM).exe + - if exist $(GVIM).exp del $(GVIM).exp + - if exist $(GVIM).lib del $(GVIM).lib - if exist $(GVIM).map del $(GVIM).map - if exist $(VIMDLLBASE).dll del $(VIMDLLBASE).dll - if exist $(VIMDLLBASE).ilk del $(VIMDLLBASE).ilk @@ -1409,7 +1441,8 @@ cmdidxs: ex_cmds.h # - change nv_cmds[] in nv_cmds.h to add the new normal/visual mode command. # - run "make nvcmdidxs" to generate nv_cmdidxs.h nvcmdidxs: nv_cmds.h - $(CC) /nologo -I. -Iproto -DNDEBUG create_nvcmdidxs.c -link -subsystem:$(SUBSYSTEM_TOOLS) + $(CC) /nologo -I. -Iproto -DNDEBUG create_nvcmdidxs.c \ + -link -subsystem:$(SUBSYSTEM_TOOLS) vim --clean -N -X --not-a-term -u create_nvcmdidxs.vim -c quit -del create_nvcmdidxs.exe @@ -1420,7 +1453,7 @@ test: testgvim testgui: cd testdir - $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\gvim + $(MAKE) /NOLOGO -f Make_mvc.mak "VIMPROG=..\gvim.exe" cd .. testtiny: @@ -1430,7 +1463,7 @@ testtiny: testgvimtiny: cd testdir - $(MAKE) /NOLOGO -f Make_mvc.mak tiny VIMPROG=..\gvim + $(MAKE) /NOLOGO -f Make_mvc.mak "VIMPROG=..\gvim.exe" tiny cd .. testclean: @@ -1471,15 +1504,15 @@ test_vim9: ########################################################################### # Create a default rule for transforming .c files to .obj files in $(OUTDIR) -.c{$(OUTDIR)/}.obj:: +.c{$(OUTDIR)}.obj:: $(CC) $(CFLAGS_OUTDIR) $< # Create a default rule for xdiff. -{xdiff/}.c{$(OUTDIR)/}.obj:: +{xdiff}.c{$(OUTDIR)}.obj:: $(CC) $(CFLAGS_OUTDIR) $< # Create a default rule for transforming .cpp files to .obj files in $(OUTDIR) -.cpp{$(OUTDIR)/}.obj:: +.cpp{$(OUTDIR)}.obj:: $(CC) $(CFLAGS_OUTDIR) $< $(OUTDIR)/alloc.obj: $(OUTDIR) alloc.c $(INCL) @@ -1605,8 +1638,7 @@ $(OUTDIR)/if_cscope.obj: $(OUTDIR) if_cscope.c $(INCL) $(OUTDIR)/if_lua.obj: $(OUTDIR) if_lua.c $(INCL) $(CC) $(CFLAGS_OUTDIR) $(LUA_INC) if_lua.c -auto/if_perl.c : if_perl.xs typemap - -if not exist auto/nul mkdir auto +auto/if_perl.c: if_perl.xs typemap $(XSUBPP) -prototypes -typemap $(XSUBPP_TYPEMAP) \ -typemap typemap if_perl.xs -output $@ @@ -1638,7 +1670,6 @@ $(OUTDIR)/if_tcl.obj: $(OUTDIR) if_tcl.c $(INCL) $(CC) $(CFLAGS_OUTDIR) $(TCL_INC) if_tcl.c $(OUTDIR)/iscygpty.obj: $(OUTDIR) iscygpty.c $(CUI_INCL) - $(CC) $(CFLAGS_OUTDIR) iscygpty.c $(OUTDIR)/job.obj: $(OUTDIR) job.c $(INCL) @@ -1701,10 +1732,10 @@ $(OUTDIR)/os_w32dll.obj: $(OUTDIR) os_w32dll.c $(OUTDIR)/os_w32exe.obj: $(OUTDIR) os_w32exe.c $(INCL) $(OUTDIR)/os_w32exec.obj: $(OUTDIR) os_w32exe.c $(INCL) - $(CC) $(CFLAGS:-DFEAT_GUI_MSWIN=) /Fo$@ os_w32exe.c + $(CC) $(CFLAGS:-DFEAT_GUI_MSWIN=) $(EXECFLAGS) /Fo$@ os_w32exe.c $(OUTDIR)/os_w32exeg.obj: $(OUTDIR) os_w32exe.c $(INCL) - $(CC) $(CFLAGS) /Fo$@ os_w32exe.c + $(CC) $(CFLAGS) $(EXECFLAGS) /Fo$@ os_w32exe.c $(OUTDIR)/pathdef.obj: $(OUTDIR) $(PATHDEF_SRC) $(INCL) $(CC) $(CFLAGS_OUTDIR) $(PATHDEF_SRC) @@ -1804,7 +1835,8 @@ $(OUTDIR)/vimg.res: $(OUTDIR) vim.rc vim.manifest version.h gui_w32_rc.h \ $(OUTDIR)/vimd.res: $(OUTDIR) vim.rc version.h gui_w32_rc.h \ tools.bmp tearoff.bmp vim.ico vim_error.ico \ vim_alert.ico vim_info.ico vim_quest.ico - $(RC) /nologo /l 0x409 /Fo$@ $(RCFLAGS) -DRCDLL -DVIMDLLBASE=\"$(VIMDLLBASE)\" vim.rc + $(RC) /nologo /l 0x409 /Fo$@ $(RCFLAGS) \ + -DRCDLL -DVIMDLLBASE=\"$(VIMDLLBASE)\" vim.rc !else $(OUTDIR)/vim.res: $(OUTDIR) vim.rc vim.manifest version.h gui_w32_rc.h \ tools.bmp tearoff.bmp vim.ico vim_error.ico \ @@ -1825,32 +1857,27 @@ CCCTERM = $(CC) $(CFLAGS) -Ilibvterm/include -DINLINE="" \ -DGET_SPECIAL_PTY_TYPE_FUNCTION=get_special_pty_type \ -D_CRT_SECURE_NO_WARNINGS -$(OUTDIR)/vterm_encoding.obj: $(OUTDIR) libvterm/src/encoding.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/encoding.c +# Create a default rule for vterm. +{libvterm/src}.c{$(OUTDIR)/libvterm}.obj:: + $(CCCTERM) /Fo$(OUTDIR)/libvterm/ $< + +$(OUTDIR)/libvterm/encoding.obj: $(OUTDIR)/libvterm libvterm/src/encoding.c $(TERM_DEPS) -$(OUTDIR)/vterm_keyboard.obj: $(OUTDIR) libvterm/src/keyboard.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/keyboard.c +$(OUTDIR)/libvterm/keyboard.obj: $(OUTDIR)/libvterm libvterm/src/keyboard.c $(TERM_DEPS) -$(OUTDIR)/vterm_mouse.obj: $(OUTDIR) libvterm/src/mouse.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/mouse.c +$(OUTDIR)/libvterm/mouse.obj: $(OUTDIR)/libvterm libvterm/src/mouse.c $(TERM_DEPS) -$(OUTDIR)/vterm_parser.obj: $(OUTDIR) libvterm/src/parser.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/parser.c +$(OUTDIR)/libvterm/parser.obj: $(OUTDIR)/libvterm libvterm/src/parser.c $(TERM_DEPS) -$(OUTDIR)/vterm_pen.obj: $(OUTDIR) libvterm/src/pen.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/pen.c +$(OUTDIR)/libvterm/pen.obj: $(OUTDIR)/libvterm libvterm/src/pen.c $(TERM_DEPS) -$(OUTDIR)/vterm_screen.obj: $(OUTDIR) libvterm/src/screen.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/screen.c +$(OUTDIR)/libvterm/screen.obj: $(OUTDIR)/libvterm libvterm/src/screen.c $(TERM_DEPS) -$(OUTDIR)/vterm_state.obj: $(OUTDIR) libvterm/src/state.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/state.c +$(OUTDIR)/libvterm/state.obj: $(OUTDIR)/libvterm libvterm/src/state.c $(TERM_DEPS) -$(OUTDIR)/vterm_unicode.obj: $(OUTDIR) libvterm/src/unicode.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/unicode.c +$(OUTDIR)/libvterm/unicode.obj: $(OUTDIR)/libvterm libvterm/src/unicode.c $(TERM_DEPS) -$(OUTDIR)/vterm_vterm.obj: $(OUTDIR) libvterm/src/vterm.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/vterm.c +$(OUTDIR)/libvterm/vterm.obj: $(OUTDIR)/libvterm libvterm/src/vterm.c $(TERM_DEPS) # $CFLAGS may contain backslashes, quotes and chevrons, escape them all. diff --git a/src/Makefile b/src/Makefile index 71578eb..257742f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2189,7 +2189,7 @@ test check: unittests $(TERM_TEST) scripttests scripttests: $(MAKE) -f Makefile $(VIMTARGET) if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \ - cd $(PODIR); $(MAKE) -f Makefile check VIM=../$(VIMTARGET); \ + cd $(PODIR); $(MAKE) -f Makefile check VIMPROG=../$(VIMTARGET); \ fi -if test $(VIMTARGET) != vim -a ! -r vim; then \ ln -s $(VIMTARGET) vim; \ @@ -2354,10 +2354,8 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(VIMTARGET) $(DEST_RT) \ cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)" -a -f tags; then \ mv -f tags tags.dist; fi @echo generating help tags - # We can assume Vim was build, but it may not have been installed, - # thus use the executable in the current directory. - -@BUILD_DIR="`pwd`"; cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)"; then \ - $(MAKE) VIMEXE="$$BUILD_DIR/$(VIMTARGET)" vimtags; fi + -@BUILD_DIR=`pwd`; cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)"; then \ + $(MAKE) VIMPROG="$$BUILD_DIR/$(VIMTARGET)" vimtags; fi cd $(HELPSOURCE); \ files=`ls *.txt tags`; \ files="$$files `ls *.??x tags-?? 2>/dev/null || true`"; \ @@ -2626,7 +2624,7 @@ ICONTHEMEPATH = $(DATADIR)/icons/hicolor DESKTOPPATH = $(DESTDIR)$(DATADIR)/applications KDEPATH = $(HOME)/.kde/share/icons install-icons: - if test -n "$(DESTDIR)"; then \ + if test -n "$(DESTDIR)$(DATADIR)"; then \ $(MKDIR_P) $(ICON48PATH) $(ICON32PATH) \ $(ICON16PATH) $(DESKTOPPATH); \ fi @@ -2847,6 +2845,8 @@ uninstall_runtime: -rm -f $(SYS_OPTWIN_FILE) -rm -f $(DEST_COL)/*.vim $(DEST_COL)/README.txt -rm -rf $(DEST_COL)/tools + -rm -f $(DESKTOPPATH)/vim.desktop $(DESKTOPPATH)/gvim.desktop + -rm -f $(ICON16PATH)/gvim.png $(ICON32PATH)/gvim.png $(ICON48PATH)/gvim.png -rm -rf $(DEST_COL)/lists -rm -f $(DEST_SYN)/shared/*.vim $(DEST_SYN)/shared/README.txt -rm -f $(DEST_SYN)/modula2/opt/*.vim diff --git a/src/arglist.c b/src/arglist.c index 187e16e..8825c8e 100644 --- a/src/arglist.c +++ b/src/arglist.c @@ -184,6 +184,8 @@ alist_set( /* * Add file "fname" to argument list "al". * "fname" must have been allocated and "al" must have been checked for room. + * + * May trigger Buf* autocommands */ void alist_add( @@ -196,6 +198,7 @@ alist_add( if (check_arglist_locked() == FAIL) return; arglist_locked = TRUE; + curwin->w_locked = TRUE; #ifdef BACKSLASH_IN_FILENAME slash_adjust(fname); @@ -207,6 +210,7 @@ alist_add( ++al->al_ga.ga_len; arglist_locked = FALSE; + curwin->w_locked = FALSE; } #if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) @@ -365,6 +369,7 @@ alist_add_list( mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]), (ARGCOUNT - after) * sizeof(aentry_T)); arglist_locked = TRUE; + curwin->w_locked = TRUE; for (i = 0; i < count; ++i) { int flags = BLN_LISTED | (will_edit ? BLN_CURBUF : 0); @@ -373,6 +378,7 @@ alist_add_list( ARGLIST[after + i].ae_fnum = buflist_add(files[i], flags); } arglist_locked = FALSE; + curwin->w_locked = FALSE; ALIST(curwin)->al_ga.ga_len += count; if (old_argcount > 0 && curwin->w_arg_idx >= after) curwin->w_arg_idx += count; diff --git a/src/auto/configure b/src/auto/configure index 98b9580..4a99071 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -1575,7 +1575,7 @@ Optional Packages: --with-python-command=NAME name of the Python 2 command (default: python2 or python) --with-python-config-dir=PATH Python's config directory (deprecated) --with-python3-command=NAME name of the Python 3 command (default: python3 or python) - --with-python3-stable-abi=VERSION stable ABI version to target (e.g. 3.8) + --with-python3-stable-abi=VERSION stable ABI version to target (default: 3.8) --with-python3-config-dir=PATH Python's config directory (deprecated) --with-tclsh=PATH which tclsh to use (default: tclsh8.0) --with-ruby-command=RUBY name of the Ruby command (default: ruby) @@ -7083,14 +7083,21 @@ printf %s "checking Python is 3.0 or better... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yep" >&5 printf "%s\n" "yep" >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --with-python3-stable-abi argument" >&5 + python3_stable_abi_default=3.8 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --with-python3-stable-abi argument" >&5 printf %s "checking --with-python3-stable-abi argument... " >&6; } # Check whether --with-python3-stable-abi was given. if test ${with_python3_stable_abi+y} then : - withval=$with_python3_stable_abi; vi_cv_var_python3_stable_abi="$withval"; { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $vi_cv_var_python3_stable_abi" >&5 + withval=$with_python3_stable_abi; + if test "X$withval" = "Xyes"; then + vi_cv_var_python3_stable_abi=$python3_stable_abi_default + else + vi_cv_var_python3_stable_abi="$withval" + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $vi_cv_var_python3_stable_abi" >&5 printf "%s\n" "$vi_cv_var_python3_stable_abi" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -15876,6 +15883,30 @@ then : fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dgettext" >&5 +printf %s "checking for dgettext... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <libintl.h> +int +main (void) +{ +dgettext("Test", "Test"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; printf "%s\n" "#define HAVE_DGETTEXT 1" >>confdefs.h + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _nl_msg_cat_cntr" >&5 printf %s "checking for _nl_msg_cat_cntr... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext diff --git a/src/autocmd.c b/src/autocmd.c index 8380f8a..00f41bd 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -120,6 +120,7 @@ static keyvalue_T event_tab[] = { KEYVALUE_ENTRY(EVENT_CURSORHOLD, "CursorHold"), KEYVALUE_ENTRY(EVENT_CURSORHOLDI, "CursorHoldI"), KEYVALUE_ENTRY(EVENT_CURSORMOVED, "CursorMoved"), + KEYVALUE_ENTRY(EVENT_CURSORMOVEDC, "CursorMovedC"), KEYVALUE_ENTRY(EVENT_CURSORMOVEDI, "CursorMovedI"), KEYVALUE_ENTRY(EVENT_DIFFUPDATED, "DiffUpdated"), KEYVALUE_ENTRY(EVENT_DIRCHANGED, "DirChanged"), @@ -154,6 +155,7 @@ static keyvalue_T event_tab[] = { KEYVALUE_ENTRY(EVENT_INSERTENTER, "InsertEnter"), KEYVALUE_ENTRY(EVENT_INSERTLEAVE, "InsertLeave"), KEYVALUE_ENTRY(EVENT_INSERTLEAVEPRE, "InsertLeavePre"), + KEYVALUE_ENTRY(EVENT_KEYINPUTPRE, "KeyInputPre"), KEYVALUE_ENTRY(EVENT_MENUPOPUP, "MenuPopup"), KEYVALUE_ENTRY(EVENT_MODECHANGED, "ModeChanged"), KEYVALUE_ENTRY(EVENT_OPTIONSET, "OptionSet"), @@ -2021,6 +2023,15 @@ has_insertcharpre(void) } /* + * Return TRUE when there is an KeyInputPre autocommand defined. + */ + int +has_keyinputpre(void) +{ + return (first_autopat[(int)EVENT_KEYINPUTPRE] != NULL); +} + +/* * Return TRUE when there is an CmdUndefined autocommand defined. */ int @@ -2250,10 +2261,12 @@ apply_autocmds_group( || event == EVENT_CMDLINECHANGED || event == EVENT_CMDLINEENTER || event == EVENT_CMDLINELEAVE + || event == EVENT_CURSORMOVEDC || event == EVENT_CMDWINENTER || event == EVENT_CMDWINLEAVE || event == EVENT_CMDUNDEFINED || event == EVENT_FUNCUNDEFINED + || event == EVENT_KEYINPUTPRE || event == EVENT_REMOTEREPLY || event == EVENT_SPELLFILEMISSING || event == EVENT_QUICKFIXCMDPRE diff --git a/src/buffer.c b/src/buffer.c index cbec9b9..34500e4 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -50,6 +50,7 @@ static void free_buffer(buf_T *); static void free_buffer_stuff(buf_T *buf, int free_options); static int bt_nofileread(buf_T *buf); static void no_write_message_buf(buf_T *buf); +static int do_buffer_ext(int action, int start, int dir, int count, int flags); #ifdef UNIX # define dev_T dev_t @@ -750,10 +751,16 @@ aucmd_abort: */ if (wipe_buf) { + tabpage_T *tp; + win_T *wp; + // Do not wipe out the buffer if it is used in a window. if (buf->b_nwindows > 0) return FALSE; + FOR_ALL_TAB_WINDOWS(tp, wp) + mark_forget_file(wp, buf->b_fnum); + if (action == DOBUF_WIPE_REUSE) { // we can re-use this buffer number, store it @@ -1100,13 +1107,30 @@ goto_buffer( { bufref_T old_curbuf; int save_sea = swap_exists_action; + int skip_help_buf; + + switch (eap->cmdidx) + { + case CMD_bnext: + case CMD_sbnext: + case CMD_bNext: + case CMD_bprevious: + case CMD_sbNext: + case CMD_sbprevious: + skip_help_buf = TRUE; + break; + default: + skip_help_buf = FALSE; + break; + } set_bufref(&old_curbuf, curbuf); if (swap_exists_action == SEA_NONE) swap_exists_action = SEA_DIALOG; - (void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO, - start, dir, count, eap->forceit); + (void)do_buffer_ext(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO, start, dir, count, + (eap->forceit ? DOBUF_FORCEIT : 0) | + (skip_help_buf ? DOBUF_SKIPHELP : 0)); if (swap_exists_action == SEA_QUIT && *eap->cmd == 's') { #if defined(FEAT_EVAL) @@ -1337,8 +1361,11 @@ do_buffer_ext( if (buf == NULL) buf = lastbuf; } - // don't count unlisted buffers - if (unload || buf->b_p_bl) + // Don't count unlisted buffers. + // Avoid non-help buffers if the starting point was a non-help buffer and + // vice-versa. + if (unload || (buf->b_p_bl + && ((flags & DOBUF_SKIPHELP) == 0 || buf->b_help == bp->b_help))) { --count; bp = NULL; // use this buffer as new starting point @@ -1457,7 +1484,7 @@ do_buffer_ext( // (unless it's the only window). Repeat this so long as we end up in // a window with this buffer. while (buf == curbuf - && !(curwin->w_closing || curwin->w_buffer->b_locked > 0) + && !(win_locked(curwin) || curwin->w_buffer->b_locked > 0) && (!ONE_WINDOW || first_tabpage->tp_next != NULL)) { if (win_close(curwin, FALSE) == FAIL) @@ -5443,7 +5470,7 @@ ex_buffer_all(exarg_T *eap) : wp->w_width != Columns) || (had_tab > 0 && wp != firstwin)) && !ONE_WINDOW - && !(wp->w_closing || wp->w_buffer->b_locked > 0) + && !(win_locked(wp) || wp->w_buffer->b_locked > 0) && !win_unlisted(wp)) { if (win_close(wp, FALSE) == FAIL) diff --git a/src/bufwrite.c b/src/bufwrite.c index c9d9875..23cd884 100644 --- a/src/bufwrite.c +++ b/src/bufwrite.c @@ -1350,7 +1350,7 @@ buf_write( p = copybuf + STRLEN(copybuf); if (after_pathsep(copybuf, p) && p[-1] == p[-2]) // Ends with '//', use full path - if ((p = make_percent_swname(copybuf, fname)) != NULL) + if ((p = make_percent_swname(copybuf, p, fname)) != NULL) { backup = modname(p, backup_ext, FALSE); vim_free(p); @@ -1564,7 +1564,7 @@ buf_write( p = IObuff + STRLEN(IObuff); if (after_pathsep(IObuff, p) && p[-1] == p[-2]) // path ends with '//', use full path - if ((p = make_percent_swname(IObuff, fname)) != NULL) + if ((p = make_percent_swname(IObuff, p, fname)) != NULL) { backup = modname(p, backup_ext, FALSE); vim_free(p); diff --git a/src/change.c b/src/change.c index dacc06f..72d01c5 100644 --- a/src/change.c +++ b/src/change.c @@ -1355,17 +1355,17 @@ del_bytes( mch_memmove(newp + col, oldp + col + count, (size_t)movelen); if (alloc_newp) ml_replace(lnum, newp, FALSE); -#ifdef FEAT_PROP_POPUP else { +#ifdef FEAT_PROP_POPUP // Also move any following text properties. if (oldlen + 1 < curbuf->b_ml.ml_line_len) mch_memmove(newp + newlen + 1, oldp + oldlen + 1, (size_t)curbuf->b_ml.ml_line_len - oldlen - 1); +#endif curbuf->b_ml.ml_line_len -= count; curbuf->b_ml.ml_line_textlen = 0; } -#endif // mark the buffer as changed and prepare for displaying inserted_bytes(lnum, col, -count); diff --git a/src/channel.c b/src/channel.c index b99b3a9..69bbff2 100644 --- a/src/channel.c +++ b/src/channel.c @@ -2277,7 +2277,7 @@ channel_parse_json(channel_T *channel, ch_part_T part) { int timeout; #ifdef MSWIN - timeout = GetTickCount() > chanpart->ch_deadline; + timeout = (int)(GetTickCount() - chanpart->ch_deadline) > 0; #else { struct timeval now_tv; diff --git a/src/charset.c b/src/charset.c index 9aa402a..19b0895 100644 --- a/src/charset.c +++ b/src/charset.c @@ -827,20 +827,20 @@ linetabsize_no_outer(win_T *wp, linenr_T lnum) if (cts.cts_text_prop_count) { - int write_idx = 0; - for (int read_idx = 0; read_idx < cts.cts_text_prop_count; read_idx++) - { - textprop_T *tp = &cts.cts_text_props[read_idx]; - if (tp->tp_col != MAXCOL) - { - if (read_idx != write_idx) - cts.cts_text_props[write_idx] = *tp; - write_idx++; - } - } - cts.cts_text_prop_count = write_idx; - if (cts.cts_text_prop_count == 0) - VIM_CLEAR(cts.cts_text_props); + int write_idx = 0; + for (int read_idx = 0; read_idx < cts.cts_text_prop_count; read_idx++) + { + textprop_T *tp = &cts.cts_text_props[read_idx]; + if (tp->tp_col != MAXCOL) + { + if (read_idx != write_idx) + cts.cts_text_props[write_idx] = *tp; + write_idx++; + } + } + cts.cts_text_prop_count = write_idx; + if (cts.cts_text_prop_count == 0) + VIM_CLEAR(cts.cts_text_props); } win_linetabsize_cts(&cts, (colnr_T)MAXCOL); @@ -1397,17 +1397,17 @@ win_lbr_chartabsize( else if (max_head_vcol > vcol + head_prev + prev_rem) head += (max_head_vcol - (vcol + head_prev + prev_rem) + width2 - 1) / width2 * head_mid; -# ifdef FEAT_PROP_POPUP else if (max_head_vcol < 0) { - int off = 0; + int off = mb_added; +# ifdef FEAT_PROP_POPUP if (*s != NUL && ((State & MODE_NORMAL) || cts->cts_start_incl)) off += cts->cts_cur_text_width; +# endif if (off >= prev_rem) head += (1 + (off - prev_rem) / width) * head_mid; } -# endif } } diff --git a/src/cmdexpand.c b/src/cmdexpand.c index 8d8bf06..c1ed03b 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -46,6 +46,7 @@ cmdline_fuzzy_completion_supported(expand_T *xp) && xp->xp_context != EXPAND_COLORS && xp->xp_context != EXPAND_COMPILER && xp->xp_context != EXPAND_DIRECTORIES + && xp->xp_context != EXPAND_DIRS_IN_CDPATH && xp->xp_context != EXPAND_FILES && xp->xp_context != EXPAND_FILES_IN_PATH && xp->xp_context != EXPAND_FILETYPE @@ -107,7 +108,8 @@ wildescape( || xp->xp_context == EXPAND_FILES_IN_PATH || xp->xp_context == EXPAND_SHELLCMD || xp->xp_context == EXPAND_BUFFERS - || xp->xp_context == EXPAND_DIRECTORIES) + || xp->xp_context == EXPAND_DIRECTORIES + || xp->xp_context == EXPAND_DIRS_IN_CDPATH) { // Insert a backslash into a file name before a space, \, %, # // and wildmatch characters, except '~'. @@ -357,6 +359,7 @@ cmdline_pum_create( compl_match_array[i].pum_info = NULL; compl_match_array[i].pum_extra = NULL; compl_match_array[i].pum_kind = NULL; + compl_match_array[i].pum_user_hlattr = -1; } // Compute the popup menu starting column @@ -1404,7 +1407,8 @@ addstar( if (context != EXPAND_FILES && context != EXPAND_FILES_IN_PATH && context != EXPAND_SHELLCMD - && context != EXPAND_DIRECTORIES) + && context != EXPAND_DIRECTORIES + && context != EXPAND_DIRS_IN_CDPATH) { // Matching will be done internally (on something other than files). // So we convert the file-matching-type wildcards into our kind for @@ -2138,7 +2142,7 @@ set_context_by_cmdname( case CMD_lcd: case CMD_lchdir: if (xp->xp_context == EXPAND_FILES) - xp->xp_context = EXPAND_DIRECTORIES; + xp->xp_context = EXPAND_DIRS_IN_CDPATH; break; case CMD_help: xp->xp_context = EXPAND_HELP; @@ -2845,6 +2849,8 @@ expand_files_and_dirs( flags |= EW_FILE; else if (xp->xp_context == EXPAND_FILES_IN_PATH) flags |= (EW_FILE | EW_PATH); + else if (xp->xp_context == EXPAND_DIRS_IN_CDPATH) + flags = (flags | EW_DIR | EW_CDPATH) & ~EW_FILE; else flags = (flags | EW_DIR) & ~EW_FILE; if (options & WILD_ICASE) @@ -3098,7 +3104,8 @@ ExpandFromContext( if (xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_DIRECTORIES - || xp->xp_context == EXPAND_FILES_IN_PATH) + || xp->xp_context == EXPAND_FILES_IN_PATH + || xp->xp_context == EXPAND_DIRS_IN_CDPATH) return expand_files_and_dirs(xp, pat, matches, numMatches, flags, options); diff --git a/src/config.h.in b/src/config.h.in index 8ad9f03..530c082 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -222,7 +222,6 @@ #undef HAVE_UNSETENV #undef HAVE_USLEEP #undef HAVE_UTIME -#undef HAVE_BIND_TEXTDOMAIN_CODESET #undef HAVE_MBLEN #undef HAVE_TIMER_CREATE #undef HAVE_CLOCK_GETTIME @@ -424,6 +423,12 @@ /* Define if there is a working gettext(). */ #undef HAVE_GETTEXT +/* Define if there is a working bind_textdomain_codeset(). */ +#undef HAVE_BIND_TEXTDOMAIN_CODESET + +/* Define if there is a working dgettext(). */ +#undef HAVE_DGETTEXT + /* Define if _nl_msg_cat_cntr is present. */ #undef HAVE_NL_MSG_CAT_CNTR diff --git a/src/configure.ac b/src/configure.ac index 946fe52..233e907 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -1539,11 +1539,18 @@ if test "$enable_python3interp" = "yes" -o "$enable_python3interp" = "dynamic"; AC_MSG_RESULT(yep) dnl -- get the stable ABI version if passed in + python3_stable_abi_default=3.8 AC_MSG_CHECKING(--with-python3-stable-abi argument) AC_SUBST(vi_cv_var_python3_stable_abi) - AC_ARG_WITH(python3-stable-abi, [ --with-python3-stable-abi=VERSION stable ABI version to target (e.g. 3.8)], - vi_cv_var_python3_stable_abi="$withval"; AC_MSG_RESULT($vi_cv_var_python3_stable_abi), - AC_MSG_RESULT(no)) + AC_ARG_WITH(python3-stable-abi, [ --with-python3-stable-abi=VERSION stable ABI version to target (default: 3.8)], + [ + if test "X$withval" = "Xyes"; then + vi_cv_var_python3_stable_abi=$python3_stable_abi_default + else + vi_cv_var_python3_stable_abi="$withval" + fi + AC_MSG_RESULT($vi_cv_var_python3_stable_abi)], + AC_MSG_RESULT(no)) if test "X$vi_cv_var_python3_stable_abi" != "X"; then AC_CACHE_VAL(vi_cv_var_python3_stable_abi_hex, [ @@ -4497,6 +4504,12 @@ if test "$enable_nls" = "yes"; then AC_SUBST(MAKEMO) dnl this was added in GNU gettext 0.10.36 AC_CHECK_FUNCS(bind_textdomain_codeset) + AC_MSG_CHECKING([for dgettext]) + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [#include <libintl.h>], + [dgettext("Test", "Test");])], + AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_DGETTEXT), + AC_MSG_RESULT([no])) dnl _nl_msg_cat_cntr is required for GNU gettext AC_MSG_CHECKING([for _nl_msg_cat_cntr]) AC_LINK_IFELSE([AC_LANG_PROGRAM( @@ -1222,8 +1222,7 @@ dict_lookup(hashitem_T *hi) dict_equal( dict_T *d1, dict_T *d2, - int ic, // ignore case for strings - int recursive) // TRUE when used recursively + int ic) // ignore case for strings { hashitem_T *hi; dictitem_T *item2; @@ -1247,7 +1246,7 @@ dict_equal( item2 = dict_find(d2, hi->hi_key, -1); if (item2 == NULL) return FALSE; - if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive)) + if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) return FALSE; --todo; } @@ -1275,7 +1274,7 @@ dict_count(dict_T *d, typval_T *needle, int ic) if (!HASHITEM_EMPTY(hi)) { --todo; - if (tv_equal(&HI2DI(hi)->di_tv, needle, ic, FALSE)) + if (tv_equal(&HI2DI(hi)->di_tv, needle, ic)) ++n; } } @@ -2849,7 +2849,6 @@ cursor_down_inner(win_T *wp, long n) // count each sequence of folded lines as one logical line while (n--) { - // Move to last line of fold, will fail if it's the end-of-file. if (hasFoldingWin(wp, lnum, NULL, &last, TRUE, NULL)) lnum = last + 1; else @@ -2877,8 +2876,11 @@ cursor_down( { linenr_T lnum = curwin->w_cursor.lnum; linenr_T line_count = curwin->w_buffer->b_ml.ml_line_count; - // This fails if the cursor is already in the last line or would move - // beyond the last line and '-' is in 'cpoptions' + // This fails if the cursor is already in the last (folded) line, or would + // move beyond the last line and '-' is in 'cpoptions'. +#ifdef FEAT_FOLDING + hasFoldingWin(curwin, lnum, NULL, &lnum, TRUE, NULL); +#endif if (n > 0 && (lnum >= line_count || (lnum + n > line_count diff --git a/src/errors.h b/src/errors.h index 4387a29..03b3c08 100644 --- a/src/errors.h +++ b/src/errors.h @@ -1038,8 +1038,10 @@ EXTERN char e_missing_argument_str[] INIT(= N_("E417: Missing argument: %s")); EXTERN char e_illegal_value_str[] INIT(= N_("E418: Illegal value: %s")); +#ifdef FEAT_EVAL EXTERN char e_im_a_teapot[] INIT(= N_("E418: I'm a teapot")); +#endif EXTERN char e_fg_color_unknown[] INIT(= N_("E419: FG color unknown")); EXTERN char e_bg_color_unknown[] @@ -1273,8 +1275,10 @@ EXTERN char e_is_not_file_or_writable_device[] INIT(= N_("is not a file or writable device")); EXTERN char e_str_is_not_file_or_writable_device[] INIT(= N_("E503: \"%s\" is not a file or writable device")); +#ifdef FEAT_EVAL EXTERN char e_coffee_currently_not_available[] INIT(= N_("E503: Coffee is currently not available")); +#endif // E504 EXTERN char e_is_read_only_cannot_override_W_in_cpoptions[] INIT(= N_("is read-only (cannot override: \"W\" in 'cpoptions')")); @@ -1571,11 +1575,12 @@ EXTERN char e_too_many_signs_defined[] EXTERN char e_unknown_printer_font_str[] INIT(= N_("E613: Unknown printer font: %s")); #endif -EXTERN char e_class_required[] - INIT(= N_("E614: Class required")); +// E614 unused (deleted) // E615 unused +#ifdef FEAT_EVAL EXTERN char e_object_required_for_argument_nr[] INIT(= N_("E616: Object required for argument %d")); +#endif #ifdef FEAT_GUI_GTK EXTERN char e_cannot_be_changed_in_gtk_GUI[] INIT(= N_("E617: Cannot be changed in the GTK GUI")); @@ -3315,8 +3320,10 @@ EXTERN char e_could_not_check_for_pending_sigalrm_str[] #ifdef FEAT_EVAL EXTERN char e_substitute_nesting_too_deep[] INIT(= N_("E1290: substitute nesting too deep")); +# ifdef MSWIN EXTERN char e_invalid_argument_nr[] INIT(= N_("E1291: Invalid argument: %ld")); +# endif #endif EXTERN char e_cmdline_window_already_open[] INIT(= N_("E1292: Command-line window is already open")); @@ -3387,16 +3394,13 @@ EXTERN char e_invalid_object_variable_declaration_str[] INIT(= N_("E1317: Invalid object variable declaration: %s")); EXTERN char e_not_valid_command_in_class_str[] INIT(= N_("E1318: Not a valid command in a class: %s")); -EXTERN char e_using_class_as_number[] - INIT(= N_("E1319: Using a Class as a Number")); +// E1319 unused EXTERN char e_using_object_as_number[] INIT(= N_("E1320: Using an Object as a Number")); -EXTERN char e_using_class_as_float[] - INIT(= N_("E1321: Using a Class as a Float")); +// E1321 unused EXTERN char e_using_object_as_float[] INIT(= N_("E1322: Using an Object as a Float")); -EXTERN char e_using_class_as_string[] - INIT(= N_("E1323: Using a Class as a String")); +// E1323 unused EXTERN char e_using_object_as_string[] INIT(= N_("E1324: Using an Object as a String")); EXTERN char e_method_not_found_on_class_str_str[] @@ -3547,8 +3551,7 @@ EXTERN char e_type_can_only_be_defined_in_vim9_script[] INIT(= N_("E1393: Type can only be defined in Vim9 script")); EXTERN char e_type_name_must_start_with_uppercase_letter_str[] INIT(= N_("E1394: Type name must start with an uppercase letter: %s")); -EXTERN char e_cannot_modify_typealias[] - INIT(= N_("E1395: Type alias \"%s\" cannot be modified")); +// E1395 unused EXTERN char e_typealias_already_exists_for_str[] INIT(= N_("E1396: Type alias \"%s\" already exists")); EXTERN char e_missing_typealias_name[] @@ -3557,20 +3560,16 @@ EXTERN char e_missing_typealias_type[] INIT(= N_("E1398: Missing type alias type")); EXTERN char e_type_can_only_be_used_in_script[] INIT(= N_("E1399: Type can only be used in a script")); -EXTERN char e_using_typealias_as_number[] - INIT(= N_("E1400: Using type alias \"%s\" as a Number")); -EXTERN char e_using_typealias_as_float[] - INIT(= N_("E1401: Using type alias \"%s\" as a Float")); -EXTERN char e_using_typealias_as_string[] - INIT(= N_("E1402: Using type alias \"%s\" as a String")); +// E1400 unused +// E1401 unused +// E1402 unused EXTERN char e_using_typealias_as_value_str[] INIT(= N_("E1403: Type alias \"%s\" cannot be used as a value")); EXTERN char e_abstract_cannot_be_used_in_interface[] INIT(= N_("E1404: Abstract cannot be used in an interface")); EXTERN char e_using_class_as_value_str[] INIT(= N_("E1405: Class \"%s\" cannot be used as a value")); -EXTERN char e_using_class_as_var_val[] - INIT(= N_("E1406: Cannot use a Class as a variable or value")); +// E1406 unused EXTERN char e_using_typealias_as_var_val[] INIT(= N_("E1407: Cannot use a Typealias as a variable or value")); EXTERN char e_final_variable_not_supported_in_interface[] @@ -3625,20 +3624,26 @@ EXTERN char e_fmt_arg_nr_unused_str[] INIT(= N_("E1501: format argument %d unused in $-style format: %s")); EXTERN char e_positional_num_field_spec_reused_str_str[] INIT(= N_("E1502: Positional argument %d used as field width reused as different type: %s/%s")); +#ifdef FEAT_EVAL EXTERN char e_positional_nr_out_of_bounds_str[] INIT(= N_("E1503: Positional argument %d out of bounds: %s")); +#endif EXTERN char e_positional_arg_num_type_inconsistent_str_str[] INIT(= N_("E1504: Positional argument %d type used inconsistently: %s/%s")); EXTERN char e_invalid_format_specifier_str[] INIT(= N_("E1505: Invalid format specifier: %s")); +#ifdef FEAT_XATTR EXTERN char e_xattr_erange[] INIT(= N_("E1506: Buffer too small to copy xattr value or key")); +#endif EXTERN char e_aptypes_is_null_nr_str[] INIT(= "E1507: Internal error: ap_types or ap_types[idx] is NULL: %d: %s"); +#ifdef FEAT_XATTR EXTERN char e_xattr_e2big[] INIT(= N_("E1508: Size of the extended attribute value is larger than the maximum size allowed")); EXTERN char e_xattr_other[] INIT(= N_("E1509: Error occurred when reading or writing extended attribute")); +#endif EXTERN char e_val_too_large[] INIT(= N_("E1510: Value too large: %s")); EXTERN char e_wrong_number_of_characters_for_field_str[] @@ -3259,7 +3259,7 @@ may_call_simple_func( char_u *p = STRNCMP(arg, "<SNR>", 5) == 0 ? skipdigits(arg + 5) : arg; if (to_name_end(p, TRUE) == parens) - r = call_simple_func(arg, (int)(parens - arg), rettv); + r = call_simple_func(arg, (size_t)(parens - arg), rettv); } return r; } @@ -5923,6 +5923,37 @@ func_tv2string(typval_T *tv, char_u **tofree, int echo_style) } /* + * Return a textual representation of the object method in "tv", a VAR_PARTIAL. + * If the memory is allocated "tofree" is set to it, otherwise NULL. + * When "echo_style" is FALSE, put quotes around the function name as + * "function()", otherwise does not put quotes around function name. + * May return NULL. + */ + static char_u * +method_tv2string(typval_T *tv, char_u **tofree, int echo_style) +{ + char_u buf[MAX_FUNC_NAME_LEN]; + partial_T *pt = tv->vval.v_partial; + + size_t len = vim_snprintf((char *)buf, sizeof(buf), "<SNR>%d_%s.%s", + pt->pt_func->uf_script_ctx.sc_sid, + pt->pt_func->uf_class->class_name, + pt->pt_func->uf_name); + if (len >= sizeof(buf)) + { + if (echo_style) + { + *tofree = NULL; + return (char_u *)"function()"; + } + else + return *tofree = string_quote((char_u*)"", TRUE); + } + + return *tofree = echo_style ? vim_strsave(buf) : string_quote(buf, TRUE); +} + +/* * Return a textual representation of a partial in "tv". * If the memory is allocated "tofree" is set to it, otherwise NULL. * "numbuf" is used for a number. May return NULL. @@ -6088,10 +6119,10 @@ dict_tv2string( */ static char_u * jobchan_tv2string( - typval_T *tv, - char_u **tofree, - char_u *numbuf, - int composite_val) + typval_T *tv UNUSED, + char_u **tofree UNUSED, + char_u *numbuf UNUSED, + int composite_val UNUSED) { char_u *r = NULL; @@ -6139,6 +6170,58 @@ class_tv2string(typval_T *tv, char_u **tofree) } /* + * Return a textual representation of an Object in "tv". + * If the memory is allocated "tofree" is set to it, otherwise NULL. + * When "copyID" is not zero replace recursive object with "...". + * When "restore_copyID" is FALSE, repeated items in the object are + * replaced with "...". May return NULL. + */ + static char_u * +object_tv2string( + typval_T *tv, + char_u **tofree, + int copyID, + int restore_copyID, + char_u *numbuf, + int echo_style, + int composite_val) +{ + char_u *r = NULL; + + object_T *obj = tv->vval.v_object; + if (obj == NULL || obj->obj_class == NULL) + { + *tofree = NULL; + r = (char_u *)"object of [unknown]"; + } + else if (copyID != 0 && obj->obj_copyID == copyID + && obj->obj_class->class_obj_member_count != 0) + { + size_t n = 25 + strlen((char *)obj->obj_class->class_name); + r = alloc(n); + if (r != NULL) + (void)vim_snprintf((char *)r, n, "object of %s {...}", + obj->obj_class->class_name); + *tofree = r; + } + else + { + int old_copyID; + if (restore_copyID) + old_copyID = obj->obj_copyID; + + obj->obj_copyID = copyID; + *tofree = object2string(obj, numbuf, copyID, echo_style, + restore_copyID, composite_val); + if (restore_copyID) + obj->obj_copyID = old_copyID; + r = *tofree; + } + + return r; +} + +/* * Return a string with the string representation of a variable. * If the memory is allocated "tofree" is set to it, otherwise NULL. * "numbuf" is used for a number. @@ -6169,7 +6252,7 @@ echo_string_core( { // Only give this message once for a recursive call to avoid // flooding the user with errors. And stop iterating over lists - // and dicts. + // and dicts and objects. did_echo_string_emsg = TRUE; emsg(_(e_variable_nested_too_deep_for_displaying)); } @@ -6189,7 +6272,11 @@ echo_string_core( break; case VAR_PARTIAL: - r = partial_tv2string(tv, tofree, numbuf, copyID); + if (tv->vval.v_partial == NULL + || tv->vval.v_partial->pt_obj == NULL) + r = partial_tv2string(tv, tofree, numbuf, copyID); + else + r = method_tv2string(tv, tofree, echo_style); break; case VAR_BLOB: @@ -6227,9 +6314,8 @@ echo_string_core( break; case VAR_OBJECT: - *tofree = r = object2string(tv->vval.v_object, numbuf, copyID, - echo_style, restore_copyID, - composite_val); + r = object_tv2string(tv, tofree, copyID, restore_copyID, + numbuf, echo_style, composite_val); break; case VAR_FLOAT: diff --git a/src/evalfunc.c b/src/evalfunc.c index 9720691..173b544 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -28,6 +28,7 @@ static void f_balloon_show(typval_T *argvars, typval_T *rettv); static void f_balloon_split(typval_T *argvars, typval_T *rettv); # endif #endif +static void f_bindtextdomain(typval_T *argvars, typval_T *rettv); static void f_byte2line(typval_T *argvars, typval_T *rettv); static void f_call(typval_T *argvars, typval_T *rettv); static void f_changenr(typval_T *argvars, typval_T *rettv); @@ -81,6 +82,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv); static void f_hlID(typval_T *argvars, typval_T *rettv); static void f_hlexists(typval_T *argvars, typval_T *rettv); static void f_hostname(typval_T *argvars, typval_T *rettv); +static void f_id(typval_T *argvars, typval_T *rettv); static void f_index(typval_T *argvars, typval_T *rettv); static void f_indexof(typval_T *argvars, typval_T *rettv); static void f_input(typval_T *argvars, typval_T *rettv); @@ -1133,6 +1135,7 @@ static argcheck_T arg2_number_bool[] = {arg_number, arg_bool}; static argcheck_T arg2_number_dict_any[] = {arg_number, arg_dict_any}; static argcheck_T arg2_number_list[] = {arg_number, arg_list_any}; static argcheck_T arg2_number_string[] = {arg_number, arg_string}; +static argcheck_T arg2_number_buffer[] = {arg_number, arg_buffer}; static argcheck_T arg2_number_string_or_list[] = {arg_number, arg_string_or_list_any}; static argcheck_T arg2_str_or_nr_or_list_dict[] = {arg_str_or_nr_or_list, arg_dict_any}; static argcheck_T arg2_string[] = {arg_string, arg_string}; @@ -1323,7 +1326,6 @@ ret_list_items(int argcount UNUSED, *decl_type = &t_list_any; return &t_list_list_any; } - static type_T * ret_list_string_items(int argcount UNUSED, type2_T *argtypes UNUSED, @@ -1333,6 +1335,14 @@ ret_list_string_items(int argcount UNUSED, return &t_list_list_string; } static type_T * +ret_list_regionpos(int argcount UNUSED, + type2_T *argtypes UNUSED, + type_T **decl_type) +{ + *decl_type = &t_list_any; + return &t_list_list_list_number; +} + static type_T * ret_dict_any(int argcount UNUSED, type2_T *argtypes UNUSED, type_T **decl_type UNUSED) @@ -1823,6 +1833,8 @@ static funcentry_T global_functions[] = NULL #endif }, + {"bindtextdomain", 2, 2, 0, arg2_string, + ret_bool, f_bindtextdomain}, {"blob2list", 1, 1, FEARG_1, arg1_blob, ret_list_number, f_blob2list}, {"browse", 4, 4, 0, arg4_browse, @@ -1963,11 +1975,11 @@ static funcentry_T global_functions[] = ret_number, f_diff_hlID}, {"digraph_get", 1, 1, FEARG_1, arg1_string, ret_string, f_digraph_get}, - {"digraph_getlist",0, 1, FEARG_1, arg1_bool, + {"digraph_getlist", 0, 1, FEARG_1, arg1_bool, ret_list_string_items, f_digraph_getlist}, {"digraph_set", 2, 2, FEARG_1, arg2_string, ret_bool, f_digraph_set}, - {"digraph_setlist",1, 1, FEARG_1, arg1_list_string, + {"digraph_setlist", 1, 1, FEARG_1, arg1_list_string, ret_bool, f_digraph_setlist}, {"echoraw", 1, 1, FEARG_1, arg1_string, ret_void, f_echoraw}, @@ -2139,8 +2151,8 @@ static funcentry_T global_functions[] = ret_dict_any, f_getreginfo}, {"getregion", 2, 3, FEARG_1, arg3_list_list_dict, ret_list_string, f_getregion}, - {"getregionpos", 2, 3, FEARG_1, arg3_list_list_dict, - ret_list_string, f_getregionpos}, + {"getregionpos", 2, 3, FEARG_1, arg3_list_list_dict, + ret_list_regionpos, f_getregionpos}, {"getregtype", 0, 1, FEARG_1, arg1_string, ret_string, f_getregtype}, {"getscriptinfo", 0, 1, 0, arg1_dict_any, @@ -2153,7 +2165,7 @@ static funcentry_T global_functions[] = ret_any, f_gettabwinvar}, {"gettagstack", 0, 1, FEARG_1, arg1_number, ret_dict_any, f_gettagstack}, - {"gettext", 1, 1, FEARG_1, arg1_string, + {"gettext", 1, 2, FEARG_1, arg2_string, ret_string, f_gettext}, {"getwininfo", 0, 1, FEARG_1, arg1_number, ret_list_dict_any, f_getwininfo}, @@ -2203,6 +2215,8 @@ static funcentry_T global_functions[] = ret_string, f_hostname}, {"iconv", 3, 3, FEARG_1, arg3_string, ret_string, f_iconv}, + {"id", 1, 1, FEARG_1, NULL, + ret_string, f_id}, {"indent", 1, 1, FEARG_1, arg1_lnum, ret_number, f_indent}, {"index", 2, 4, FEARG_1, arg24_index, @@ -2421,6 +2435,8 @@ static funcentry_T global_functions[] = ret_void, PROP_FUNC(f_popup_move)}, {"popup_notification", 2, 2, FEARG_1, arg2_str_or_nr_or_list_dict, ret_number, PROP_FUNC(f_popup_notification)}, + {"popup_setbuf", 2, 2, FEARG_1, arg2_number_buffer, + ret_number_bool, PROP_FUNC(f_popup_setbuf)}, {"popup_setoptions", 2, 2, FEARG_1, arg2_number_dict_any, ret_void, PROP_FUNC(f_popup_setoptions)}, {"popup_settext", 2, 2, FEARG_1, arg2_number_string_or_list, @@ -3118,8 +3134,8 @@ internal_func_check_arg_types( // functions, check the arguments are not types. if (!(func_allows_type(idx))) { - for (int i = 0; i < argcount; ++i) - if (check_type_is_value(types[i].type_curr) == FAIL) + for (int i = 0; i < argcount; ++i) + if (check_type_is_value(types[i].type_curr) == FAIL) return FAIL; } @@ -3474,6 +3490,33 @@ get_buf_arg(typval_T *arg) } /* + * "bindtextdomain(package, path)" function + */ + static void +f_bindtextdomain(typval_T *argvars, typval_T *rettv) +{ + rettv->v_type = VAR_BOOL; + rettv->vval.v_number = VVAL_TRUE; + + if (check_for_nonempty_string_arg(argvars, 0) == FAIL + || check_for_nonempty_string_arg(argvars, 1) == FAIL) + return; + + if (strcmp((const char *)argvars[0].vval.v_string, VIMPACKAGE) == 0) + semsg(_(e_invalid_argument_str), tv_get_string(&argvars[0])); + else + { + if (bindtextdomain((const char *)argvars[0].vval.v_string, (const char *)argvars[1].vval.v_string) == NULL) + { + do_outofmem_msg((long)0); + rettv->vval.v_number = VVAL_FALSE; + } + } + + return; +} + +/* * "byte2line(byte)" function */ static void @@ -5110,6 +5153,36 @@ f_get(typval_T *argvars, typval_T *rettv) list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]); } } + else if (STRCMP(what, "arity") == 0) + { + int required = 0, optional = 0, varargs = FALSE; + char_u *name = partial_name(pt); + + get_func_arity(name, &required, &optional, &varargs); + + rettv->v_type = VAR_DICT; + if (rettv_dict_alloc(rettv) == OK) + { + dict_T *dict = rettv->vval.v_dict; + + // Take into account the arguments of the partial, if any. + // Note that it is possible to supply more arguments than the function + // accepts. + if (pt->pt_argc >= required + optional) + required = optional = 0; + else if (pt->pt_argc > required) + { + optional -= pt->pt_argc - required; + required = 0; + } + else + required -= pt->pt_argc; + + dict_add_number(dict, "required", required); + dict_add_number(dict, "optional", optional); + dict_add_bool(dict, "varargs", varargs); + } + } else semsg(_(e_invalid_argument_str), what); @@ -6030,11 +6103,39 @@ f_gettagstack(typval_T *argvars, typval_T *rettv) static void f_gettext(typval_T *argvars, typval_T *rettv) { - if (check_for_nonempty_string_arg(argvars, 0) == FAIL) +#if defined(HAVE_BIND_TEXTDOMAIN_CODESET) + char *prev = NULL; +#endif + + if (check_for_nonempty_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL) return; rettv->v_type = VAR_STRING; - rettv->vval.v_string = vim_strsave((char_u *)_(argvars[0].vval.v_string)); + + if (argvars[1].v_type == VAR_STRING && + argvars[1].vval.v_string != NULL && + *(argvars[1].vval.v_string) != NUL) + { +#if defined(HAVE_BIND_TEXTDOMAIN_CODESET) + prev = bind_textdomain_codeset((const char *)argvars[1].vval.v_string, (char *)p_enc); +#endif + +#if defined(HAVE_DGETTEXT) + rettv->vval.v_string = vim_strsave((char_u *)dgettext((const char *)argvars[1].vval.v_string, (const char *)argvars[0].vval.v_string)); +#else + textdomain((const char *)argvars[1].vval.v_string); + rettv->vval.v_string = vim_strsave((char_u *)_(argvars[0].vval.v_string)); + textdomain(VIMPACKAGE); +#endif + +#if defined(HAVE_BIND_TEXTDOMAIN_CODESET) + if (prev != NULL) + bind_textdomain_codeset((const char *)argvars[1].vval.v_string, prev); +#endif + } + else + rettv->vval.v_string = vim_strsave((char_u *)_(argvars[0].vval.v_string)); } // for VIM_VERSION_ defines @@ -7435,6 +7536,54 @@ f_hostname(typval_T *argvars UNUSED, typval_T *rettv) } /* + * "id()" function + * Identity. Return address of item as a hex string, %p format. + * Currently only valid for object/container types. + * Return empty string if not an object. + */ +#ifdef VMS // VMS does not have defined uintptr_t +# if defined(HAVE_NO_LONG_LONG) +typedef unsigned int uintptr_t; +# else +typedef unsigned long long uintptr_t; +# endif +#endif // VMS + + static void +f_id(typval_T *argvars, typval_T *rettv) +{ + char numbuf[NUMBUFLEN]; + char *p = numbuf; + + switch (argvars[0].v_type) + { + case VAR_LIST: + case VAR_DICT: + case VAR_OBJECT: + case VAR_JOB: + case VAR_CHANNEL: + case VAR_BLOB: + // Assume pointer value in typval_T vval union at common location. + if (argvars[0].vval.v_object != NULL) + { + // "v" gets the address as an integer + uintptr_t v = (uintptr_t)(void *)argvars[0].vval.v_object; + // Build a hex string from the item's address; it is in + // reverse order. Ignore trailing zeros. + for (; p < numbuf + sizeof(uintptr_t) * 2 && v != 0; + ++p, v >>= 4) + *p = "0123456789abcdef"[v & 0xf]; + } + default: + break; + } + *p = NUL; + + rettv->v_type = VAR_STRING; + rettv->vval.v_string = vim_strsave((char_u *)numbuf); +} + +/* * "index()" function */ static void @@ -7483,7 +7632,7 @@ f_index(typval_T *argvars, typval_T *rettv) { tv.v_type = VAR_NUMBER; tv.vval.v_number = blob_get(b, idx); - if (tv_equal(&tv, &argvars[1], ic, FALSE)) + if (tv_equal(&tv, &argvars[1], ic)) { rettv->vval.v_number = idx; return; @@ -7516,7 +7665,7 @@ f_index(typval_T *argvars, typval_T *rettv) } for ( ; item != NULL; item = item->li_next, ++idx) - if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE)) + if (tv_equal(&item->li_tv, &argvars[1], ic)) { rettv->vval.v_number = idx; break; @@ -9215,69 +9364,47 @@ f_test_srand_seed(typval_T *argvars, typval_T *rettv UNUSED) static void init_srand(UINT32_T *x) { -#ifndef MSWIN - static int dev_urandom_state = NOTDONE; // FAIL or OK once tried -#endif + struct { + union { + UINT32_T number; + char_u bytes[sizeof(UINT32_T)]; + } contents; + } buf; if (srand_seed_for_testing_is_used) { *x = srand_seed_for_testing; return; } -#ifndef MSWIN - if (dev_urandom_state != FAIL) - { - int fd = open("/dev/urandom", O_RDONLY); - struct { - union { - UINT32_T number; - char bytes[sizeof(UINT32_T)]; - } contents; - } buf; - // Attempt reading /dev/urandom. - if (fd == -1) - dev_urandom_state = FAIL; - else - { - buf.contents.number = 0; - if (read(fd, buf.contents.bytes, sizeof(UINT32_T)) - != sizeof(UINT32_T)) - dev_urandom_state = FAIL; - else - { - dev_urandom_state = OK; - *x = buf.contents.number; - } - close(fd); - } - } - if (dev_urandom_state != OK) -#endif + if (mch_get_random(buf.contents.bytes, sizeof(buf.contents.bytes)) == OK) { - // Reading /dev/urandom doesn't work, fall back to: - // - randombytes_random() - // - reltime() or time() - // - XOR with process ID + *x = buf.contents.number; + return; + } + + // The system's random number generator doesn't work, fall back to: + // - randombytes_random() + // - reltime() or time() + // - XOR with process ID #if defined(FEAT_SODIUM) - if (crypt_sodium_init() >= 0) - *x = crypt_sodium_randombytes_random(); - else + if (crypt_sodium_init() >= 0) + *x = crypt_sodium_randombytes_random(); + else #endif - { + { #if defined(FEAT_RELTIME) - proftime_T res; - profile_start(&res); + proftime_T res; + profile_start(&res); # if defined(MSWIN) - *x = (UINT32_T)res.LowPart; + *x = (UINT32_T)res.LowPart; # else - *x = (UINT32_T)res.tv_fsec; + *x = (UINT32_T)res.tv_fsec; # endif #else - *x = vim_time(); + *x = vim_time(); #endif - *x ^= mch_get_pid(); - } + *x ^= mch_get_pid(); } } diff --git a/src/evalvars.c b/src/evalvars.c index 6facbeb..f18b516 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -4100,7 +4100,7 @@ set_var_const( // Modifying a final variable with a List value using the "+=" // operator is allowed. For other types, it is not allowed. - if (((flags & ASSIGN_FOR_LOOP) == 0 + if ((((flags & ASSIGN_FOR_LOOP) == 0 || (flags & ASSIGN_DECL) == 0) && ((flags & ASSIGN_COMPOUND_OP) == 0 || !type_inplace_modifiable)) ? var_check_permission(di, name) == FAIL diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 8143c24..acddd9c 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -2838,9 +2838,9 @@ do_ecmd( int did_decrement; buf_T *was_curbuf = curbuf; - // Set the w_closing flag to avoid that autocommands close the + // Set the w_locked flag to avoid that autocommands close the // window. And set b_locked for the same reason. - the_curwin->w_closing = TRUE; + the_curwin->w_locked = TRUE; ++buf->b_locked; if (curbuf == old_curbuf.br_buf) @@ -2854,7 +2854,7 @@ do_ecmd( // Autocommands may have closed the window. if (win_valid(the_curwin)) - the_curwin->w_closing = FALSE; + the_curwin->w_locked = FALSE; --buf->b_locked; #ifdef FEAT_EVAL @@ -3360,11 +3360,17 @@ ex_append(exarg_T *eap) indent = get_indent_lnum(lnum); } ex_keep_indent = FALSE; - if (eap->ea_getline == NULL) + if (*eap->arg == '|') + { + // Get the text after the trailing bar. + theline = vim_strsave(eap->arg + 1); + *eap->arg = NUL; + } + else if (eap->ea_getline == NULL) { // No getline() function, use the lines that follow. This ends // when there is no more. - if (eap->nextcmd == NULL || *eap->nextcmd == NUL) + if (eap->nextcmd == NULL) break; p = vim_strchr(eap->nextcmd, NL); if (p == NULL) @@ -3372,6 +3378,8 @@ ex_append(exarg_T *eap) theline = vim_strnsave(eap->nextcmd, p - eap->nextcmd); if (*p != NUL) ++p; + else + p = NULL; eap->nextcmd = p; } else @@ -3769,6 +3777,7 @@ ex_substitute(exarg_T *eap) int endcolumn = FALSE; // cursor in last column when done pos_T old_cursor = curwin->w_cursor; int start_nsubs; + int keeppatterns = cmdmod.cmod_flags & CMOD_KEEPPATTERNS; #ifdef FEAT_EVAL int save_ma = 0; int save_sandbox = 0; @@ -3832,11 +3841,11 @@ ex_substitute(exarg_T *eap) which_pat = RE_LAST; // use last used regexp delimiter = *cmd++; // remember delimiter character pat = cmd; // remember start of search pat - patlen = STRLEN(pat); cmd = skip_regexp_ex(cmd, delimiter, magic_isset(), &eap->arg, NULL, NULL); if (cmd[0] == delimiter) // end delimiter found *cmd++ = NUL; // replace it with a NUL + patlen = STRLEN(pat); } /* @@ -3868,7 +3877,7 @@ ex_substitute(exarg_T *eap) // out of memory return; } - else + else if (!keeppatterns) { vim_free(old_sub); old_sub = vim_strsave(sub); @@ -3932,7 +3941,7 @@ ex_substitute(exarg_T *eap) ex_may_print(eap); } - if ((cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) + if (!keeppatterns) save_re_pat(RE_SUBST, pat, patlen, magic_isset()); // put pattern in history add_to_history(HIST_SEARCH, pat, patlen, TRUE, NUL); diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index ce30b8d..0681153 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -197,7 +197,7 @@ dialog_changed( // restore to empty when write failed if (empty_bufname) { - VIM_CLEAR(buf->b_fname); + buf->b_fname = NULL; VIM_CLEAR(buf->b_ffname); VIM_CLEAR(buf->b_sfname); unchanged(buf, TRUE, FALSE); diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 71bfa93..2a59301 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -19,10 +19,6 @@ static int ex_pressedreturn = FALSE; # define ex_hardcopy ex_ni #endif -#if defined(FEAT_EVAL) || defined(PROTO) -static int cmp_cmdmod_info(const void *a, const void *b); -#endif - #ifdef FEAT_EVAL static char_u *do_one_cmd(char_u **, int, cstack_T *, char_u *(*fgetline)(int, void *, int, getline_opt_T), void *cookie); #else @@ -1460,8 +1456,13 @@ handle_did_throw(void) current_exception->throw_name = NULL; discard_current_exception(); // uses IObuff if 'verbose' - suppress_errthrow = TRUE; - force_abort = TRUE; + + // If "silent!" is active the uncaught exception is not fatal. + if (emsg_silent == 0) + { + suppress_errthrow = TRUE; + force_abort = TRUE; + } if (messages != NULL) { @@ -2336,12 +2337,7 @@ do_one_cmd( { for (p = ea.arg; *p; ++p) { - // Remove one backslash before a newline, so that it's possible to - // pass a newline to the shell and also a newline that is preceded - // with a backslash. This makes it impossible to end a shell - // command in a backslash, but that doesn't appear useful. - // Halving the number of backslashes is incompatible with previous - // versions. + // Remove one backslash before a newline if (*p == '\\' && p[1] == '\n') STRMOVE(p, p + 1); else if (*p == '\n' && !(ea.argt & EX_EXPR_ARG)) @@ -2722,6 +2718,12 @@ ex_errmsg(char *msg, char_u *arg) } /* + * The "+" string used in place of an empty command in Ex mode. + * This string is used in pointer comparison. + */ +static char exmode_plus[] = "+"; + +/* * Handle a range without a command. * Returns an error message on failure. */ @@ -2730,7 +2732,8 @@ ex_range_without_command(exarg_T *eap) { char *errormsg = NULL; - if ((*eap->cmd == '|' || (exmode_active && eap->line1 != eap->line2)) + if ((*eap->cmd == '|' || + (exmode_active && eap->cmd != (char_u *)exmode_plus + 1)) #ifdef FEAT_EVAL && !in_vim9script() #endif @@ -2860,9 +2863,8 @@ parse_command_modifiers( { // The automatically inserted Visual area range is skipped, so that // typing ":cmdmod cmd" in Visual mode works without having to move the - // range to after the modififiers. The command will be - // "'<,'>cmdmod cmd", parse "cmdmod cmd" and then put back "'<,'>" - // before "cmd" below. + // range to after the modifiers. The command will be "'<,'>cmdmod cmd", + // parse "cmdmod cmd" and then put back "'<,'>" before "cmd" below. eap->cmd += 5; cmd_start = eap->cmd; has_visual_range = TRUE; @@ -3213,7 +3215,7 @@ parse_command_modifiers( eap->cmd = orig_cmd; } else if (use_plus_cmd) - eap->cmd = (char_u *)"+"; + eap->cmd = (char_u *)exmode_plus; return OK; } @@ -4044,16 +4046,6 @@ static cmdmod_info_T cmdmod_info_tab[] = { {"vim9cmd", 4, FALSE} }; // cmdmod_info_tab -// compare two cmdmod_info_T structs by case sensitive name with length - static int -cmp_cmdmod_info(const void *a, const void *b) -{ - cmdmod_info_T *cm1 = (cmdmod_info_T *)a; - cmdmod_info_T *cm2 = (cmdmod_info_T *)b; - - return STRNCMP(cm1->name, cm2->name, cm2->minlen); -} - /* * Return length of a command modifier (including optional count). * Return zero when it's not a modifier. @@ -4061,36 +4053,20 @@ cmp_cmdmod_info(const void *a, const void *b) int modifier_len(char_u *cmd) { + int i, j; char_u *p = cmd; - cmdmod_info_T target; - cmdmod_info_T *entry; if (VIM_ISDIGIT(*cmd)) p = skipwhite(skipdigits(cmd + 1)); - - // only lowercase characters can match - if (!ASCII_ISLOWER(*p)) - return 0; - - target.name = (char *)p; - target.minlen = 0; // not used, see cmp_cmdmod_info() - target.has_count = FALSE; - - entry = (cmdmod_info_T *)bsearch(&target, &cmdmod_info_tab, ARRAY_LENGTH(cmdmod_info_tab), sizeof(cmdmod_info_tab[0]), cmp_cmdmod_info); - if (entry != NULL) + for (i = 0; i < (int)ARRAY_LENGTH(cmdmod_info_tab); ++i) { - int i; - - for (i = entry->minlen; p[i] != NUL; ++i) - { - if (p[i] != entry->name[i]) + for (j = 0; p[j] != NUL; ++j) + if (p[j] != cmdmod_info_tab[i].name[j]) break; - } - - if (!ASCII_ISALPHA(p[i]) && i >= entry->minlen && (p == cmd || entry->has_count)) - return i + (int)(p - cmd); + if (!ASCII_ISALPHA(p[j]) && j >= cmdmod_info_tab[i].minlen + && (p == cmd || cmdmod_info_tab[i].has_count)) + return j + (int)(p - cmd); } - return 0; } @@ -4104,33 +4080,18 @@ cmd_exists(char_u *name) { exarg_T ea; int full = FALSE; + int i; + int j; char_u *p; - // only lowercase characters can match - if (ASCII_ISLOWER(*name)) + // Check command modifiers. + for (i = 0; i < (int)ARRAY_LENGTH(cmdmod_info_tab); ++i) { - cmdmod_info_T target; - cmdmod_info_T *entry; - - target.name = (char *)name; - target.minlen = 0; // not used, see cmp_cmdmod_info() - target.has_count = FALSE; - - // Check command modifiers. - entry = (cmdmod_info_T *)bsearch(&target, &cmdmod_info_tab, ARRAY_LENGTH(cmdmod_info_tab), sizeof(cmdmod_info_tab[0]), cmp_cmdmod_info); - if (entry != NULL) - { - int i; - - for (i = entry->minlen; name[i] != NUL; ++i) - { - if (name[i] != entry->name[i]) - break; - } - - if (name[i] == NUL && i >= entry->minlen) - return (entry->name[i] == NUL ? 2 : 1); - } + for (j = 0; name[j] != NUL; ++j) + if (name[j] != cmdmod_info_tab[i].name[j]) + break; + if (name[j] == NUL && j >= cmdmod_info_tab[i].minlen) + return (cmdmod_info_tab[i].name[j] == NUL ? 2 : 1); } // Check built-in commands and user defined commands. @@ -4698,6 +4659,7 @@ get_address( if (n == MAXLNUM) { emsg(_(e_line_number_out_of_range)); + cmd = NULL; goto error; } } @@ -4728,6 +4690,7 @@ get_address( if (lnum >= 0 && n >= LONG_MAX - lnum) { emsg(_(e_line_number_out_of_range)); + cmd = NULL; goto error; } lnum += n; @@ -5401,7 +5364,11 @@ separate_nextcmd(exarg_T *eap, int keep_backslash) && in_vim9script() && !(eap->argt & EX_NOTRLCOM) && p > eap->cmd && VIM_ISWHITE(p[-1])) - || *p == '|' || *p == '\n') + || (*p == '|' + && eap->cmdidx != CMD_append + && eap->cmdidx != CMD_change + && eap->cmdidx != CMD_insert) + || *p == '\n') { /* * We remove the '\' before the '|', unless EX_CTRLV is used @@ -5981,6 +5948,10 @@ get_command_name(expand_T *xp UNUSED, int idx) { if (idx >= (int)CMD_SIZE) return expand_user_command_name(idx); + // the following are no real commands + if (STRNCMP(cmdnames[idx].cmd_name, "{", 1) == 0 || + STRNCMP(cmdnames[idx].cmd_name, "}", 1) == 0) + return (char_u *)""; return cmdnames[idx].cmd_name; } @@ -7261,7 +7232,7 @@ ex_resize(exarg_T *eap) ex_find(exarg_T *eap) { if (!check_can_set_curbuf_forceit(eap->forceit)) - return; + return; char_u *fname; int count; @@ -7353,7 +7324,7 @@ ex_edit(exarg_T *eap) // All other commands must obey 'winfixbuf' / ! rules && (is_other_file(0, ffname) && !check_can_set_curbuf_forceit(eap->forceit)) ) - return; + return; do_exedit(eap, NULL); } diff --git a/src/ex_getln.c b/src/ex_getln.c index 3ae4958..1b3a699 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -1586,6 +1586,7 @@ getcmdline_int( int res; int save_msg_scroll = msg_scroll; int save_State = State; // remember State when called + int prev_cmdpos = -1; int some_key_typed = FALSE; // one of the keys was typed // mouse drag and release events are ignored, unless they are // preceded with a mouse down event @@ -2473,6 +2474,13 @@ getcmdline_int( * (Sorry for the goto's, I know it is ugly). */ cmdline_not_changed: + // Trigger CursorMovedC autocommands. + if (ccline.cmdpos != prev_cmdpos) + { + trigger_cmd_autocmd(cmdline_type, EVENT_CURSORMOVEDC); + prev_cmdpos = ccline.cmdpos; + } + #ifdef FEAT_SEARCH_EXTRA if (!is_state.incsearch_postponed) continue; @@ -2484,10 +2492,17 @@ cmdline_changed: if (is_state.winid != curwin->w_id) init_incsearch_state(&is_state); #endif + // Trigger CmdlineChanged autocommands. if (trigger_cmdlinechanged) - // Trigger CmdlineChanged autocommands. trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED); + // Trigger CursorMovedC autocommands. + if (ccline.cmdpos != prev_cmdpos) + { + trigger_cmd_autocmd(cmdline_type, EVENT_CURSORMOVEDC); + prev_cmdpos = ccline.cmdpos; + } + #ifdef FEAT_SEARCH_EXTRA if (xpc.xp_context == EXPAND_NOTHING && (KeyTyped || vpeekc() == NUL)) may_do_incsearch_highlighting(firstc, count, &is_state); @@ -3130,31 +3145,15 @@ redraw: windgoto(msg_row, msg_col); pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len; - // We are done when a NL is entered, but not when it comes after an - // odd number of backslashes, that results in a NUL. - if (line_ga.ga_len > 0 && pend[-1] == '\n') + // We are done when a NL is entered, but not when it comes after a + // backslash in prompt mode. + if (line_ga.ga_len > 0 && pend[-1] == '\n' + && (line_ga.ga_len <= 1 || pend[-2] != '\\' || !promptc)) { - int bcount = 0; - - while (line_ga.ga_len - 2 >= bcount && pend[-2 - bcount] == '\\') - ++bcount; - - if (bcount > 0) - { - // Halve the number of backslashes: "\NL" -> "NUL", "\\NL" -> - // "\NL", etc. - line_ga.ga_len -= (bcount + 1) / 2; - pend -= (bcount + 1) / 2; - pend[-1] = '\n'; - } - - if ((bcount & 1) == 0) - { - --line_ga.ga_len; - --pend; - *pend = NUL; - break; - } + --line_ga.ga_len; + --pend; + *pend = NUL; + break; } } @@ -4176,6 +4175,7 @@ get_cmdline_completion(void) { cmdline_info_T *p; char_u *buffer; + int xp_context; if (cmdline_star > 0) return NULL; @@ -4184,15 +4184,21 @@ get_cmdline_completion(void) if (p == NULL || p->xpc == NULL) return NULL; - set_expand_context(p->xpc); - if (p->xpc->xp_context == EXPAND_UNSUCCESSFUL) + xp_context = p->xpc->xp_context; + if (xp_context == EXPAND_NOTHING) + { + set_expand_context(p->xpc); + xp_context = p->xpc->xp_context; + p->xpc->xp_context = EXPAND_NOTHING; + } + if (xp_context == EXPAND_UNSUCCESSFUL) return NULL; - char_u *cmd_compl = cmdcomplete_type_to_str(p->xpc->xp_context); + char_u *cmd_compl = cmdcomplete_type_to_str(xp_context); if (cmd_compl == NULL) return NULL; - if (p->xpc->xp_context == EXPAND_USER_LIST || p->xpc->xp_context == EXPAND_USER_DEFINED) + if (xp_context == EXPAND_USER_LIST || xp_context == EXPAND_USER_DEFINED) { buffer = alloc(STRLEN(cmd_compl) + STRLEN(p->xpc->xp_arg) + 2); if (buffer == NULL) @@ -4308,6 +4314,7 @@ set_cmdline_pos( new_cmdpos = 0; else new_cmdpos = pos; + return 0; } diff --git a/src/fileio.c b/src/fileio.c index e7f3332..d27a172 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3912,7 +3912,7 @@ vim_rename(char_u *from, char_u *to) /* * Create the new file with same permissions as the original. - * Return -1 for failure, 0 for success. + * Return FAIL for failure, OK for success. */ int vim_copyfile(char_u *from, char_u *to) @@ -3936,7 +3936,7 @@ vim_copyfile(char_u *from, char_u *to) ret = mch_lstat((char *)from, &st); if (ret >= 0 && S_ISLNK(st.st_mode)) { - ret = FAIL; + ret = -1; len = readlink((char *)from, linkbuf, MAXPATHL); if (len > 0) diff --git a/src/filepath.c b/src/filepath.c index 9f68d7c..d514aaf 100644 --- a/src/filepath.c +++ b/src/filepath.c @@ -3645,11 +3645,15 @@ dos_expandpath( } else { + stat_T sb; + // no more wildcards, check if there is a match // remove backslashes for the remaining components only if (*path_end != 0) backslash_halve(buf + len + 1); - if (mch_getperm(buf) >= 0) // add existing file + // add existing file + if ((flags & EW_ALLLINKS) ? mch_lstat((char *)buf, &sb) >= 0 + : mch_getperm(buf) >= 0) addfile(gap, buf, flags); } } @@ -3999,6 +4003,8 @@ gen_expand_wildcards( int add_pat; int retval = OK; int did_expand_in_path = FALSE; + char_u *path_option = *curbuf->b_p_path == NUL ? + p_path : curbuf->b_p_path; /* * expand_env() is called to expand things like "~user". If this fails, @@ -4088,7 +4094,7 @@ gen_expand_wildcards( */ if (mch_has_exp_wildcard(p) || (flags & EW_ICASE)) { - if ((flags & EW_PATH) + if ((flags & (EW_PATH | EW_CDPATH)) && !mch_isFullName(p) && !(p[0] == '.' && (vim_ispathsep(p[1]) @@ -4122,8 +4128,8 @@ gen_expand_wildcards( vim_free(t); } - if (did_expand_in_path && ga.ga_len > 0 && (flags & EW_PATH)) - uniquefy_paths(&ga, p); + if (did_expand_in_path && ga.ga_len > 0 && (flags & (EW_PATH | EW_CDPATH))) + uniquefy_paths(&ga, p, path_option); if (p != pat[i]) vim_free(p); } diff --git a/src/findfile.c b/src/findfile.c index 2636609..4310a50 100644 --- a/src/findfile.c +++ b/src/findfile.c @@ -418,6 +418,7 @@ vim_findfile_init( { char_u *helper; void *ptr; + size_t len; helper = walker; ptr = vim_realloc(search_ctx->ffsc_stopdirs_v, @@ -428,18 +429,21 @@ vim_findfile_init( // ignore, keep what we have and continue break; walker = vim_strchr(walker, ';'); - if (walker) + len = walker ? (size_t)(walker - helper) : STRLEN(helper); + // "" means ascent till top of directory tree. + if (*helper != NUL && !vim_isAbsName(helper) + && len + 1 < MAXPATHL) { + // Make the stop dir an absolute path name. + vim_strncpy(ff_expand_buffer, helper, len); search_ctx->ffsc_stopdirs_v[dircount-1] = - vim_strnsave(helper, walker - helper); - walker++; + FullName_save(ff_expand_buffer, FALSE); } else - // this might be "", which means ascent till top - // of directory tree. search_ctx->ffsc_stopdirs_v[dircount-1] = - vim_strsave(helper); - + vim_strnsave(helper, len); + if (walker) + walker++; dircount++; } while (walker != NULL); @@ -1078,11 +1082,13 @@ vim_findfile(void *search_ctx_arg) && search_ctx->ffsc_stopdirs_v != NULL && !got_int) { ff_stack_T *sptr; + // path_end may point to the NUL or the previous path separator + int plen = (path_end - search_ctx->ffsc_start_dir) + + (*path_end != NUL); // is the last starting directory in the stop list? if (ff_path_in_stoplist(search_ctx->ffsc_start_dir, - (int)(path_end - search_ctx->ffsc_start_dir), - search_ctx->ffsc_stopdirs_v) == TRUE) + plen, search_ctx->ffsc_stopdirs_v) == TRUE) break; // cut of last dir @@ -1521,22 +1527,14 @@ ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v) return TRUE; for (i = 0; stopdirs_v[i] != NULL; i++) - { - if ((int)STRLEN(stopdirs_v[i]) > path_len) - { - // match for parent directory. So '/home' also matches - // '/home/rks'. Check for PATHSEP in stopdirs_v[i], else - // '/home/r' would also match '/home/rks' - if (fnamencmp(stopdirs_v[i], path, path_len) == 0 - && vim_ispathsep(stopdirs_v[i][path_len])) - return TRUE; - } - else - { - if (fnamecmp(stopdirs_v[i], path) == 0) - return TRUE; - } - } + // match for parent directory. So '/home' also matches + // '/home/rks'. Check for PATHSEP in stopdirs_v[i], else + // '/home/r' would also match '/home/rks' + if (fnamencmp(stopdirs_v[i], path, path_len) == 0 + && ((int)STRLEN(stopdirs_v[i]) <= path_len + || vim_ispathsep(stopdirs_v[i][path_len]))) + return TRUE; + return FALSE; } @@ -2213,10 +2211,11 @@ is_unique(char_u *maybe_unique, garray_T *gap, int i) * expanding each into their equivalent path(s). */ static void -expand_path_option(char_u *curdir, garray_T *gap) +expand_path_option( + char_u *curdir, + char_u *path_option, // p_path or p_cdpath + garray_T *gap) { - char_u *path_option = *curbuf->b_p_path == NUL - ? p_path : curbuf->b_p_path; char_u *buf; char_u *p; int len; @@ -2331,7 +2330,10 @@ get_path_cutoff(char_u *fname, garray_T *gap) * that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len". */ void -uniquefy_paths(garray_T *gap, char_u *pattern) +uniquefy_paths( + garray_T *gap, + char_u *pattern, + char_u *path_option) // p_path or p_cdpath { int i; int len; @@ -2374,7 +2376,7 @@ uniquefy_paths(garray_T *gap, char_u *pattern) if ((curdir = alloc(MAXPATHL)) == NULL) goto theend; mch_dirname(curdir, MAXPATHL); - expand_path_option(curdir, &path_ga); + expand_path_option(curdir, path_option, &path_ga); in_curdir = ALLOC_CLEAR_MULT(char_u *, gap->ga_len); if (in_curdir == NULL) @@ -2522,13 +2524,17 @@ expand_in_path( garray_T path_ga; char_u *paths = NULL; int glob_flags = 0; + char_u *path_option = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; if ((curdir = alloc(MAXPATHL)) == NULL) return 0; mch_dirname(curdir, MAXPATHL); ga_init2(&path_ga, sizeof(char_u *), 1); - expand_path_option(curdir, &path_ga); + if (flags & EW_CDPATH) + expand_path_option(curdir, p_cdpath, &path_ga); + else + expand_path_option(curdir, path_option, &path_ga); vim_free(curdir); if (path_ga.ga_len == 0) return 0; @@ -2542,7 +2548,7 @@ expand_in_path( glob_flags |= WILD_ICASE; if (flags & EW_ADDSLASH) glob_flags |= WILD_ADD_SLASH; - globpath(paths, pattern, gap, glob_flags, FALSE); + globpath(paths, pattern, gap, glob_flags, !!(flags & EW_CDPATH)); vim_free(paths); return gap->ga_len; @@ -1492,6 +1492,9 @@ deleteFoldRecurse(garray_T *gap) // foldMarkAdjust() {{{2 /* * Update line numbers of folds for inserted/deleted lines. + * + * We are adjusting the folds in the range from line1 til line2, + * make sure that line2 does not get smaller than line1 */ void foldMarkAdjust( @@ -1505,6 +1508,8 @@ foldMarkAdjust( // lines, set line2 so that only deleted lines have their folds removed. if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after) line2 = line1 - amount_after - 1; + if (line2 < line1) + line2 = line1; // If appending a line in Insert mode, it should be included in the fold // just above the line. if ((State & MODE_INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) diff --git a/src/getchar.c b/src/getchar.c index 1c544da..96e180f 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -42,6 +42,11 @@ static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0}; static int typeahead_char = 0; // typeahead char that's not flushed +#ifdef FEAT_EVAL +static char_u typedchars[MAXMAPLEN + 1] = { NUL }; // typed chars before map +static int typedchars_pos = 0; +#endif + /* * When block_redo is TRUE the redo buffer will not be changed. * Used by edit() to repeat insertions. @@ -96,6 +101,9 @@ static void closescript(void); static void updatescript(int c); static int vgetorpeek(int); static int inchar(char_u *buf, int maxlen, long wait_time); +#ifdef FEAT_EVAL +static int do_key_input_pre(int c); +#endif /* * Free and clear a buffer. @@ -438,9 +446,18 @@ flush_buffers(flush_buffers_T flush_typeahead) if (flush_typeahead == FLUSH_MINIMAL) { - // remove mapped characters at the start only - typebuf.tb_off += typebuf.tb_maplen; - typebuf.tb_len -= typebuf.tb_maplen; + // remove mapped characters at the start only, + // but only when enough space left in typebuf + if (typebuf.tb_off + typebuf.tb_maplen >= typebuf.tb_buflen) + { + typebuf.tb_off = MAXMAPLEN; + typebuf.tb_len = 0; + } + else + { + typebuf.tb_off += typebuf.tb_maplen; + typebuf.tb_len -= typebuf.tb_maplen; + } #if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL) if (typebuf.tb_len == 0) typebuf_was_filled = FALSE; @@ -1706,6 +1723,13 @@ updatescript(int c) ml_sync_all(c == 0, TRUE); count = 0; } +#ifdef FEAT_EVAL + if (typedchars_pos < MAXMAPLEN) + { + typedchars[typedchars_pos] = c; + typedchars_pos++; + } +#endif } /* @@ -1996,8 +2020,45 @@ vgetc(void) #endif } - // a keypad or special function key was not mapped, use it like - // its ASCII equivalent + // For a multi-byte character get all the bytes and return the + // converted character. + // Note: This will loop until enough bytes are received! + if (has_mbyte && (n = MB_BYTE2LEN_CHECK(c)) > 1) + { + ++no_mapping; + buf[0] = c; + for (i = 1; i < n; ++i) + { + buf[i] = vgetorpeek(TRUE); + if (buf[i] == K_SPECIAL +#ifdef FEAT_GUI + || (buf[i] == CSI) +#endif + ) + { + // Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER + // sequence, which represents a K_SPECIAL (0x80), + // or a CSI - KS_EXTRA - KE_CSI sequence, which + // represents a CSI (0x9B), + // or a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI + // too. + c = vgetorpeek(TRUE); + if (vgetorpeek(TRUE) == KE_CSI && c == KS_EXTRA) + buf[i] = CSI; + } + } + --no_mapping; + c = (*mb_ptr2char)(buf); + } + + if (vgetc_char == 0) + { + vgetc_mod_mask = mod_mask; + vgetc_char = c; + } + + // A keypad or special function key was not mapped, use it like + // its ASCII equivalent. switch (c) { case K_KPLUS: c = '+'; break; @@ -2059,43 +2120,6 @@ vgetc(void) case K_XRIGHT: c = K_RIGHT; break; } - // For a multi-byte character get all the bytes and return the - // converted character. - // Note: This will loop until enough bytes are received! - if (has_mbyte && (n = MB_BYTE2LEN_CHECK(c)) > 1) - { - ++no_mapping; - buf[0] = c; - for (i = 1; i < n; ++i) - { - buf[i] = vgetorpeek(TRUE); - if (buf[i] == K_SPECIAL -#ifdef FEAT_GUI - || (buf[i] == CSI) -#endif - ) - { - // Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER - // sequence, which represents a K_SPECIAL (0x80), - // or a CSI - KS_EXTRA - KE_CSI sequence, which - // represents a CSI (0x9B), - // or a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI - // too. - c = vgetorpeek(TRUE); - if (vgetorpeek(TRUE) == KE_CSI && c == KS_EXTRA) - buf[i] = CSI; - } - } - --no_mapping; - c = (*mb_ptr2char)(buf); - } - - if (vgetc_char == 0) - { - vgetc_mod_mask = mod_mask; - vgetc_char = c; - } - break; } @@ -2130,6 +2154,13 @@ vgetc(void) } #endif +#ifdef FEAT_EVAL + c = do_key_input_pre(c); + + // Clear the next typedchars_pos + typedchars_pos = 0; +#endif + // Need to process the character before we know it's safe to do something // else. if (c != K_IGNORE) @@ -2138,6 +2169,78 @@ vgetc(void) return c; } +#ifdef FEAT_EVAL +/* + * Handle the InsertCharPre autocommand. + * "c" is the character that was typed. + * Return new input character. + */ + static int +do_key_input_pre(int c) +{ + int res = c; + char_u buf[MB_MAXBYTES + 1]; + char_u curr_mode[MODE_MAX_LENGTH]; + int save_State = State; + save_v_event_T save_v_event; + dict_T *v_event; + + // Return quickly when there is nothing to do. + if (!has_keyinputpre()) + return res; + + if (IS_SPECIAL(c)) + { + buf[0] = K_SPECIAL; + buf[1] = KEY2TERMCAP0(c); + buf[2] = KEY2TERMCAP1(c); + buf[3] = NUL; + } + else + buf[(*mb_char2bytes)(c, buf)] = NUL; + + typedchars[typedchars_pos] = NUL; + vim_unescape_csi(typedchars); + + get_mode(curr_mode); + + // Lock the text to avoid weird things from happening. + ++textlock; + set_vim_var_string(VV_CHAR, buf, -1); // set v:char + + v_event = get_v_event(&save_v_event); + (void)dict_add_bool(v_event, "typed", KeyTyped); + (void)dict_add_string(v_event, "typedchar", typedchars); + + if (apply_autocmds(EVENT_KEYINPUTPRE, curr_mode, curr_mode, FALSE, curbuf) + && STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0) + { + // Get the value of v:char. It may be empty or more than one + // character. Only use it when changed, otherwise continue with the + // original character. + char_u *v_char; + + v_char = get_vim_var_str(VV_CHAR); + + // Convert special bytes when it is special string. + if (STRLEN(v_char) >= 3 && v_char[0] == K_SPECIAL) + res = TERMCAP2KEY(v_char[1], v_char[2]); + else if (STRLEN(v_char) > 0) + res = PTR2CHAR(v_char); + } + + restore_v_event(v_event, &save_v_event); + + set_vim_var_string(VV_CHAR, NULL, -1); // clear v:char + --textlock; + + // Restore the State, it may have been changed. + State = save_State; + + return res; +} +#endif + /* * Like vgetc(), but never return a NUL when called recursively, get a key * directly from the user (ignoring typeahead). @@ -2841,8 +2944,11 @@ handle_mapping( } } else + { // No match; may have to check for termcode at next - // character. If the first character that didn't match is + // character. + + // If the first character that didn't match is // K_SPECIAL then check for a termcode. This isn't perfect // but should work in most cases. if (max_mlen < mlen) @@ -2852,6 +2958,12 @@ handle_mapping( } else if (max_mlen == mlen && mp->m_keys[mlen] == K_SPECIAL) want_termcode = 1; + + // Check termcode for uppercase character to properly + // process "ESC[27;2;<ascii code>~" control sequences. + if (ASCII_ISUPPER(mp->m_keys[mlen])) + want_termcode = 1; + } } } @@ -3053,6 +3165,8 @@ handle_mapping( int save_m_noremap; int save_m_silent; char_u *save_m_keys; + char_u *save_alt_m_keys; + int save_alt_m_keylen; #else # define save_m_noremap mp->m_noremap # define save_m_silent mp->m_silent @@ -3101,6 +3215,8 @@ handle_mapping( save_m_noremap = mp->m_noremap; save_m_silent = mp->m_silent; save_m_keys = NULL; // only saved when needed + save_alt_m_keys = NULL; // only saved when needed + save_alt_m_keylen = mp->m_alt != NULL ? mp->m_alt->m_keylen : 0; /* * Handle ":map <expr>": evaluate the {rhs} as an expression. Also @@ -3117,7 +3233,10 @@ handle_mapping( vgetc_busy = 0; may_garbage_collect = FALSE; - save_m_keys = vim_strsave(mp->m_keys); + save_m_keys = vim_strnsave(mp->m_keys, (size_t)mp->m_keylen); + save_alt_m_keys = mp->m_alt != NULL + ? vim_strnsave(mp->m_alt->m_keys, + (size_t)save_alt_m_keylen) : NULL; map_str = eval_map_expr(mp, NUL); // The mapping may do anything, but we expect it to take care of @@ -3175,15 +3294,20 @@ handle_mapping( noremap = save_m_noremap; else if ( #ifdef FEAT_EVAL - STRNCMP(map_str, save_m_keys != NULL ? save_m_keys : mp->m_keys, - (size_t)keylen) -#else - STRNCMP(map_str, mp->m_keys, (size_t)keylen) + save_m_expr ? + (save_m_keys != NULL + && STRNCMP(map_str, save_m_keys, (size_t)keylen) == 0) + || (save_alt_m_keys != NULL + && STRNCMP(map_str, save_alt_m_keys, + (size_t)save_alt_m_keylen) == 0) : #endif - != 0) - noremap = REMAP_YES; - else + STRNCMP(map_str, mp->m_keys, (size_t)keylen) == 0 + || (mp->m_alt != NULL + && STRNCMP(map_str, mp->m_alt->m_keys, + (size_t)mp->m_alt->m_keylen) == 0)) noremap = REMAP_SKIP; + else + noremap = REMAP_YES; i = ins_typebuf(map_str, noremap, 0, TRUE, cmd_silent || save_m_silent); #ifdef FEAT_EVAL @@ -3193,6 +3317,7 @@ handle_mapping( } #ifdef FEAT_EVAL vim_free(save_m_keys); + vim_free(save_alt_m_keys); #endif *keylenp = keylen; if (i == FAIL) diff --git a/src/globals.h b/src/globals.h index fb5c7b3..77ddea8 100644 --- a/src/globals.h +++ b/src/globals.h @@ -131,8 +131,8 @@ EXTERN int screen_Columns INIT(= 0); // actual size of ScreenLines[] */ EXTERN int mod_mask INIT(= 0); // current key modifiers -// The value of "mod_mask" and the unomdified character before calling -// merge_modifyOtherKeys(). +// The value of "mod_mask" and the unmodified character in vgetc() after it has +// called vgetorpeek() enough times. EXTERN int vgetc_mod_mask INIT(= 0); EXTERN int vgetc_char INIT(= 0); @@ -519,31 +519,37 @@ EXTERN int garbage_collect_at_exit INIT(= FALSE); #define t_list_list_any (static_types[70]) #define t_const_list_list_any (static_types[71]) -#define t_list_list_string (static_types[72]) -#define t_const_list_list_string (static_types[73]) +#define t_list_list_number (static_types[72]) +#define t_const_list_list_number (static_types[73]) -#define t_dict_bool (static_types[74]) -#define t_const_dict_bool (static_types[75]) +#define t_list_list_string (static_types[74]) +#define t_const_list_list_string (static_types[75]) -#define t_dict_number (static_types[76]) -#define t_const_dict_number (static_types[77]) +#define t_list_list_list_number (static_types[76]) +#define t_const_list_list_list_number (static_types[77]) -#define t_dict_string (static_types[78]) -#define t_const_dict_string (static_types[79]) +#define t_dict_bool (static_types[78]) +#define t_const_dict_bool (static_types[79]) -#define t_super (static_types[80]) -#define t_const_super (static_types[81]) +#define t_dict_number (static_types[80]) +#define t_const_dict_number (static_types[81]) -#define t_object (static_types[82]) -#define t_const_object (static_types[83]) +#define t_dict_string (static_types[82]) +#define t_const_dict_string (static_types[83]) -#define t_class (static_types[84]) -#define t_const_class (static_types[85]) +#define t_super (static_types[84]) +#define t_const_super (static_types[85]) -#define t_typealias (static_types[86]) -#define t_const_typealias (static_types[87]) +#define t_object (static_types[86]) +#define t_const_object (static_types[87]) -EXTERN type_T static_types[88] +#define t_class (static_types[88]) +#define t_const_class (static_types[89]) + +#define t_typealias (static_types[90]) +#define t_const_typealias (static_types[91]) + +EXTERN type_T static_types[92] #ifdef DO_INIT = { // 0: t_unknown @@ -690,35 +696,43 @@ EXTERN type_T static_types[88] {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_any, NULL, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_any, NULL, NULL}, - // 72: t_list_list_string + // 74: t_list_list_number + {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_number, NULL, NULL}, + {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_number, NULL, NULL}, + + // 74: t_list_list_string {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_string, NULL, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_string, NULL, NULL}, - // 74: t_dict_bool + // 76: t_list_list_list_number + {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_list_number, NULL, NULL}, + {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_list_number, NULL, NULL}, + + // 78: t_dict_bool {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_bool, NULL, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL, NULL}, - // 76: t_dict_number + // 80: t_dict_number {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_number, NULL, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL, NULL}, - // 78: t_dict_string + // 82: t_dict_string {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_string, NULL, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL, NULL}, - // 80: t_super (VAR_CLASS with tt_member set to &t_bool + // 84: t_super (VAR_CLASS with tt_member set to &t_bool {VAR_CLASS, 0, 0, TTFLAG_STATIC, &t_bool, NULL, NULL}, {VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL, NULL}, - // 82: t_object + // 86: t_object {VAR_OBJECT, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL}, {VAR_OBJECT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL}, - // 84: t_class + // 88: t_class {VAR_CLASS, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL}, {VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL}, - // 86: t_typealias + // 90: t_typealias {VAR_TYPEALIAS, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL}, {VAR_TYPEALIAS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL}, } @@ -460,7 +460,7 @@ gui_init_check(void) // and in that case we don't want to overwrite ligatures map that has already // been correctly populated (as that would lead to a cleared ligatures maps). if (*p_guiligatures == NUL) - CLEAR_FIELD(gui.ligatures_map); + CLEAR_FIELD(gui.ligatures_map); #endif #if defined(ALWAYS_USE_GUI) || defined(VIMDLL) diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index 67ee531..6c97d1a 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -797,8 +797,8 @@ draw_event(GtkWidget *widget UNUSED, # if GTK_CHECK_VERSION(3,10,0) static gboolean scale_factor_event(GtkWidget *widget, - GParamSpec* pspec UNUSED, - gpointer user_data UNUSED) + GParamSpec* pspec UNUSED, + gpointer user_data UNUSED) { if (gui.surface != NULL) cairo_surface_destroy(gui.surface); diff --git a/src/gui_w32.c b/src/gui_w32.c index f628dd6..78f252a 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -274,13 +274,9 @@ gui_mch_set_rendering_options(char_u *s) // cproto fails on missing include files #ifndef PROTO - -# ifndef __MINGW32__ -# include <shellapi.h> -# endif +# include <shellapi.h> # include <commctrl.h> # include <windowsx.h> - #endif // PROTO #ifdef FEAT_MENU @@ -5526,6 +5522,9 @@ gui_mch_prepare(int *argc, char **argv) } #ifdef FEAT_OLE +# ifdef VIMDLL + if (mch_is_gui_executable()) +# endif { int bDoRestart = FALSE; @@ -813,6 +813,8 @@ fix_help_buffer(void) f1 = fnames[i1]; t1 = gettail(f1); e1 = vim_strrchr(t1, '.'); + if (e1 == NULL) + continue; if (fnamecmp(e1, ".txt") != 0 && fnamecmp(e1, fname + 4) != 0) { @@ -828,6 +830,8 @@ fix_help_buffer(void) continue; t2 = gettail(f2); e2 = vim_strrchr(t2, '.'); + if (e2 == NULL) + continue; if (e1 - f1 != e2 - f2 || fnamencmp(f1, f2, e1 - f1) != 0) continue; diff --git a/src/highlight.c b/src/highlight.c index a71a100..d3ea2d2 100644 --- a/src/highlight.c +++ b/src/highlight.c @@ -3351,8 +3351,8 @@ syn_list_header( if (msg_col >= endcol) // output at least one space endcol = msg_col + 1; - if (Columns <= endcol) // avoid hang for tiny window - endcol = Columns - 1; + if (Columns <= (long)endcol) // avoid hang for tiny window + endcol = (int)(Columns - 1); msg_advance(endcol); diff --git a/src/if_mzsch.c b/src/if_mzsch.c index 9a9c487..4a8644c 100644 --- a/src/if_mzsch.c +++ b/src/if_mzsch.c @@ -383,7 +383,7 @@ static void (*dll_scheme_set_config_path)(Scheme_Object *p); # define scheme_null dll_scheme_null # define scheme_true dll_scheme_true -// pointers are GetProceAddress'ed as pointers to pointer +// pointers are GetProcAddress'ed as pointers to pointer #if !defined(USE_THREAD_LOCAL) && !defined(LINK_EXTENSIONS_BY_TABLE) # define scheme_current_thread (*dll_scheme_current_thread_ptr) # endif @@ -924,7 +924,7 @@ mzscheme_end(void) #endif } -#if HAVE_TLS_SPACE +#if HAVE_TLS_SPACE && !defined(VIMDLL) # if defined(_MSC_VER) static __declspec(thread) void *tls_space; extern intptr_t _tls_index; @@ -960,7 +960,24 @@ mzscheme_main(void) } #endif #ifdef HAVE_TLS_SPACE +# ifdef VIMDLL + void **ptls_space; + intptr_t tls_index; + void (*pget_tls_info)(void ***ptls_space, intptr_t *ptls_index); + + // Get the address of get_tls_info() from (g)vim.exe. + pget_tls_info = (void *)GetProcAddress( + GetModuleHandle(NULL), "get_tls_info"); + if (pget_tls_info == NULL) + { + disabled = TRUE; + return vim_main2(); + } + pget_tls_info(&ptls_space, &tls_index); + scheme_register_tls_space(ptls_space, tls_index); +# else scheme_register_tls_space(&tls_space, _tls_index); +# endif #endif #ifdef TRAMPOLINED_MZVIM_STARTUP return scheme_main_setup(TRUE, mzscheme_env_main, argc, &argv); diff --git a/src/if_py_both.h b/src/if_py_both.h index e0fd3ea..3643f8b 100644 --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -358,7 +358,9 @@ static PyObject *py_find_spec; #else static PyObject *py_load_module; #endif +#if PY_VERSION_HEX < 0x30c00a7 static PyObject *py_find_module; +#endif static PyObject *VimError; @@ -3081,7 +3083,7 @@ ListConcatInPlace(ListObject *self, PyObject *obj) } Py_DECREF(lookup_dict); - Py_INCREF(self); + Py_INCREF((PyObject *)self); return (PyObject *)(self); } @@ -4010,7 +4012,7 @@ TabPageNew(tabpage_T *tab) if (TAB_PYTHON_REF(tab)) { self = TAB_PYTHON_REF(tab); - Py_INCREF(self); + Py_INCREF((PyObject *)self); } else { @@ -4204,7 +4206,7 @@ WindowNew(win_T *win, tabpage_T *tab) if (WIN_PYTHON_REF(win)) { self = WIN_PYTHON_REF(win); - Py_INCREF(self); + Py_INCREF((PyObject *)self); } else { @@ -4332,7 +4334,7 @@ WindowAttr(WindowObject *self, char *name) } else if (strcmp(name, "tabpage") == 0) { - Py_INCREF(self->tabObject); + Py_INCREF((PyObject *)self->tabObject); return (PyObject *)(self->tabObject); } else if (strcmp(name, "__members__") == 0) @@ -4486,7 +4488,7 @@ WinListNew(TabPageObject *tabObject) self = PyObject_NEW(WinListObject, WinListTypePtr); self->tabObject = tabObject; - Py_INCREF(tabObject); + Py_INCREF((PyObject *)tabObject); return (PyObject *)(self); } @@ -5381,7 +5383,7 @@ RangeNew(buf_T *buf, PyInt start, PyInt end) Py_DECREF(self); return NULL; } - Py_INCREF(bufr); + Py_INCREF((PyObject *)bufr); self->buf = bufr; self->start = start; @@ -5510,7 +5512,7 @@ BufferNew(buf_T *buf) if (BUF_PYTHON_REF(buf) != NULL) { self = BUF_PYTHON_REF(buf); - Py_INCREF(self); + Py_INCREF((PyObject *)self); } else { diff --git a/src/if_python3.c b/src/if_python3.c index c135e7e..ac817bd 100644 --- a/src/if_python3.c +++ b/src/if_python3.c @@ -219,6 +219,17 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll # define PyObject_GetItem py3_PyObject_GetItem # define PyObject_IsTrue py3_PyObject_IsTrue # define PyModule_GetDict py3_PyModule_GetDict +# if defined(USE_LIMITED_API) \ + && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG)) +# undef Py_INCREF +# if Py_LIMITED_API+0 >= 0x030a00A7 +# define _Py_IncRef py3__Py_IncRef +# define Py_INCREF _Py_IncRef +# else +# define Py_IncRef py3_Py_IncRef +# define Py_INCREF Py_IncRef +# endif +# endif # ifdef USE_LIMITED_API # define Py_CompileString py3_Py_CompileString # define PyEval_EvalCode py3_PyEval_EvalCode @@ -232,7 +243,11 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll # define PyObject_HasAttrString py3_PyObject_HasAttrString # define PyObject_SetAttrString py3_PyObject_SetAttrString # define PyObject_CallFunctionObjArgs py3_PyObject_CallFunctionObjArgs -# define _PyObject_CallFunction_SizeT py3__PyObject_CallFunction_SizeT +# if PY_VERSION_HEX >= 0x030d0000 +# define PyObject_CallFunction py3_PyObject_CallFunction +# else +# define _PyObject_CallFunction_SizeT py3__PyObject_CallFunction_SizeT +# endif # define PyObject_Call py3_PyObject_Call # define PyEval_GetLocals py3_PyEval_GetLocals # define PyEval_GetGlobals py3_PyEval_GetGlobals @@ -387,6 +402,15 @@ static void (*py3_Py_Finalize)(void); static void (*py3_PyErr_SetString)(PyObject *, const char *); static void (*py3_PyErr_SetObject)(PyObject *, PyObject *); static int (*py3_PyErr_ExceptionMatches)(PyObject *); +# if defined(USE_LIMITED_API) \ + && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG)) +# if Py_LIMITED_API+0 >= 0x030a00A7 +# define _Py_IncRef py3__Py_IncRef +static void (*py3__Py_IncRef)(PyObject *); +# else +static void (*py3_Py_IncRef)(PyObject *); +# endif +# endif # ifdef USE_LIMITED_API static PyObject* (*py3_Py_CompileString)(const char *, const char *, int); static PyObject* (*py3_PyEval_EvalCode)(PyObject *co, PyObject *globals, PyObject *locals); @@ -398,7 +422,11 @@ static PyObject* (*py3_PyObject_GetAttrString)(PyObject *, const char *); static int (*py3_PyObject_HasAttrString)(PyObject *, const char *); static int (*py3_PyObject_SetAttrString)(PyObject *, const char *, PyObject *); static PyObject* (*py3_PyObject_CallFunctionObjArgs)(PyObject *, ...); +# if PY_VERSION_HEX >= 0x030d0000 +static PyObject* (*py3_PyObject_CallFunction)(PyObject *, char *, ...); +# else static PyObject* (*py3__PyObject_CallFunction_SizeT)(PyObject *, char *, ...); +# endif static PyObject* (*py3_PyObject_Call)(PyObject *, PyObject *, PyObject *); static PyObject* (*py3_PyEval_GetGlobals)(void); static PyObject* (*py3_PyEval_GetLocals)(void); @@ -590,6 +618,14 @@ static struct {"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString}, {"PyErr_SetObject", (PYTHON_PROC*)&py3_PyErr_SetObject}, {"PyErr_ExceptionMatches", (PYTHON_PROC*)&py3_PyErr_ExceptionMatches}, +# if defined(USE_LIMITED_API) \ + && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG)) +# if Py_LIMITED_API+0 >= 0x030a00A7 + {"_Py_IncRef", (PYTHON_PROC*)&py3__Py_IncRef}, +# else + {"Py_IncRef", (PYTHON_PROC*)&py3_Py_IncRef}, +# endif +# endif # ifdef USE_LIMITED_API {"Py_CompileString", (PYTHON_PROC*)&py3_Py_CompileString}, {"PyEval_EvalCode", (PYTHON_PROC*)&PyEval_EvalCode}, @@ -601,7 +637,11 @@ static struct {"PyObject_HasAttrString", (PYTHON_PROC*)&py3_PyObject_HasAttrString}, {"PyObject_SetAttrString", (PYTHON_PROC*)&py3_PyObject_SetAttrString}, {"PyObject_CallFunctionObjArgs", (PYTHON_PROC*)&py3_PyObject_CallFunctionObjArgs}, +# if PY_VERSION_HEX >= 0x030d0000 + {"PyObject_CallFunction", (PYTHON_PROC*)&py3_PyObject_CallFunction}, +# else {"_PyObject_CallFunction_SizeT", (PYTHON_PROC*)&py3__PyObject_CallFunction_SizeT}, +# endif {"PyObject_Call", (PYTHON_PROC*)&py3_PyObject_Call}, {"PyEval_GetGlobals", (PYTHON_PROC*)&py3_PyEval_GetGlobals}, {"PyEval_GetLocals", (PYTHON_PROC*)&py3_PyEval_GetLocals}, @@ -762,6 +802,20 @@ py3__Py_XDECREF(PyObject *op) # define Py_XDECREF(op) py3__Py_XDECREF(_PyObject_CAST(op)) # endif +# if defined(USE_LIMITED_API) \ + && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG)) + static inline void +py3__Py_XINCREF(PyObject *op) +{ + if (op != NULL) + { + Py_INCREF(op); + } +} +# undef Py_XINCREF +# define Py_XINCREF(op) py3__Py_XINCREF(_PyObject_CAST(op)) +# endif + # if PY_VERSION_HEX >= 0x030900b0 static inline int py3_PyType_HasFeature(PyTypeObject *type, unsigned long feature) @@ -1067,7 +1121,7 @@ static int python_end_called = FALSE; #ifdef USE_LIMITED_API # define DESTRUCTOR_FINISH(self) \ - ((freefunc)PyType_GetSlot(Py_TYPE(self), Py_tp_free))((PyObject*)self) + ((freefunc)PyType_GetSlot(Py_TYPE((PyObject*)self), Py_tp_free))((PyObject*)self) #else # define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self) #endif diff --git a/src/indent.c b/src/indent.c index 777db24..0d6fadb 100644 --- a/src/indent.c +++ b/src/indent.c @@ -996,7 +996,7 @@ get_breakindent_win( # else if (wp->w_briopt_vcol == 0) prev_indent = get_indent_str(line, - (int)wp->w_buffer->b_p_ts, no_ts); + (int)wp->w_buffer->b_p_ts, no_ts); # endif prev_tick = CHANGEDTICK(wp->w_buffer); prev_listopt = wp->w_briopt_list; diff --git a/src/insexpand.c b/src/insexpand.c index c673df9..af818d4 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -58,7 +58,7 @@ static char *ctrl_x_msgs[] = N_(" Command-line completion (^V^N^P)"), N_(" User defined completion (^U^N^P)"), N_(" Omni completion (^O^N^P)"), - N_(" Spelling suggestion (s^N^P)"), + N_(" Spelling suggestion (^S^N^P)"), N_(" Keyword Local completion (^N^P)"), NULL, // CTRL_X_EVAL doesn't use msg. N_(" Command-line completion (^V^N^P)"), @@ -114,6 +114,8 @@ struct compl_S int cp_flags; // CP_ values int cp_number; // sequence number int cp_score; // fuzzy match score + int cp_user_hlattr; // highlight attribute to combine with + int cp_user_kind_hlattr; // highlight attribute for kind }; // values for cp_flags @@ -203,7 +205,9 @@ static int compl_opt_suppress_empty = FALSE; static int compl_selected_item = -1; -static int ins_compl_add(char_u *str, int len, char_u *fname, char_u **cptext, typval_T *user_data, int cdir, int flags, int adup); +static int *compl_fuzzy_scores; + +static int ins_compl_add(char_u *str, int len, char_u *fname, char_u **cptext, typval_T *user_data, int cdir, int flags, int adup, int user_hlattr, int user_kind_hlattr); static void ins_compl_longest_match(compl_T *match); static void ins_compl_del_pum(void); static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir); @@ -743,7 +747,7 @@ ins_compl_add_infercase( if (icase) flags |= CP_ICASE; - res = ins_compl_add(str, len, fname, NULL, NULL, dir, flags, FALSE); + res = ins_compl_add(str, len, fname, NULL, NULL, dir, flags, FALSE, -1, -1); vim_free(tofree); return res; } @@ -776,7 +780,9 @@ ins_compl_add( typval_T *user_data UNUSED, // "user_data" entry or NULL int cdir, int flags_arg, - int adup) // accept duplicate match + int adup, // accept duplicate match + int user_hlattr, + int user_kind_hlattr) { compl_T *match; int dir = (cdir == 0 ? compl_direction : cdir); @@ -840,6 +846,8 @@ ins_compl_add( else match->cp_fname = NULL; match->cp_flags = flags; + match->cp_user_hlattr = user_hlattr; + match->cp_user_kind_hlattr = user_kind_hlattr; if (cptext != NULL) { @@ -992,7 +1000,7 @@ ins_compl_add_matches( for (i = 0; i < num_matches && add_r != FAIL; i++) if ((add_r = ins_compl_add(matches[i], -1, NULL, NULL, NULL, dir, - CP_FAST | (icase ? CP_ICASE : 0), FALSE)) == OK) + CP_FAST | (icase ? CP_ICASE : 0), FALSE, -1, -1)) == OK) // if dir was BACKWARD then honor it just once dir = FORWARD; FreeWild(num_matches, matches); @@ -1306,7 +1314,13 @@ ins_compl_build_pum(void) { did_find_shown_match = TRUE; max_fuzzy_score = compl->cp_score; - compl_shown_match = compl; + if (!compl_no_select) + compl_shown_match = compl; + } + + if (!shown_match_ok && compl == compl_shown_match && !compl_no_select) + { + cur = i; shown_match_ok = TRUE; } @@ -1318,8 +1332,6 @@ ins_compl_build_pum(void) && (max_fuzzy_score > 0 || (compl_leader == NULL || lead_len == 0))) { - shown_match_ok = TRUE; - cur = 0; if (match_at_original_text(compl_shown_match)) compl_shown_match = shown_compl; } @@ -1333,6 +1345,8 @@ ins_compl_build_pum(void) compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND]; compl_match_array[i].pum_info = compl->cp_text[CPT_INFO]; compl_match_array[i].pum_score = compl->cp_score; + compl_match_array[i].pum_user_hlattr = compl->cp_user_hlattr; + compl_match_array[i].pum_user_kind_hlattr = compl->cp_user_kind_hlattr; if (compl->cp_text[CPT_MENU] != NULL) compl_match_array[i++].pum_extra = compl->cp_text[CPT_MENU]; @@ -1367,6 +1381,7 @@ ins_compl_build_pum(void) // sort by the largest score of fuzzy match qsort(compl_match_array, (size_t)compl_match_arraysize, sizeof(pumitem_T), ins_compl_fuzzy_cmp); + shown_match_ok = TRUE; } if (!shown_match_ok) // no displayed match at all @@ -2833,6 +2848,14 @@ theend: #endif // FEAT_COMPL_FUNC #if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) || defined(PROTO) + + static inline int +get_user_highlight_attr(char_u *hlname) +{ + if (hlname != NULL && *hlname != NUL) + return syn_name2attr(hlname); + return -1; +} /* * Add a match to the list of matches from a typeval_T. * If the given string is already in the list of completions, then return @@ -2850,6 +2873,10 @@ ins_compl_add_tv(typval_T *tv, int dir, int fast) char_u *(cptext[CPT_COUNT]); typval_T user_data; int status; + char_u *user_hlname; + char_u *user_kind_hlname; + int user_hlattr = -1; + int user_kind_hlattr = -1; user_data.v_type = VAR_UNKNOWN; if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) @@ -2859,6 +2886,13 @@ ins_compl_add_tv(typval_T *tv, int dir, int fast) cptext[CPT_MENU] = dict_get_string(tv->vval.v_dict, "menu", FALSE); cptext[CPT_KIND] = dict_get_string(tv->vval.v_dict, "kind", FALSE); cptext[CPT_INFO] = dict_get_string(tv->vval.v_dict, "info", FALSE); + + user_hlname = dict_get_string(tv->vval.v_dict, "hl_group", FALSE); + user_hlattr = get_user_highlight_attr(user_hlname); + + user_kind_hlname = dict_get_string(tv->vval.v_dict, "kind_hlgroup", FALSE); + user_kind_hlattr = get_user_highlight_attr(user_kind_hlname); + dict_get_tv(tv->vval.v_dict, "user_data", &user_data); if (dict_get_string(tv->vval.v_dict, "icase", FALSE) != NULL && dict_get_number(tv->vval.v_dict, "icase")) @@ -2881,7 +2915,8 @@ ins_compl_add_tv(typval_T *tv, int dir, int fast) clear_tv(&user_data); return FAIL; } - status = ins_compl_add(word, -1, NULL, cptext, &user_data, dir, flags, dup); + status = ins_compl_add(word, -1, NULL, cptext, + &user_data, dir, flags, dup, user_hlattr, user_kind_hlattr); if (status != OK) clear_tv(&user_data); return status; @@ -2968,7 +3003,7 @@ set_completion(colnr_T startcol, list_T *list) flags |= CP_ICASE; if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, -1, NULL, NULL, NULL, 0, - flags | CP_FAST, FALSE) != OK) + flags | CP_FAST, FALSE, -1, -1) != OK) return; ctrl_x_mode = CTRL_X_EVAL; @@ -3318,7 +3353,8 @@ typedef struct process_next_cpt_value( ins_compl_next_state_T *st, int *compl_type_arg, - pos_T *start_match_pos) + pos_T *start_match_pos, + int in_fuzzy) { int compl_type = -1; int status = INS_COMPL_CPT_OK; @@ -3334,7 +3370,7 @@ process_next_cpt_value( st->first_match_pos = *start_match_pos; // Move the cursor back one character so that ^N can match the // word immediately after the cursor. - if (ctrl_x_mode_normal() && dec(&st->first_match_pos) < 0) + if (ctrl_x_mode_normal() && (!in_fuzzy && dec(&st->first_match_pos) < 0)) { // Move the cursor to after the last character in the // buffer, so that word at start of buffer is found @@ -3502,6 +3538,18 @@ get_next_tag_completion(void) } /* + * Compare function for qsort + */ +static int compare_scores(const void *a, const void *b) +{ + int idx_a = *(const int *)a; + int idx_b = *(const int *)b; + int score_a = compl_fuzzy_scores[idx_a]; + int score_b = compl_fuzzy_scores[idx_b]; + return (score_a > score_b) ? -1 : (score_a < score_b) ? 1 : 0; +} + +/* * Get the next set of filename matching "compl_pattern". */ static void @@ -3509,6 +3557,77 @@ get_next_filename_completion(void) { char_u **matches; int num_matches; + char_u *ptr; + garray_T fuzzy_indices; + int i; + int score; + char_u *leader = ins_compl_leader(); + size_t leader_len = STRLEN(leader); + int in_fuzzy = ((get_cot_flags() & COT_FUZZY) != 0 && leader_len > 0); + char_u **sorted_matches; + int *fuzzy_indices_data; + char_u *last_sep = NULL; + size_t path_with_wildcard_len; + char_u *path_with_wildcard; + +#ifdef BACKSLASH_IN_FILENAME + char pathsep = (curbuf->b_p_csl[0] == 's') ? + '/' : (curbuf->b_p_csl[0] == 'b') ? '\\' : PATHSEP; +#else + char pathsep = PATHSEP; +#endif + + if (in_fuzzy) + { +#ifdef BACKSLASH_IN_FILENAME + if (curbuf->b_p_csl[0] == 's') + { + for (i = 0; i < leader_len; i++) + { + if (leader[i] == '\\') + leader[i] = '/'; + } + } + else if (curbuf->b_p_csl[0] == 'b') + { + for (i = 0; i < leader_len; i++) + { + if (leader[i] == '/') + leader[i] = '\\'; + } + } +#endif + last_sep = vim_strrchr(leader, pathsep); + if (last_sep == NULL) + { + // No path separator or separator is the last character, + // fuzzy match the whole leader + vim_free(compl_pattern); + compl_pattern = vim_strsave((char_u *)"*"); + compl_patternlen = STRLEN(compl_pattern); + } + else if (*(last_sep + 1) == '\0') + in_fuzzy = FALSE; + else + { + // Split leader into path and file parts + int path_len = last_sep - leader + 1; + path_with_wildcard_len = path_len + 2; + path_with_wildcard = alloc(path_with_wildcard_len); + if (path_with_wildcard != NULL) + { + vim_strncpy(path_with_wildcard, leader, path_len); + vim_strcat(path_with_wildcard, (char_u *)"*", path_with_wildcard_len); + vim_free(compl_pattern); + compl_pattern = path_with_wildcard; + compl_patternlen = STRLEN(compl_pattern); + + // Move leader to the file part + leader = last_sep + 1; + leader_len = STRLEN(leader); + } + } + } if (expand_wildcards(1, &compl_pattern, &num_matches, &matches, EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) != OK) @@ -3519,12 +3638,9 @@ get_next_filename_completion(void) #ifdef BACKSLASH_IN_FILENAME if (curbuf->b_p_csl[0] != NUL) { - int i; - for (i = 0; i < num_matches; ++i) { - char_u *ptr = matches[i]; - + ptr = matches[i]; while (*ptr != NUL) { if (curbuf->b_p_csl[0] == 's' && *ptr == '\\') @@ -3536,7 +3652,53 @@ get_next_filename_completion(void) } } #endif - ins_compl_add_matches(num_matches, matches, p_fic || p_wic); + + if (in_fuzzy) + { + ga_init2(&fuzzy_indices, sizeof(int), 10); + compl_fuzzy_scores = (int *)alloc(sizeof(int) * num_matches); + + for (i = 0; i < num_matches; i++) + { + ptr = matches[i]; + score = fuzzy_match_str(ptr, leader); + if (score > 0) + { + if (ga_grow(&fuzzy_indices, 1) == OK) + { + ((int *)fuzzy_indices.ga_data)[fuzzy_indices.ga_len] = i; + compl_fuzzy_scores[i] = score; + fuzzy_indices.ga_len++; + } + } + } + + // prevent qsort from deref NULL pointer + if (fuzzy_indices.ga_len > 0) + { + fuzzy_indices_data = (int *)fuzzy_indices.ga_data; + qsort(fuzzy_indices_data, fuzzy_indices.ga_len, sizeof(int), compare_scores); + + sorted_matches = (char_u **)alloc(sizeof(char_u *) * fuzzy_indices.ga_len); + for (i = 0; i < fuzzy_indices.ga_len; ++i) + sorted_matches[i] = vim_strsave(matches[fuzzy_indices_data[i]]); + + FreeWild(num_matches, matches); + matches = sorted_matches; + num_matches = fuzzy_indices.ga_len; + } + else if (leader_len > 0) + { + FreeWild(num_matches, matches); + num_matches = 0; + } + + vim_free(compl_fuzzy_scores); + ga_clear(&fuzzy_indices); + } + + if (num_matches > 0) + ins_compl_add_matches(num_matches, matches, p_fic || p_wic); } /* @@ -3683,8 +3845,10 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos) int save_p_scs; int save_p_ws; int looped_around = FALSE; - char_u *ptr; - int len; + char_u *ptr = NULL; + int len = 0; + int in_fuzzy = (get_cot_flags() & COT_FUZZY) != 0 && compl_length > 0; + char_u *leader = ins_compl_leader(); // If 'infercase' is set, don't use 'smartcase' here save_p_scs = p_scs; @@ -3698,7 +3862,7 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos) save_p_ws = p_ws; if (st->ins_buf != curbuf) p_ws = FALSE; - else if (*st->e_cpt == '.') + else if (*st->e_cpt == '.' && !in_fuzzy) p_ws = TRUE; looped_around = FALSE; for (;;) @@ -3709,9 +3873,13 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos) // ctrl_x_mode_line_or_eval() || word-wise search that // has added a word that was at the beginning of the line - if (ctrl_x_mode_line_or_eval() || (compl_cont_status & CONT_SOL)) + if ((ctrl_x_mode_whole_line() && !in_fuzzy) || ctrl_x_mode_eval() || (compl_cont_status & CONT_SOL)) found_new_match = search_for_exact_line(st->ins_buf, st->cur_match_pos, compl_direction, compl_pattern); + else if (in_fuzzy) + found_new_match = search_for_fuzzy_match(st->ins_buf, + st->cur_match_pos, leader, compl_direction, + start_pos, &len, &ptr, ctrl_x_mode_whole_line()); else found_new_match = searchit(NULL, st->ins_buf, st->cur_match_pos, NULL, compl_direction, compl_pattern, compl_patternlen, @@ -3760,8 +3928,9 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos) && start_pos->col == st->cur_match_pos->col) continue; - ptr = ins_compl_get_next_word_or_line(st->ins_buf, st->cur_match_pos, - &len, &cont_s_ipos); + if (!in_fuzzy) + ptr = ins_compl_get_next_word_or_line(st->ins_buf, st->cur_match_pos, + &len, &cont_s_ipos); if (ptr == NULL) continue; @@ -3860,6 +4029,7 @@ ins_compl_get_exp(pos_T *ini) int i; int found_new_match; int type = ctrl_x_mode; + int in_fuzzy = (get_cot_flags() & COT_FUZZY) != 0; if (!compl_started) { @@ -3886,7 +4056,7 @@ ins_compl_get_exp(pos_T *ini) compl_old_match = compl_curr_match; // remember the last current match st.cur_match_pos = (compl_dir_forward()) - ? &st.last_match_pos : &st.first_match_pos; + ? &st.last_match_pos : &st.first_match_pos; // For ^N/^P loop over all the flags/windows/buffers in 'complete'. for (;;) @@ -3900,7 +4070,7 @@ ins_compl_get_exp(pos_T *ini) if ((ctrl_x_mode_normal() || ctrl_x_mode_line_or_eval()) && (!compl_started || st.found_all)) { - int status = process_next_cpt_value(&st, &type, ini); + int status = process_next_cpt_value(&st, &type, ini, in_fuzzy); if (status == INS_COMPL_CPT_END) break; @@ -4100,10 +4270,10 @@ find_comp_when_fuzzy(void) int is_backward = compl_shows_dir_backward(); compl_T *comp = NULL; - if (compl_match_array == NULL || - (is_forward && compl_selected_item == compl_match_arraysize - 1) + if ((is_forward && compl_selected_item == compl_match_arraysize - 1) || (is_backward && compl_selected_item == 0)) - return compl_first_match; + return compl_first_match != compl_shown_match ? compl_first_match : + (compl_first_match->cp_prev ? compl_first_match->cp_prev : NULL); if (is_forward) target_idx = compl_selected_item + 1; @@ -4621,7 +4791,6 @@ get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col) } compl_patternlen = STRLEN(compl_pattern); - return OK; } @@ -5066,7 +5235,7 @@ ins_compl_start(void) if (p_ic) flags |= CP_ICASE; if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, - -1, NULL, NULL, NULL, 0, flags, FALSE) != OK) + -1, NULL, NULL, NULL, 0, flags, FALSE, -1, -1) != OK) { VIM_CLEAR(compl_pattern); compl_patternlen = 0; @@ -365,8 +365,7 @@ list_len(list_T *l) list_equal( list_T *l1, list_T *l2, - int ic, // ignore case for strings - int recursive) // TRUE when used recursively + int ic) // ignore case for strings { listitem_T *item1, *item2; @@ -386,7 +385,7 @@ list_equal( for (item1 = l1->lv_first, item2 = l2->lv_first; item1 != NULL && item2 != NULL; item1 = item1->li_next, item2 = item2->li_next) - if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive)) + if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) return FALSE; return item1 == NULL && item2 == NULL; } @@ -2727,7 +2726,7 @@ list_count(list_T *l, typval_T *needle, long idx, int ic) } for ( ; li != NULL; li = li->li_next) - if (tv_equal(&li->li_tv, needle, ic, FALSE)) + if (tv_equal(&li->li_tv, needle, ic)) ++n; return n; diff --git a/src/macros.h b/src/macros.h index 190778e..38983ac 100644 --- a/src/macros.h +++ b/src/macros.h @@ -194,7 +194,11 @@ #ifdef HAVE_LSTAT # define mch_lstat(n, p) lstat((n), (p)) #else -# define mch_lstat(n, p) mch_stat((n), (p)) +# ifdef MSWIN +# define mch_lstat(n, p) vim_lstat((n), (p)) +# else +# define mch_lstat(n, p) mch_stat((n), (p)) +# endif #endif #ifdef VMS @@ -85,6 +85,8 @@ map_free(mapblock_T **mpp) mp = *mpp; vim_free(mp->m_keys); + if (mp->m_alt != NULL) + mp->m_alt->m_alt = NULL; vim_free(mp->m_str); vim_free(mp->m_orig_str); *mpp = mp->m_next; @@ -213,7 +215,7 @@ theend: --map_locked; } - static int + static mapblock_T * map_add( mapblock_T **map_table, mapblock_T **abbr_table, @@ -236,7 +238,7 @@ map_add( mapblock_T *mp = ALLOC_CLEAR_ONE(mapblock_T); if (mp == NULL) - return FAIL; + return NULL; // If CTRL-C has been mapped, don't always use it for Interrupting. if (*keys == Ctrl_C) @@ -256,7 +258,7 @@ map_add( vim_free(mp->m_str); vim_free(mp->m_orig_str); vim_free(mp); - return FAIL; + return NULL; } mp->m_keylen = (int)STRLEN(mp->m_keys); mp->m_noremap = noremap; @@ -292,7 +294,7 @@ map_add( mp->m_next = map_table[n]; map_table[n] = mp; } - return OK; + return mp; } /* @@ -444,6 +446,7 @@ do_map( { char_u *keys; mapblock_T *mp, **mpp; + mapblock_T *mp_result[2] = {NULL, NULL}; char_u *rhs; char_u *p; int n; @@ -844,6 +847,8 @@ do_map( retval = 4; // no mem goto theend; } + if (mp->m_alt != NULL) + mp->m_alt = mp->m_alt->m_alt = NULL; vim_free(mp->m_str); mp->m_str = newstr; vim_free(mp->m_orig_str); @@ -858,6 +863,7 @@ do_map( mp->m_script_ctx = current_sctx; mp->m_script_ctx.sc_lnum += SOURCING_LNUM; #endif + mp_result[keyround - 1] = mp; did_it = TRUE; } } @@ -921,18 +927,25 @@ do_map( continue; // have added the new entry already // Get here when adding a new entry to the maphash[] list or abbrlist. - if (map_add(map_table, abbr_table, keys, rhs, orig_rhs, - noremap, nowait, silent, mode, abbrev, + mp_result[keyround - 1] = map_add(map_table, abbr_table, keys, + rhs, orig_rhs, noremap, nowait, silent, mode, abbrev, #ifdef FEAT_EVAL expr, /* sid */ 0, /* scriptversion */ 0, /* lnum */ 0, #endif - keyround1_simplified) == FAIL) + keyround1_simplified); + if (mp_result[keyround - 1] == NULL) { retval = 4; // no mem goto theend; } } + if (mp_result[0] != NULL && mp_result[1] != NULL) + { + mp_result[0]->m_alt = mp_result[1]; + mp_result[1]->m_alt = mp_result[0]; + } + theend: vim_free(keys_buf); vim_free(alt_keys_buf); @@ -2710,6 +2723,7 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED) int nowait; char_u *arg; int dict_only; + mapblock_T *mp_result[2] = {NULL, NULL}; // If first arg is a dict, then that's the only arg permitted. dict_only = argvars[0].v_type == VAR_DICT; @@ -2806,12 +2820,20 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED) do_map(MAPTYPE_UNMAP, arg, mode, is_abbr); vim_free(arg); - (void)map_add(map_table, abbr_table, lhsraw, rhs, orig_rhs, noremap, - nowait, silent, mode, is_abbr, expr, sid, scriptversion, lnum, 0); + mp_result[0] = map_add(map_table, abbr_table, lhsraw, rhs, orig_rhs, + noremap, nowait, silent, mode, is_abbr, expr, sid, + scriptversion, lnum, 0); if (lhsrawalt != NULL) - (void)map_add(map_table, abbr_table, lhsrawalt, rhs, orig_rhs, noremap, - nowait, silent, mode, is_abbr, expr, sid, scriptversion, - lnum, 1); + mp_result[1] = map_add(map_table, abbr_table, lhsrawalt, rhs, orig_rhs, + noremap, nowait, silent, mode, is_abbr, expr, sid, + scriptversion, lnum, 1); + + if (mp_result[0] != NULL && mp_result[1] != NULL) + { + mp_result[0]->m_alt = mp_result[1]; + mp_result[1]->m_alt = mp_result[0]; + } + vim_free(arg_buf); } #endif @@ -130,6 +130,38 @@ setmark_pos(int c, pos_T *pos, int fnum) } /* + * Delete every entry referring to file 'fnum' from both the jumplist and the + * tag stack. + */ + void +mark_forget_file(win_T *wp, int fnum) +{ + int i; + + for (i = wp->w_jumplistlen - 1; i >= 0; --i) + if (wp->w_jumplist[i].fmark.fnum == fnum) + { + vim_free(wp->w_jumplist[i].fname); + if (wp->w_jumplistidx > i) + --wp->w_jumplistidx; + --wp->w_jumplistlen; + mch_memmove(&wp->w_jumplist[i], &wp->w_jumplist[i + 1], + (wp->w_jumplistlen - i) * sizeof(wp->w_jumplist[i])); + } + + for (i = wp->w_tagstacklen - 1; i >= 0; --i) + if (wp->w_tagstack[i].fmark.fnum == fnum) + { + tagstack_clear_entry(&wp->w_tagstack[i]); + if (wp->w_tagstackidx > i) + --wp->w_tagstackidx; + --wp->w_tagstacklen; + mch_memmove(&wp->w_tagstack[i], &wp->w_tagstack[i + 1], + (wp->w_tagstacklen - i) * sizeof(wp->w_tagstack[i])); + } +} + +/* * Set the previous context mark to the current position and add it to the * jump list. */ diff --git a/src/mbyte.c b/src/mbyte.c index 07446ca..d8c47ac 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -102,7 +102,7 @@ # define WINBYTE BYTE #endif -#if (defined(MSWIN) || defined(WIN32UNIX)) && !defined(__MINGW32__) +#if defined(MSWIN) || defined(WIN32UNIX) # include <winnls.h> #endif @@ -3801,6 +3801,15 @@ utf_strnicmp( * two characters otherwise. */ int +mb_strnicmp2(char_u *s1, char_u *s2, size_t n1, size_t n2) +{ + if (n1 == n2 || !enc_utf8) + return mb_strnicmp(s1, s2, n1); + else + return utf_strnicmp(s1, s2, n1, n2); +} + + int mb_strnicmp(char_u *s1, char_u *s2, size_t nn) { int i, l; diff --git a/src/memline.c b/src/memline.c index 6c63fad..b93eb0a 100644 --- a/src/memline.c +++ b/src/memline.c @@ -1975,7 +1975,7 @@ recover_names( if (after_pathsep(dir_name, p) && len > 1 && p[-1] == p[-2]) { // Ends with '//', Use Full path for swap name - tail = make_percent_swname(dir_name, fname_res); + tail = make_percent_swname(dir_name, p, fname_res); } else #endif @@ -2143,7 +2143,7 @@ recover_names( * removed. */ char_u * -make_percent_swname(char_u *dir, char_u *name) +make_percent_swname(char_u *dir, char_u *dir_end, char_u *name) { char_u *d = NULL, *s, *f; @@ -2159,7 +2159,7 @@ make_percent_swname(char_u *dir, char_u *name) if (vim_ispathsep(*d)) *d = '%'; - dir[STRLEN(dir) - 1] = NUL; // remove one trailing slash + dir_end[-1] = NUL; // remove one trailing slash d = concat_fnames(dir, s, TRUE); vim_free(s); } @@ -2710,7 +2710,7 @@ ml_get_buf_len(buf_T *buf, linenr_T lnum) char_u *line; if (*(line = ml_get_buf(buf, lnum, FALSE)) == NUL) - return 0; + return 0; if (buf->b_ml.ml_line_textlen <= 0) buf->b_ml.ml_line_textlen = (int)STRLEN(line) + 1; @@ -4676,7 +4676,7 @@ makeswapname( if (after_pathsep(dir_name, s) && len > 1 && s[-1] == s[-2]) { // Ends with '//', Use Full path r = NULL; - if ((s = make_percent_swname(dir_name, fname_res)) != NULL) + if ((s = make_percent_swname(dir_name, s, fname_res)) != NULL) { r = modname(s, (char_u *)".swp", FALSE); vim_free(s); diff --git a/src/misc1.c b/src/misc1.c index 8348488..0898efb 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -678,17 +678,6 @@ get_mode(char_u *buf) buf[i++] = 't'; } #endif - else if (VIsual_active) - { - if (VIsual_select) - buf[i++] = VIsual_mode + 's' - 'v'; - else - { - buf[i++] = VIsual_mode; - if (restart_VIsual_select) - buf[i++] = 's'; - } - } else if (State == MODE_HITRETURN || State == MODE_ASKMORE || State == MODE_SETWSIZE || State == MODE_CONFIRM) @@ -731,6 +720,17 @@ get_mode(char_u *buf) if ((State & MODE_CMDLINE) && cmdline_overstrike()) buf[i++] = 'r'; } + else if (VIsual_active) + { + if (VIsual_select) + buf[i++] = VIsual_mode + 's' - 'v'; + else + { + buf[i++] = VIsual_mode; + if (restart_VIsual_select) + buf[i++] = 's'; + } + } else { buf[i++] = 'n'; diff --git a/src/misc2.c b/src/misc2.c index c07ed80..b5044fb 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -72,7 +72,7 @@ coladvance_force(colnr_T wcol) * Get the screen position of character col with a coladd in the cursor line. */ int -getviscol2(colnr_T col, colnr_T coladd UNUSED) +getviscol2(colnr_T col, colnr_T coladd) { colnr_T x; pos_T pos; @@ -3281,10 +3281,13 @@ pagescroll(int dir, long count, int half) MAX(1, p_window - 2) : get_scroll_overlap(dir)); nochange = scroll_with_sms(dir, count, &count); - // Place cursor at top or bottom of window. - validate_botline(); - curwin->w_cursor.lnum = (dir == FORWARD ? curwin->w_topline + if (!nochange) + { + // Place cursor at top or bottom of window. + validate_botline(); + curwin->w_cursor.lnum = (dir == FORWARD ? curwin->w_topline : curwin->w_botline - 1); + } } if (get_scrolloff_value() > 0) diff --git a/src/netbeans.c b/src/netbeans.c index 3b68869..781caa8 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -1689,8 +1689,10 @@ nb_do_cmd( if (streq((char *)args, "T") && buf->bufp != curbuf) { exarg_T exarg; + CLEAR_FIELD(exarg); exarg.cmd = (char_u *)"goto"; exarg.forceit = FALSE; + exarg.cmdidx = CMD_USER; dosetvisible = TRUE; goto_buffer(&exarg, DOBUF_FIRST, FORWARD, buf->bufp->b_fnum); do_update = 1; diff --git a/src/normal.c b/src/normal.c index b55d941..a929dd8 100644 --- a/src/normal.c +++ b/src/normal.c @@ -4462,7 +4462,7 @@ nv_brackets(cmdarg_T *cap) SAFE_islower(cap->nchar) ? ACTION_SHOW : ACTION_GOTO, cap->cmdchar == ']' ? curwin->w_cursor.lnum + 1 : (linenr_T)1, (linenr_T)MAXLNUM, - FALSE); + FALSE); vim_free(ptr); curwin->w_set_curswant = TRUE; } @@ -6598,8 +6598,12 @@ nv_wordcmd(cmdarg_T *cap) // "ce" will change until the end of the next word, but "cw" // will change only one character! This is done by setting // flag. - cap->oap->inclusive = TRUE; - word_end = TRUE; + // This can be configured using :set cpo-z + if (vim_strchr(p_cpo, CPO_WORD) != NULL) + { + cap->oap->inclusive = TRUE; + word_end = TRUE; + } flag = TRUE; } } @@ -240,8 +240,8 @@ shift_line( if (round) // round off indent { - i = count / sw_val; // number of 'shiftwidth' rounded down - j = count % sw_val; // extra spaces + i = trim_to_int(count) / sw_val; // number of 'shiftwidth' rounded down + j = trim_to_int(count) % sw_val; // extra spaces if (j && left) // first remove extra spaces --amount; if (left) @@ -676,6 +676,7 @@ op_delete(oparg_T *oap) && !oap->block_mode && oap->line_count > 1 && oap->motion_force == NUL + && (vim_strchr(p_cpo, CPO_WORD) != NULL) && oap->op_type == OP_DELETE) { ptr = ml_get(oap->end.lnum) + oap->end.col; @@ -2673,6 +2674,8 @@ do_addsub( int do_bin; int do_alpha; int do_unsigned; + int do_blank; + int blank_unsigned = FALSE; // blank: treat as unsigned? int firstdigit; int subtract; int negative = FALSE; @@ -2690,6 +2693,7 @@ do_addsub( do_bin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin" do_alpha = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha" do_unsigned = (vim_strchr(curbuf->b_p_nf, 'u') != NULL); // "Unsigned" + do_blank = (vim_strchr(curbuf->b_p_nf, 'k') != NULL); // "blanK" if (virtual_active()) { @@ -2813,8 +2817,13 @@ do_addsub( && (!has_mbyte || !(*mb_head_off)(ptr, ptr + col - 1)) && !do_unsigned) { - negative = TRUE; - was_positive = FALSE; + if (do_blank && col >= 2 && !VIM_ISWHITE(ptr[col - 2])) + blank_unsigned = TRUE; + else + { + negative = TRUE; + was_positive = FALSE; + } } } @@ -2875,10 +2884,16 @@ do_addsub( && !visual && !do_unsigned) { - // negative number - --col; - negative = TRUE; + if (do_blank && col >= 2 && !VIM_ISWHITE(ptr[col - 2])) + blank_unsigned = TRUE; + else + { + // negative number + --col; + negative = TRUE; + } } + // get the number value (unsigned) if (visual && VIsual_mode != 'V') maxlen = (curbuf->b_visual.vi_curswant == MAXCOL @@ -2938,7 +2953,7 @@ do_addsub( negative = FALSE; } - if (do_unsigned && negative) + if ((do_unsigned || blank_unsigned) && negative) { if (subtract) // sticking at zero. diff --git a/src/option.h b/src/option.h index 91d8d95..fba2672 100644 --- a/src/option.h +++ b/src/option.h @@ -212,6 +212,7 @@ typedef enum { #define CPO_REPLCNT 'X' // "R" with a count only deletes chars once #define CPO_YANK 'y' #define CPO_KEEPRO 'Z' // don't reset 'readonly' on ":w!" +#define CPO_WORD 'z' // do not special-case word motions cw and dw #define CPO_DOLLAR '$' #define CPO_FILTER '!' #define CPO_MATCH '%' @@ -231,9 +232,9 @@ typedef enum { #define CPO_SCOLON ';' // using "," and ";" will skip over char if // cursor would not move // default values for Vim, Vi and POSIX -#define CPO_VIM "aABceFs" -#define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;" -#define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\\.;" +#define CPO_VIM "aABceFsz" +#define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>;" +#define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>#{|&/\\.;" // characters for p_ww option: #define WW_ALL "bshl<>[]~" @@ -520,13 +521,13 @@ EXTERN unsigned cot_flags; // flags from 'completeopt' #define COT_ANY_MENU 0x003 // combination of menu flags #define COT_LONGEST 0x004 // FALSE: insert full match, // TRUE: insert longest prefix -#define COT_PREVIEW 0x008 -#define COT_POPUP 0x010 -#define COT_POPUPHIDDEN 0x020 -#define COT_ANY_PREVIEW 0x038 // combination of preview flags -#define COT_NOINSERT 0x040 // FALSE: select & insert, TRUE: noinsert -#define COT_NOSELECT 0x080 // FALSE: select & insert, TRUE: noselect -#define COT_FUZZY 0x100 // TRUE: fuzzy match enabled +#define COT_PREVIEW 0x008 +#define COT_POPUP 0x010 +#define COT_POPUPHIDDEN 0x020 +#define COT_ANY_PREVIEW 0x038 // combination of preview flags +#define COT_NOINSERT 0x040 // FALSE: select & insert, TRUE: noinsert +#define COT_NOSELECT 0x080 // FALSE: select & insert, TRUE: noselect +#define COT_FUZZY 0x100 // TRUE: fuzzy match enabled #ifdef BACKSLASH_IN_FILENAME EXTERN char_u *p_csl; // 'completeslash' #endif @@ -955,7 +956,6 @@ EXTERN int p_sol; // 'startofline' EXTERN char_u *p_su; // 'suffixes' EXTERN char_u *p_sws; // 'swapsync' EXTERN char_u *p_swb; // 'switchbuf' -EXTERN char_u *p_spk; // 'splitkeep' EXTERN unsigned swb_flags; // Keep in sync with p_swb_values in optionstr.c #define SWB_USEOPEN 0x001 @@ -964,9 +964,14 @@ EXTERN unsigned swb_flags; #define SWB_NEWTAB 0x008 #define SWB_VSPLIT 0x010 #define SWB_USELAST 0x020 +EXTERN char_u *p_spk; // 'splitkeep' #ifdef FEAT_SYN_HL EXTERN char_u *p_syn; // 'syntax' #endif +EXTERN char_u *p_tcl; // 'tabclose' +EXTERN unsigned tcl_flags; // flags from 'tabclose' +#define TCL_LEFT 0x001 +#define TCL_USELAST 0x002 EXTERN long p_ts; // 'tabstop' EXTERN int p_tbs; // 'tagbsearch' EXTERN char_u *p_tc; // 'tagcase' diff --git a/src/optiondefs.h b/src/optiondefs.h index 617f3ce..8982ac6 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -621,13 +621,12 @@ static struct vimoption options[] = {"columns", "co", P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR, (char_u *)&Columns, PV_NONE, NULL, NULL, {(char_u *)80L, (char_u *)0L} SCTX_INIT}, - {"comments", "com", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA - |P_NODUP|P_CURSWANT, + {"comments", "com", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, (char_u *)&p_com, PV_COM, did_set_comments, NULL, {(char_u *)"s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-", (char_u *)0L} SCTX_INIT}, - {"commentstring", "cms", P_STRING|P_ALLOCED|P_VI_DEF|P_CURSWANT, + {"commentstring", "cms", P_STRING|P_ALLOCED|P_VI_DEF, #ifdef FEAT_FOLDING (char_u *)&p_cms, PV_CMS, did_set_commentstring, NULL, {(char_u *)"/* %s */", (char_u *)0L} @@ -801,7 +800,7 @@ static struct vimoption options[] = {"debug", NULL, P_STRING|P_VI_DEF, (char_u *)&p_debug, PV_NONE, did_set_debug, expand_set_debug, {(char_u *)"", (char_u *)0L} SCTX_INIT}, - {"define", "def", P_STRING|P_ALLOCED|P_VI_DEF|P_CURSWANT, + {"define", "def", P_STRING|P_ALLOCED|P_VI_DEF, #ifdef FEAT_FIND_ID (char_u *)&p_def, PV_DEF, NULL, NULL, {(char_u *)"^\\s*#\\s*define", (char_u *)0L} @@ -2462,6 +2461,9 @@ static struct vimoption options[] = {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, + {"tabclose", "tcl", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, + (char_u *)&p_tcl, PV_NONE, did_set_tabclose, expand_set_tabclose, + {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"tabline", "tal", P_STRING|P_VI_DEF|P_RALL|P_MLE, #ifdef FEAT_STL_OPT (char_u *)&p_tal, PV_NONE, did_set_tabline, NULL, @@ -2852,13 +2854,13 @@ static struct vimoption options[] = {"window", "wi", P_NUM|P_VI_DEF, (char_u *)&p_window, PV_NONE, did_set_window, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, - {"winfixbuf", "wfb", P_BOOL|P_VI_DEF|P_RWIN, + {"winfixbuf", "wfb", P_BOOL|P_VI_DEF, (char_u *)VAR_WIN, PV_WFB, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"winfixheight", "wfh", P_BOOL|P_VI_DEF|P_RSTAT, (char_u *)VAR_WIN, PV_WFH, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, - {"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT, + {"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT, (char_u *)VAR_WIN, PV_WFW, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"winheight", "wh", P_NUM|P_VI_DEF, @@ -2868,7 +2870,7 @@ static struct vimoption options[] = {"winminheight", "wmh", P_NUM|P_VI_DEF, (char_u *)&p_wmh, PV_NONE, did_set_winminheight, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, - {"winminwidth", "wmw", P_NUM|P_VI_DEF, + {"winminwidth", "wmw", P_NUM|P_VI_DEF, (char_u *)&p_wmw, PV_NONE, did_set_winminwidth, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"winptydll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, diff --git a/src/optionstr.c b/src/optionstr.c index d722981..b6249a2 100644 --- a/src/optionstr.c +++ b/src/optionstr.c @@ -33,7 +33,7 @@ static char *(p_briopt_values[]) = {"shift:", "min:", "sbr", "list:", "column:", static char *(p_dip_values[]) = {"filler", "context:", "iblank", "icase", "iwhite", "iwhiteall", "iwhiteeol", "horizontal", "vertical", "closeoff", "hiddenoff", "foldcolumn:", "followwrap", "internal", "indent-heuristic", "algorithm:", NULL}; static char *(p_dip_algorithm_values[]) = {"myers", "minimal", "patience", "histogram", NULL}; #endif -static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", NULL}; +static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", "blank", NULL}; static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL}; #ifdef FEAT_CLIPBOARD // Note: Keep this in sync with did_set_clipboard() @@ -81,6 +81,8 @@ static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize", static char *(p_swb_values[]) = {"useopen", "usetab", "split", "newtab", "vsplit", "uselast", NULL}; static char *(p_spk_values[]) = {"cursor", "screen", "topline", NULL}; static char *(p_tc_values[]) = {"followic", "ignore", "match", "followscs", "smart", NULL}; +// Keep in sync with TCL_ flags in option.h +static char *(p_tcl_values[]) = {"left", "uselast", NULL}; #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN) static char *(p_toolbar_values[]) = {"text", "icons", "tooltips", "horiz", NULL}; #endif @@ -166,6 +168,7 @@ didset_string_options(void) (void)opt_strings_flags(p_tbis, p_tbis_values, &tbis_flags, FALSE); #endif (void)opt_strings_flags(p_swb, p_swb_values, &swb_flags, TRUE); + (void)opt_strings_flags(p_tcl, p_tcl_values, &tcl_flags, TRUE); } #if defined(FEAT_EVAL) || defined(PROTO) @@ -3669,6 +3672,26 @@ expand_set_switchbuf(optexpand_T *args, int *numMatches, char_u ***matches) matches); } +/* + * The 'tabclose' option is changed. + */ + char * +did_set_tabclose(optset_T *args UNUSED) +{ + return did_set_opt_flags(p_tcl, p_tcl_values, &tcl_flags, TRUE); +} + + int +expand_set_tabclose(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_tcl_values, + ARRAY_LENGTH(p_tcl_values) - 1, + numMatches, + matches); +} + #if defined(FEAT_STL_OPT) || defined(PROTO) /* * The 'tabline' option is changed. diff --git a/src/os_mswin.c b/src/os_mswin.c index 512fa40..95e3cbc 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -18,20 +18,12 @@ #include <sys/types.h> #include <signal.h> #include <limits.h> + +// cproto fails on missing include files #ifndef PROTO # include <process.h> -#endif - -#undef chdir -#ifdef __GNUC__ -# ifndef __MINGW32__ -# include <dirent.h> -# endif -#else # include <direct.h> -#endif -#ifndef PROTO # if !defined(FEAT_GUI_MSWIN) # include <shellapi.h> # endif @@ -41,37 +33,8 @@ # include <winspool.h> # include <commdlg.h> # endif - #endif // PROTO -#ifdef __MINGW32__ -# ifndef FROM_LEFT_1ST_BUTTON_PRESSED -# define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001 -# endif -# ifndef RIGHTMOST_BUTTON_PRESSED -# define RIGHTMOST_BUTTON_PRESSED 0x0002 -# endif -# ifndef FROM_LEFT_2ND_BUTTON_PRESSED -# define FROM_LEFT_2ND_BUTTON_PRESSED 0x0004 -# endif -# ifndef FROM_LEFT_3RD_BUTTON_PRESSED -# define FROM_LEFT_3RD_BUTTON_PRESSED 0x0008 -# endif -# ifndef FROM_LEFT_4TH_BUTTON_PRESSED -# define FROM_LEFT_4TH_BUTTON_PRESSED 0x0010 -# endif - -/* - * EventFlags - */ -# ifndef MOUSE_MOVED -# define MOUSE_MOVED 0x0001 -# endif -# ifndef DOUBLE_CLICK -# define DOUBLE_CLICK 0x0002 -# endif -#endif - /* * When generating prototypes for Win32 on Unix, these lines make the syntax * errors disappear. They do not need to be correct. @@ -144,37 +107,6 @@ static HWND s_hwnd = 0; // console window handle, set by GetConsoleHwnd() int WSInitialized = FALSE; // WinSock is initialized #endif -// Don't generate prototypes here, because some systems do have these -// functions. -#if defined(__GNUC__) && !defined(PROTO) -# ifndef __MINGW32__ -int _stricoll(char *a, char *b) -{ - // the ANSI-ish correct way is to use strxfrm(): - char a_buff[512], b_buff[512]; // file names, so this is enough on Win32 - strxfrm(a_buff, a, 512); - strxfrm(b_buff, b, 512); - return strcoll(a_buff, b_buff); -} - -char * _fullpath(char *buf, char *fname, int len) -{ - LPTSTR toss; - - return (char *)GetFullPathName(fname, len, buf, &toss); -} -# endif - -# if !defined(__MINGW32__) || (__GNUC__ < 4) -int _chdrive(int drive) -{ - char temp [3] = "-:"; - temp[0] = drive + 'A' - 1; - return !SetCurrentDirectory(temp); -} -# endif -#endif - #ifndef PROTO /* @@ -430,16 +362,6 @@ slash_adjust(char_u *p) } } -// Use 64-bit stat functions. -#undef stat -#undef _stat -#undef _wstat -#undef _fstat -#define stat _stat64 -#define _stat _stat64 -#define _wstat _wstat64 -#define _fstat _fstat64 - static int read_reparse_point(const WCHAR *name, char_u *buf, DWORD *buf_len) { @@ -461,58 +383,6 @@ read_reparse_point(const WCHAR *name, char_u *buf, DWORD *buf_len) return ok ? OK : FAIL; } - static int -wstat_symlink_aware(const WCHAR *name, stat_T *stp) -{ -#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__) - // Work around for VC12 or earlier (and MinGW). _wstat() can't handle - // symlinks properly. - // VC9 or earlier: _wstat() doesn't support a symlink at all. It retrieves - // status of a symlink itself. - // VC10: _wstat() supports a symlink to a normal file, but it doesn't - // support a symlink to a directory (always returns an error). - // VC11 and VC12: _wstat() doesn't return an error for a symlink to a - // directory, but it doesn't set S_IFDIR flag. - // MinGW: Same as VC9. - int n; - BOOL is_symlink = FALSE; - HANDLE hFind, h; - DWORD attr = 0; - WIN32_FIND_DATAW findDataW; - - hFind = FindFirstFileW(name, &findDataW); - if (hFind != INVALID_HANDLE_VALUE) - { - attr = findDataW.dwFileAttributes; - if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) - && (findDataW.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) - is_symlink = TRUE; - FindClose(hFind); - } - if (is_symlink) - { - h = CreateFileW(name, FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, - (attr & FILE_ATTRIBUTE_DIRECTORY) - ? FILE_FLAG_BACKUP_SEMANTICS : 0, - NULL); - if (h != INVALID_HANDLE_VALUE) - { - int fd; - - fd = _open_osfhandle((intptr_t)h, _O_RDONLY); - n = _fstat(fd, (struct _stat *)stp); - if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY)) - stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR; - _close(fd); - return n; - } - } -#endif - return _wstat(name, (struct _stat *)stp); -} - char_u * resolve_appexeclink(char_u *fname) { @@ -568,11 +438,76 @@ resolve_appexeclink(char_u *fname) return utf16_to_enc(p, NULL); } +// Use 64-bit stat functions. +#undef stat +#undef _stat +#undef _wstat +#undef _fstat +#define stat _stat64 +#define _stat _stat64 +#define _wstat _wstat64 +#define _fstat _fstat64 + +/* + * Implements lstat() and stat() that can handle symlinks properly. + */ + static int +mswin_stat_impl(const WCHAR *name, stat_T *stp, const int resolve) +{ + int n; + int fd; + BOOL is_symlink = FALSE; + HANDLE hFind, h; + DWORD attr = 0; + DWORD flag = 0; + WIN32_FIND_DATAW findDataW; + +#ifdef _UCRT + if (resolve) + // Universal CRT can handle symlinks properly. + return _wstat(name, stp); +#endif + + hFind = FindFirstFileW(name, &findDataW); + if (hFind != INVALID_HANDLE_VALUE) + { + attr = findDataW.dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) + && (findDataW.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) + is_symlink = TRUE; + FindClose(hFind); + } + + // Use the plain old stat() whenever it's possible. + if (!is_symlink) + return _wstat(name, stp); + + if (!resolve && is_symlink) + flag = FILE_FLAG_OPEN_REPARSE_POINT; + if (attr & FILE_ATTRIBUTE_DIRECTORY) + flag |= FILE_FLAG_BACKUP_SEMANTICS; + + h = CreateFileW(name, FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, flag, + NULL); + if (h == INVALID_HANDLE_VALUE) + return -1; + + fd = _open_osfhandle((intptr_t)h, _O_RDONLY); + n = _fstat(fd, (struct _stat *)stp); + if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY)) + stp->st_mode = (stp->st_mode & ~S_IFMT) | S_IFDIR; + _close(fd); + + return n; +} + /* * stat() can't handle a trailing '/' or '\', remove it first. + * When 'resolve' is true behave as lstat() wrt symlinks. */ - int -vim_stat(const char *name, stat_T *stp) + static int +stat_impl(const char *name, stat_T *stp, const int resolve) { // WinNT and later can use _MAX_PATH wide characters for a pathname, which // means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is @@ -607,11 +542,23 @@ vim_stat(const char *name, stat_T *stp) if (wp == NULL) return -1; - n = wstat_symlink_aware(wp, stp); + n = mswin_stat_impl(wp, stp, resolve); vim_free(wp); return n; } + int +vim_lstat(const char *name, stat_T *stp) +{ + return stat_impl(name, stp, FALSE); +} + + int +vim_stat(const char *name, stat_T *stp) +{ + return stat_impl(name, stp, TRUE); +} + #if (defined(FEAT_GUI_MSWIN) && !defined(VIMDLL)) || defined(PROTO) void mch_settmode(tmode_T tmode UNUSED) @@ -883,6 +830,40 @@ mch_icon_load(HANDLE *iconp) 0, mch_icon_load_cb, iconp); } +/* + * Fill the buffer 'buf' with 'len' random bytes. + * Returns FAIL if the OS PRNG is not available or something went wrong. + */ + int +mch_get_random(char_u *buf, int len) +{ + static int initialized = NOTDONE; + static HINSTANCE hInstLib; + static BOOL (WINAPI *pProcessPrng)(PUCHAR, ULONG); + + if (initialized == NOTDONE) + { + hInstLib = vimLoadLib("bcryptprimitives.dll"); + if (hInstLib != NULL) + pProcessPrng = (void *)GetProcAddress(hInstLib, "ProcessPrng"); + if (hInstLib == NULL || pProcessPrng == NULL) + { + FreeLibrary(hInstLib); + initialized = FAIL; + } + else + initialized = OK; + } + + if (initialized == FAIL) + return FAIL; + + // According to the documentation this call cannot fail. + pProcessPrng(buf, len); + + return OK; +} + int mch_libcall( char_u *libname, @@ -2940,7 +2921,7 @@ expand_font_enumproc( // Filter only on ANSI. Otherwise will see a lot of random fonts that we // usually don't want. if (lf->lfCharSet != ANSI_CHARSET) - return 1; + return 1; int (*add_match)(char_u *) = (int (*)(char_u *))lparam; @@ -2974,7 +2955,7 @@ gui_mch_expand_font(optexpand_T *args, void *param UNUSED, int (*add_match)(char // Always fill in with the current font size as first option for // convenience. We simply round to the closest integer for simplicity. - int font_height = (int)round( + int font_height = (int)round( pixels_to_points(-current_font_height, TRUE, (long_i)NULL)); vim_snprintf(buf, ARRAY_LENGTH(buf), "h%d", font_height); add_match((char_u *)buf); diff --git a/src/os_unix.c b/src/os_unix.c index d155142..e77a4b2 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -2699,6 +2699,9 @@ mch_FullName( if ((force || !mch_isFullName(fname)) && ((p = vim_strrchr(fname, '/')) == NULL || p != fname)) { + if (p == NULL && STRCMP(fname, "..") == 0) + // Handle ".." without path separators. + p = fname + 2; /* * If the file name has a path, change to that directory for a moment, * and then get the directory (and get back to where we were). @@ -2707,7 +2710,7 @@ mch_FullName( if (p != NULL) { if (STRCMP(p, "/..") == 0) - // for "/path/dir/.." include the "/.." + // For "/path/dir/.." include the "/..". p += 3; #ifdef HAVE_FCHDIR @@ -7498,9 +7501,9 @@ gpm_open(void) { Gpm_Close(); // We don't want to talk to xterm via gpm - // Gpm_Close fails to properly restore the WINCH and TSTP handlers, - // leading to Vim ignoring resize signals. We have to re-initialize - // these handlers again here. + // Gpm_Close fails to properly restore the WINCH and TSTP handlers, + // leading to Vim ignoring resize signals. We have to re-initialize + // these handlers again here. # ifdef SIGWINCH mch_signal(SIGWINCH, sig_winch); # endif @@ -7722,6 +7725,37 @@ sig_sysmouse SIGDEFARG(sigarg) } #endif // FEAT_SYSMOUSE +/* + * Fill the buffer 'buf' with 'len' random bytes. + * Returns FAIL if the OS PRNG is not available or something went wrong. + */ + int +mch_get_random(char_u *buf, int len) +{ + static int dev_urandom_state = NOTDONE; + + if (dev_urandom_state == FAIL) + return FAIL; + + int fd = open("/dev/urandom", O_RDONLY); + + // Attempt reading /dev/urandom. + if (fd == -1) + dev_urandom_state = FAIL; + else if (read(fd, buf, len) == len) + { + dev_urandom_state = OK; + close(fd); + } + else + { + dev_urandom_state = FAIL; + close(fd); + } + + return dev_urandom_state; +} + #if defined(FEAT_LIBCALL) || defined(PROTO) typedef char_u * (*STRPROCSTR)(char_u *); typedef char_u * (*INTPROCSTR)(int); diff --git a/src/os_w32dll.c b/src/os_w32dll.c index e7ba99b..651f96c 100644 --- a/src/os_w32dll.c +++ b/src/os_w32dll.c @@ -7,7 +7,7 @@ * See README.txt for an overview of the Vim source code. */ /* - * Windows GUI: main program (DLL) entry point: + * Windows GUI/Console: main program (DLL) entry point: * * Ron Aaron <ronaharon@yahoo.com> wrote this and the DLL support code. * Adapted by Ken Takata. diff --git a/src/os_w32exe.c b/src/os_w32exe.c index c4f0294..7aa4ead 100644 --- a/src/os_w32exe.c +++ b/src/os_w32exe.c @@ -8,10 +8,10 @@ * See README.txt for an overview of the Vim source code. */ /* - * Windows GUI: main program (EXE) entry point: + * Windows GUI/Console: main program (EXE) entry point: * - * Ron Aaron <ronaharon@yahoo.com> wrote this and the (now deleted) DLL support - * code. + * Ron Aaron <ronaharon@yahoo.com> wrote this and the DLL support code. + * Adapted by Ken Takata. */ #include "vim.h" @@ -20,32 +20,74 @@ __declspec(dllimport) #endif int VimMain(int argc, char **argv); -#ifndef VIMDLL + +#ifdef VIMDLL +# define SaveInst(hInst) // Do nothing +#else void SaveInst(HINSTANCE hInst); #endif -#ifndef PROTO -# ifdef FEAT_GUI +#ifdef FEAT_GUI int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInst UNUSED, LPWSTR lpszCmdLine UNUSED, int nCmdShow UNUSED) -# else +{ + SaveInst(hInstance); + return VimMain(0, NULL); +} +#else int wmain(int argc UNUSED, wchar_t **argv UNUSED) -# endif { -# ifndef VIMDLL -# ifdef FEAT_GUI - SaveInst(hInstance); -# else SaveInst(GetModuleHandleW(NULL)); -# endif -# endif + return VimMain(0, NULL); +} +#endif + +#ifdef USE_OWNSTARTUP +// Use our own entry point and don't use the default CRT startup code to +// reduce the size of (g)vim.exe. This works only when VIMDLL is defined. +// +// For MSVC, the /GS- compiler option is needed to avoid the undefined symbol +// error. (It disables the security check. However, it affects only this +// function and doesn't have any effect on Vim itself.) +// For MinGW, the -nostdlib compiler option and the --entry linker option are +// needed. +# ifdef FEAT_GUI + void WINAPI +wWinMainCRTStartup(void) +{ VimMain(0, NULL); +} +# else + void +wmainCRTStartup(void) +{ + VimMain(0, NULL); +} +# endif +#endif // USE_OWNSTARTUP + + +#if defined(VIMDLL) && defined(FEAT_MZSCHEME) - return 0; +# if defined(_MSC_VER) +static __declspec(thread) void *tls_space; +extern intptr_t _tls_index; +# elif defined(__MINGW32__) +static __thread void *tls_space; +extern intptr_t _tls_index; +# endif + +// Get TLS information that is needed for if_mzsch. + __declspec(dllexport) void +get_tls_info(void ***ptls_space, intptr_t *ptls_index) +{ + *ptls_space = &tls_space; + *ptls_index = _tls_index; + return; } #endif diff --git a/src/os_win32.c b/src/os_win32.c index 9947150..6384ac8 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -34,52 +34,14 @@ #ifndef PROTO # include <process.h> # include <winternl.h> -#endif - -#undef chdir -#ifdef __GNUC__ -# ifndef __MINGW32__ -# include <dirent.h> -# endif -#else # include <direct.h> -#endif -#ifndef PROTO # if !defined(FEAT_GUI_MSWIN) # include <shellapi.h> # endif -#endif - -#ifdef FEAT_JOB_CHANNEL -# include <tlhelp32.h> -#endif -#ifdef __MINGW32__ -# ifndef FROM_LEFT_1ST_BUTTON_PRESSED -# define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001 -# endif -# ifndef RIGHTMOST_BUTTON_PRESSED -# define RIGHTMOST_BUTTON_PRESSED 0x0002 -# endif -# ifndef FROM_LEFT_2ND_BUTTON_PRESSED -# define FROM_LEFT_2ND_BUTTON_PRESSED 0x0004 -# endif -# ifndef FROM_LEFT_3RD_BUTTON_PRESSED -# define FROM_LEFT_3RD_BUTTON_PRESSED 0x0008 -# endif -# ifndef FROM_LEFT_4TH_BUTTON_PRESSED -# define FROM_LEFT_4TH_BUTTON_PRESSED 0x0010 -# endif - -/* - * EventFlags - */ -# ifndef MOUSE_MOVED -# define MOUSE_MOVED 0x0001 -# endif -# ifndef DOUBLE_CLICK -# define DOUBLE_CLICK 0x0002 +# ifdef FEAT_JOB_CHANNEL +# include <tlhelp32.h> # endif #endif @@ -1302,6 +1264,13 @@ decode_key_event( } } } + else if (pker->wVirtualKeyCode == VK_INSERT + && (nModifs & SHIFT) != 0 + && (nModifs & ~SHIFT) == 0) + { + *pmodifiers = 0; + *pch2 = VirtKeyMap[i].chShift; + } else { *pch2 = VirtKeyMap[i].chAlone; @@ -2762,12 +2731,6 @@ theend: #endif // FEAT_GUI_MSWIN } -#ifndef PROTO -# ifndef __MINGW32__ -# include <shellapi.h> // required for FindExecutable() -# endif -#endif - /* * Return TRUE if "name" is an executable file, FALSE if not or it doesn't exist. * When returning TRUE and "path" is not NULL save the path and set "*path" to @@ -3598,6 +3561,10 @@ mch_exit_c(int r) vtp_exit(); stoptermcap(); + // Switch back to main screen buffer. + if (use_alternate_screen_buffer) + vtp_printf("\033[?1049l"); + if (g_fWindInitCalled) settmode(TMODE_COOK); @@ -5529,11 +5496,7 @@ mch_call_shell( * CTRL-C, Ctrl-Break or illegal instruction might otherwise kill us. */ mch_signal(SIGINT, SIG_IGN); -#if defined(__GNUC__) && !defined(__MINGW32__) - mch_signal(SIGKILL, SIG_IGN); -#else mch_signal(SIGBREAK, SIG_IGN); -#endif mch_signal(SIGILL, SIG_IGN); mch_signal(SIGFPE, SIG_IGN); mch_signal(SIGSEGV, SIG_IGN); @@ -5768,11 +5731,7 @@ mch_call_shell( resettitle(); mch_signal(SIGINT, SIG_DFL); -#if defined(__GNUC__) && !defined(__MINGW32__) - mch_signal(SIGKILL, SIG_DFL); -#else mch_signal(SIGBREAK, SIG_DFL); -#endif mch_signal(SIGILL, SIG_DFL); mch_signal(SIGFPE, SIG_DFL); mch_signal(SIGSEGV, SIG_DFL); @@ -6379,10 +6338,6 @@ termcap_mode_end(void) RestoreConsoleBuffer(cb, p_rs); restore_console_color_rgb(); - // Switch back to main screen buffer. - if (exiting && use_alternate_screen_buffer) - vtp_printf("\033[?1049l"); - if (!USE_WT && (p_rs || exiting)) { /* diff --git a/src/po/Make_cyg.mak b/src/po/Make_cyg.mak index 705858d..c04837e 100644 --- a/src/po/Make_cyg.mak +++ b/src/po/Make_cyg.mak @@ -16,7 +16,7 @@ endif include Make_all.mak PACKAGE = vim -VIM = ../vim +VIMPROG = ../vim # Uncomment one of the lines below or modify it to put the path to your # gettext binaries @@ -64,18 +64,18 @@ PO_INPUTLIST = \ vim.desktop.in first_time: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST) - $(VIM) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) $(XGETTEXT) --default-domain=$(LANGUAGE) \ --add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST) - $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) $(RM) *.js $(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST) - $(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) $(XGETTEXT) --default-domain=$(PACKAGE) \ --add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST) $(MV) $(PACKAGE).po $(PACKAGE).pot - $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) $(RM) *.js # Don't add a dependency here, we only want to update the .po files manually diff --git a/src/po/Make_ming.mak b/src/po/Make_ming.mak index 42dab84..21d2d20 100644 --- a/src/po/Make_ming.mak +++ b/src/po/Make_ming.mak @@ -23,9 +23,9 @@ include Make_all.mak PACKAGE = vim ifeq (sh.exe, $(SHELL)) -VIM = ..\vim +VIMPROG = ..\vim else -VIM = ../vim +VIMPROG = ../vim endif # Uncomment one of the lines below or modify it to put the path to your @@ -77,18 +77,18 @@ PO_INPUTLIST = \ vim.desktop.in first_time: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST) - $(VIM) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) $(XGETTEXT) --default-domain=$(LANGUAGE) \ --add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST) - $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) $(RM) *.js $(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST) - $(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) $(XGETTEXT) --default-domain=$(PACKAGE) \ --add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST) $(MV) $(PACKAGE).po $(PACKAGE).pot - $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) $(RM) *.js # Don't add a dependency here, we only want to update the .po files manually diff --git a/src/po/Make_mvc.mak b/src/po/Make_mvc.mak index a9a69fd..f567d88 100644 --- a/src/po/Make_mvc.mak +++ b/src/po/Make_mvc.mak @@ -40,7 +40,9 @@ VIMRUNTIME = ..\..\runtime PACKAGE = vim # Correct the following line for the where executeable file vim is # installed. Please do not put the path in quotes. -VIM = ..\vim.exe +!IFNDEF VIMPROG +VIMPROG = ..\vim.exe +!ENDIF # Correct the following line for the directory where gettext et al is # installed. Please do not put the path in quotes. @@ -102,7 +104,7 @@ originals : $(MOFILES) converted: $(MOCONVERTED) .po.ck: - "$(VIM)" -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" -S check.vim \ + "$(VIMPROG)" -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" -S check.vim \ -c "if error == 0 | q | else | num 2 | cq | endif" $< $(TOUCH_TARGET) @@ -122,9 +124,7 @@ nb.po: no.po ja.sjis.po: ja.po @$(MAKE) -nologo -f Make_mvc.mak sjiscorr -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t CP932 $? | .\sjiscorr.exe > $@ -!ELSEIF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f UTF-8 -t CP932 $? | .\sjiscorr.exe > $@ !ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ @@ -146,23 +146,19 @@ sjiscorr: sjiscorr.c # Convert ja.po to create ja.euc-jp.po. ja.euc-jp.po: ja.po -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t EUC-JP -o $@ $? -!ELSE -! IF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f UTF-8 -t EUC-JP $? > $@ -! ELSE +!ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ [System.IO.File]::ReadAllText(\"$?\", \ [System.Text.Encoding]::GetEncoding(65001)), \ [System.Text.Encoding]::GetEncoding(20932)) -! ENDIF +!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(20932)) -replace \ 'charset=utf-8', 'charset=EUC-JP'; \ [System.IO.File]::WriteAllText(\"$@\", $$out, \ [System.Text.Encoding]::GetEncoding(20932)) -!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(20932)) -replace \ '# Original translations', \ @@ -173,23 +169,19 @@ ja.euc-jp.po: ja.po # Convert cs.po to create cs.cp1250.po. cs.cp1250.po: cs.po -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t CP1250 -o $@ $? -!ELSE -! IF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f ISO-8859-2 -t CP1250 $? > $@ -! ELSE +!ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ [System.IO.File]::ReadAllText(\"$?\", \ [System.Text.Encoding]::GetEncoding(28592)), \ [System.Text.Encoding]::GetEncoding(1250)) -! ENDIF +!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(1250)) -replace \ 'charset=iso-8859-2', 'charset=CP1250'; \ [System.IO.File]::WriteAllText(\"$@\", $$out, \ [System.Text.Encoding]::GetEncoding(1250)) -!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(1250)) -replace \ '# Original translations', \ @@ -200,23 +192,19 @@ cs.cp1250.po: cs.po # Convert pl.po to create pl.cp1250.po. pl.cp1250.po: pl.po -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t CP1250 -o $@ $? -!ELSE -! IF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f ISO-8859-2 -t CP1250 $? > $@ -! ELSE +!ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ [System.IO.File]::ReadAllText(\"$?\", \ [System.Text.Encoding]::GetEncoding(28592)), \ [System.Text.Encoding]::GetEncoding(1250)) -! ENDIF +!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(1250)) -replace \ 'charset=iso-8859-2', 'charset=CP1250'; \ [System.IO.File]::WriteAllText(\"$@\", $$out, \ [System.Text.Encoding]::GetEncoding(1250)) -!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(1250)) -replace \ '# Original translations', \ @@ -227,20 +215,16 @@ pl.cp1250.po: pl.po # Convert pl.po to create pl.UTF-8.po. pl.UTF-8.po: pl.po -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t UTF-8 -o $@ $? -!ELSE -! IF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f ISO-8859-2 -t UTF-8 $? > $@ -! ELSE +!ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ [System.IO.File]::ReadAllText(\"$?\", \ [System.Text.Encoding]::GetEncoding(28592))) -! ENDIF +!ENDIF $(PS) $(PSFLAGS) (Get-Content -Raw -Encoding UTF8 $@ \ ^| % {$$_-replace 'charset=iso-8859-2', 'charset=UTF-8'}) \ ^| 1>nul New-Item -Force -Path . -ItemType file -Name $@ -!ENDIF $(PS) $(PSFLAGS) (Get-Content -Raw -Encoding UTF8 $@ \ ^| % {$$_-replace '# Original translations', \ '# Generated from $?, DO NOT EDIT'}) \ @@ -249,23 +233,19 @@ pl.UTF-8.po: pl.po # Convert sk.po to create sk.cp1250.po. sk.cp1250.po: sk.po -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t CP1250 -o $@ $? -!ELSE -! IF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f ISO-8859-2 -t CP1250 $? > $@ -! ELSE +!ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ [System.IO.File]::ReadAllText(\"$?\", \ [System.Text.Encoding]::GetEncoding(28592)), \ [System.Text.Encoding]::GetEncoding(1250)) -! ENDIF +!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(1250)) -replace \ 'charset=iso-8859-2', 'charset=CP1250'; \ [System.IO.File]::WriteAllText(\"$@\", $$out, \ [System.Text.Encoding]::GetEncoding(1250)) -!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(1250)) -replace \ '# Original translations', \ @@ -276,24 +256,20 @@ sk.cp1250.po: sk.po # Convert zh_CN.UTF-8.po to create zh_CN.po. zh_CN.po: zh_CN.UTF-8.po -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t GB2312 -o $@ $? -!ELSE -! IF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f UTF-8 -t GB2312 $? > $@ -! ELSE +!ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ [System.IO.File]::ReadAllText(\"$?\", \ [System.Text.Encoding]::GetEncoding(65001)), \ [System.Text.Encoding]::GetEncoding(936)) -! ENDIF +!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(936)) -replace \ 'charset=UTF-8', 'charset=GB2312'; \ [System.IO.File]::WriteAllText(\"$@\", $$out, \ [System.Text.Encoding]::GetEncoding(936)) -!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(936)) -replace \ '# Original translations', \ @@ -326,24 +302,19 @@ zh_CN.cp936.po: zh_CN.UTF-8.po # Convert zh_TW.UTF-8.po to create zh_TW.po. zh_TW.po: zh_TW.UTF-8.po -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t BIG5 -o $@ $? -!ELSE -! IF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f UTF-8 -t BIG5 $? > $@ -! ELSE +!ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ [System.IO.File]::ReadAllText(\"$?\", \ [System.Text.Encoding]::GetEncoding(65001)), \ [System.Text.Encoding]::GetEncoding(950)) - -! ENDIF +!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(950)) -replace \ 'charset=UTF-8', 'charset=BIG5'; \ [System.IO.File]::WriteAllText(\"$@\", $$out, \ [System.Text.Encoding]::GetEncoding(950)) -!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(950)) -replace \ '# Original translations', \ @@ -371,9 +342,7 @@ zh_TW.po: zh_TW.UTF-8.po #zh_TW.po: zh_TW.UTF-8.po # @$(MAKE) -nologo -f Make_mvc.mak big5corr # -$(RM) $@ -#!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") -# "$(GETTEXT_PATH)\msgconv.exe" -t BIG5 $? | .\big5corr.exe > $@ -#!ELSEIF DEFINED (ICONV) +#!IF DEFINED (ICONV) # $(ICONV) -f UTF-8 -t BIG5 $? | .\big5corr.exe > $@ #!ELSE # $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ @@ -396,24 +365,20 @@ zh_TW.po: zh_TW.UTF-8.po # Convert ko.UTF-8.po to create ko.po. ko.po: ko.UTF-8.po -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t EUC-KR -o $@ $? -!ELSE -! IF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f UTF-8 -t EUC-KR $? > $@ -! ELSE +!ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ [System.IO.File]::ReadAllText(\"$?\", \ [System.Text.Encoding]::GetEncoding(65001)), \ [System.Text.Encoding]::GetEncoding(51949)) -! ENDIF +!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(51949)) -replace \ 'charset=UTF-8', 'charset=EUC-KR'; \ [System.IO.File]::WriteAllText(\"$@\", $$out, \ [System.Text.Encoding]::GetEncoding(51949)) -!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(51949)) -replace \ '# Original translations', \ @@ -424,24 +389,19 @@ ko.po: ko.UTF-8.po # Convert ru.po to create ru.cp1251.po. ru.cp1251.po: ru.po -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t CP1251 -o $@ $? -!ELSE -! IF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f UTF-8 -t CP1251 $? > $@ -! ELSE +!ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ [System.IO.File]::ReadAllText(\"$?\", \ [System.Text.Encoding]::GetEncoding(65001)), \ [System.Text.Encoding]::GetEncoding(1251)) - -! ENDIF +!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(1251)) -replace \ 'charset=UTF-8', 'charset=CP1251'; \ [System.IO.File]::WriteAllText(\"$@\", $$out, \ [System.Text.Encoding]::GetEncoding(1251)) -!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(1251)) -replace \ '# Original translations', \ @@ -452,24 +412,19 @@ ru.cp1251.po: ru.po # Convert uk.po to create uk.cp1251.po. uk.cp1251.po: uk.po -$(RM) $@ -!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe") - "$(GETTEXT_PATH)\msgconv.exe" -t CP1251 -o $@ $? -!ELSE -! IF DEFINED (ICONV) +!IF DEFINED (ICONV) $(ICONV) -f UTF-8 -t CP1251 $? > $@ -! ELSE +!ELSE $(PS) $(PSFLAGS) [System.IO.File]::WriteAllText(\"$@\", \ [System.IO.File]::ReadAllText(\"$?\", \ [System.Text.Encoding]::GetEncoding(65001)), \ [System.Text.Encoding]::GetEncoding(1251)) - -! ENDIF +!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(1251)) -replace \ 'charset=UTF-8', 'charset=CP1251'; \ [System.IO.File]::WriteAllText(\"$@\", $$out, \ [System.Text.Encoding]::GetEncoding(1251)) -!ENDIF $(PS) $(PSFLAGS) $$out = [System.IO.File]::ReadAllText(\"$@\", \ [System.Text.Encoding]::GetEncoding(1251)) -replace \ '# Original translations', \ @@ -496,27 +451,28 @@ files: $(PO_INPUTLIST) $(LS) $(LSFLAGS) $(PO_INPUTLIST) > .\files first_time: files - "$(VIM)" -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).po \ + "$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).po \ $(PO_VIM_INPUTLIST) + @ copy /b .\files+.\vim_to_js .\allfiles set OLD_PO_FILE_INPUT=yes set OLD_PO_FILE_OUTPUT=yes $(XGETTEXT) --default-domain=$(LANGUAGE) --add-comments $(XGETTEXT_KEYWORDS) \ - --files-from=.\files $(PO_VIM_JSLIST) - "$(VIM)" -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).po \ + --files-from=.\allfiles + "$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).po \ $(PO_VIM_INPUTLIST) - $(RM) *.js + $(RM) *.js .\vim_to_js $(PACKAGE).pot: files - "$(VIM)" -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \ + "$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \ $(PO_VIM_INPUTLIST) + @ copy /b .\files+.\vim_to_js .\allfiles set OLD_PO_FILE_INPUT=yes set OLD_PO_FILE_OUTPUT=yes - $(XGETTEXT) --default-domain=$(PACKAGE) --add-comments $(XGETTEXT_KEYWORDS) \ - --files-from=.\files $(PO_VIM_JSLIST) - $(MV) $(PACKAGE).po $(PACKAGE).pot - "$(VIM)" -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \ + $(XGETTEXT) --default-domain=$(PACKAGE) --output=$(PACKAGE).pot \ + --add-comments $(XGETTEXT_KEYWORDS) --files-from=.\allfiles + "$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \ $(PO_VIM_INPUTLIST) - $(RM) *.js + $(RM) *.js .\vim_to_js # Only original translations with default encoding should be updated. # The files that are converted to a different encoding clearly state "DO NOT EDIT". @@ -541,16 +497,39 @@ install-all: all "$(VIMRUNTIME)\lang\%%l\LC_MESSAGES\$(PACKAGE).mo" cleanup-po: $(LANGUAGE).po - "$(VIM)" -u NONE -e -X -S cleanup.vim -c wq $(LANGUAGE).po + "$(VIMPROG)" -u NONE -e -X -S cleanup.vim -c wq $(LANGUAGE).po cleanup-po-all: $(POFILES) - !"$(VIM)" -u NONE -e -X -S cleanup.vim -c wq $** + !"$(VIMPROG)" -u NONE -e -X -S cleanup.vim -c wq $** + +####### +# For translations of plug-ins +####### + +# Preparing the POT file of the plug-in package +POT_PLUGPACKAGE_PATH = $(MAKEDIR) +$(PLUGPACKAGE).pot : $(PO_PLUG_INPUTLIST) + "$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim \ + $(PLUGPACKAGE).pot $** + $(XGETTEXT) --from-code=UTF-8 --default-domain=$(PLUGPACKAGE) \ + --package-name=$(PLUGPACKAGE) \ + --output-dir="$(POT_PLUGPACKAGE_PATH)" \ + --output=$(PLUGPACKAGE).pot --files-from=.\vim_to_js + "$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim \ + "$(POT_PLUGPACKAGE_PATH)\$(PLUGPACKAGE).pot" $** + $(RM) *.js .\vim_to_js + +# Converting the PO file of the plug-in package to the binary format of the MO file +MO_PLUGPACKAGE_PATH = $(MAKEDIR) +$(PLUGPACKAGE).mo : $(PO_PLUGPACKAGE) + $(MSGFMT) -o $(MO_PLUGPACKAGE_PATH)\$@ $? + clean: checkclean $(RM) *.mo $(RM) *.pot $(RM) *.orig - $(RM) files + $(RM) files allfiles $(RM) sjiscorr.obj sjiscorr.exe # $(RM) big5corr.obj big5corr.exe diff --git a/src/po/Makefile b/src/po/Makefile index cc4008f..95259a6 100644 --- a/src/po/Makefile +++ b/src/po/Makefile @@ -11,7 +11,7 @@ include Make_all.mak PACKAGE = vim SHELL = /bin/sh -VIM = ../vim +VIMPROG = ../vim # MacOS sed is locale aware, set $LANG to avoid problems. SED = LANG=C sed @@ -40,8 +40,8 @@ converted: $(MOCONVERTED) $(MSGFMTCMD) -o $@ $< .po.ck: - $(VIM) -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" -S check.vim \ - -c "if error == 0 | q | else | num 2 | cq | endif" $< + $(VIMPROG) -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" \ + -S check.vim -c "if error == 0 | q | else | num 2 | cq | endif" $< >/dev/null touch $@ check: $(CHECKFILES) @@ -107,55 +107,55 @@ nb.po: no.po ja.sjis.po: ja.po @$(MAKE) sjiscorr rm -f $@ - iconv -f UTF-8 -t CP932 $< | ./sjiscorr > $@ + iconv -f UTF-8 -t CP932 $? | ./sjiscorr > $@ sjiscorr: sjiscorr.c $(CC) -o sjiscorr sjiscorr.c ja.euc-jp.po: ja.po - iconv -f UTF-8 -t EUC-JP $< | \ + iconv -f UTF-8 -t EUC-JP $? | \ $(SED) -e 's/charset=[uU][tT][fF]-8/charset=EUC-JP/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ # Convert cs.po to create cs.cp1250.po. cs.cp1250.po: cs.po rm -f $@ - iconv -f ISO-8859-2 -t CP1250 $< | \ + iconv -f ISO-8859-2 -t CP1250 $? | \ $(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=CP1250/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ # Convert pl.po to create pl.cp1250.po. pl.cp1250.po: pl.po rm -f $@ - iconv -f ISO-8859-2 -t CP1250 $< | \ + iconv -f ISO-8859-2 -t CP1250 $? | \ $(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=CP1250/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ # Convert pl.po to create pl.UTF-8.po. pl.UTF-8.po: pl.po rm -f $@ - iconv -f ISO-8859-2 -t UTF-8 $< | \ + iconv -f ISO-8859-2 -t UTF-8 $? | \ $(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=UTF-8/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ # Convert sk.po to create sk.cp1250.po. sk.cp1250.po: sk.po rm -f $@ - iconv -f ISO-8859-2 -t CP1250 $< | \ + iconv -f ISO-8859-2 -t CP1250 $? | \ $(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=CP1250/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ # Convert zh_CN.UTF-8.po to create zh_CN.po. zh_CN.po: zh_CN.UTF-8.po rm -f $@ - iconv -f UTF-8 -t GB2312 $< | \ + iconv -f UTF-8 -t GB2312 $? | \ $(SED) -e 's/charset=[uU][tT][fF]-8/charset=GB2312/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ # Convert zh_CN.UTF-8.po to create zh_CN.cp936.po. @@ -163,17 +163,17 @@ zh_CN.po: zh_CN.UTF-8.po # This used to convert from zh_CN.po, but that results in a conversion error. zh_CN.cp936.po: zh_CN.UTF-8.po rm -f $@ - iconv -f UTF-8 -t CP936 $< | \ + iconv -f UTF-8 -t CP936 $? | \ $(SED) -e 's/charset=[uU][tT][fF]-8/charset=GBK/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ # Convert zh_TW.UTF-8.po to create zh_TW.po. zh_TW.po: zh_TW.UTF-8.po rm -f $@ - iconv -f UTF-8 -t BIG5 $< | \ + iconv -f UTF-8 -t BIG5 $? | \ $(SED) -e 's/charset=[uU][tT][fF]-8/charset=BIG5/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ @@ -197,7 +197,7 @@ zh_TW.po: zh_TW.UTF-8.po #zh_TW.po: zh_TW.UTF-8.po # @$(MAKE) big5corr # rm -f $@ -# iconv -f UTF-8 -t BIG5 $< | ./big5corr > $@ +# iconv -f UTF-8 -t BIG5 $? | ./big5corr > $@ # 06.11.23, added by Restorer @@ -209,25 +209,25 @@ zh_TW.po: zh_TW.UTF-8.po # Convert ko.UTF-8.po to create ko.po. ko.po: ko.UTF-8.po rm -f $@ - iconv -f UTF-8 -t EUC-KR $< | \ + iconv -f UTF-8 -t EUC-KR $? | \ $(SED) -e 's/charset=[uU][tT][fF]-8/charset=EUC-KR/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ # Convert ru.po to create ru.cp1251.po. ru.cp1251.po: ru.po rm -f $@ - iconv -f UTF-8 -t CP1251 $< | \ + iconv -f UTF-8 -t CP1251 $? | \ $(SED) -e 's/charset=[uU][tT][fF]-8/charset=CP1251/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ # Convert uk.po to create uk.cp1251.po. uk.cp1251.po: uk.po rm -f $@ - iconv -f UTF-8 -t CP1251 $< | \ + iconv -f UTF-8 -t CP1251 $? | \ $(SED) -e 's/charset=[uU][tT][fF]-8/charset=CP1251/' \ - -e 's/# Original translations/# Generated from $<, DO NOT EDIT/' \ + -e 's/# Original translations/# Generated from $?, DO NOT EDIT/' \ > $@ prefixcheck: @@ -241,6 +241,7 @@ prefixcheck: clean: checkclean rm -f core core.* *.old.po *.mo *.pot sjiscorr rm -f LINGUAS vim.desktop gvim.desktop tmp_*desktop + rm -f ./allfiles # rm -f big5corr distclean: clean @@ -261,21 +262,25 @@ PO_INPUTLIST = \ $(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST) # Convert the Vim scripts to (what looks like) Javascript. - $(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \ + $(PO_VIM_INPUTLIST) + @ echo ${PO_INPUTLIST} | tr ' ' '\n' > ./allfiles + @ cat ./vim_to_js >> ./allfiles # Create vim.pot. - $(XGETTEXT) --default-domain=$(PACKAGE) --add-comments \ - $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST) - mv -f $(PACKAGE).po $(PACKAGE).pot + $(XGETTEXT) --default-domain=$(PACKAGE) --output=$(PACKAGE).pot \ + --add-comments $(XGETTEXT_KEYWORDS) --files-from=./allfiles # Fix Vim scripts names, so that "gf" works. - $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \ + $(PO_VIM_INPUTLIST) # Delete the temporary files. - rm *.js + rm -f *.js ./vim_to_js vim.desktop: vim.desktop.in $(POFILES) echo $(LANGUAGES) | tr " " "\n" |$(SED) -e '/\./d' | sort > LINGUAS $(MSGFMT) --desktop -d . --template vim.desktop.in -o tmp_vim.desktop rm -f LINGUAS - if command -v desktop-file-validate; then desktop-file-validate tmp_vim.desktop; fi + if command -v desktop-file-validate; \ + then desktop-file-validate tmp_vim.desktop; fi mv tmp_vim.desktop vim.desktop # The dependency on vim.desktop is only to avoid the two targets are build at @@ -284,7 +289,8 @@ gvim.desktop: gvim.desktop.in $(POFILES) vim.desktop echo $(LANGUAGES) | tr " " "\n" |$(SED) -e '/\./d' | sort > LINGUAS $(MSGFMT) --desktop -d . --template gvim.desktop.in -o tmp_gvim.desktop rm -f LINGUAS - if command -v desktop-file-validate; then desktop-file-validate tmp_gvim.desktop; fi + if command -v desktop-file-validate; \ + then desktop-file-validate tmp_gvim.desktop; fi mv tmp_gvim.desktop gvim.desktop # Only original translations with default encoding should be updated. @@ -301,3 +307,28 @@ $(LANGUAGES): else \ echo "msgmerge for $@.po failed!"; mv $@.po.old $@.po; \ fi + + +####### +# For translations of plug-ins +####### + +# Preparing the POT file of the plug-in package +POT_PLUGPACKAGE_PATH = $(PWD) +$(PLUGPACKAGE).pot: $(PO_PLUG_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim \ + $(PLUGPACKAGE).pot $? + $(XGETTEXT) --from-code=UTF-8 --default-domain=$(PLUGPACKAGE) \ + --package-name=$(PLUGPACKAGE) \ + --output-dir=$(POT_PLUGPACKAGE_PATH) \ + --output=$(PLUGPACKAGE).pot --files-from=./vim_to_js + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim \ + $(POT_PLUGPACKAGE_PATH)/$(PLUGPACKAGE).pot $? + rm -f *.js ./vim_to_js + +# Converting the PO file of the plug-in package to the binary format of the MO +MO_PLUGPACKAGE_PATH = $(PWD) +$(PLUGPACKAGE).mo: $(PO_PLUGPACKAGE) + $(MSGFMTCMD) -o $(MO_PLUGPACKAGE_PATH)/$@ $? + +# vim: set noet sw=8 ts=8 sts=0 wm=0 tw=0 ft=make: diff --git a/src/po/README.txt b/src/po/README.txt index 50aff6a..801f5e5 100644 --- a/src/po/README.txt +++ b/src/po/README.txt @@ -160,3 +160,20 @@ convert ja.po to EUC-JP (supposed as your system encoding): "Content-Type: text/plain; charset=EUC-JP\n" There are examples in the Makefile for the conversions already supported. + + +TRANSLATION OF VIM THE EDITOR PLUG-INS + +Vim supports displaying plugin messages for various native languages. +Translation is available both for plugins that are supplied as part of the Vim +editor (e.g. "optwin.vim") and for third-party plugin packages. + +To translate the plugins supplied with the Vim editor, you must specify a +gettext() function call for the strings you want to translate. +The translation of these strings will be retrieved by gettext() from the MO +file "vim.mo". + +For third-party plugins, it is necessary to specify a one-time call to the +bindtextdomain() function in scripts containing translation strings and for +all message strings to add a {package} argument to the gettext() function. For +more information, see ":help package-translation". diff --git a/src/po/README_mvc.txt b/src/po/README_mvc.txt index ae9fa2b..e5fd85e 100644 --- a/src/po/README_mvc.txt +++ b/src/po/README_mvc.txt @@ -137,4 +137,22 @@ command: nmake.exe -f Make_mvc.mak clean + +TRANSLATION OF VIM THE EDITOR PLUG-INS + +Vim supports displaying plugin messages for various native languages. +Translation is available both for plugins that are supplied as part of the Vim +editor (e.g. "optwin.vim") and for third-party plugin packages. + +To translate the plugins supplied with the Vim editor, you must specify a +gettext() function call for the strings you want to translate. +The translation of these strings will be retrieved by gettext() from the MO +file "vim.mo". + +For third-party plugins, it is necessary to specify a one-time call to the +bindtextdomain() function in scripts containing translation strings and for +all message strings to add a {package} argument to the gettext() function. For +more information, see ":help package-translation". + + vim:tw=78: diff --git a/src/po/ca.po b/src/po/ca.po index caf02a9..052caad 100644 --- a/src/po/ca.po +++ b/src/po/ca.po @@ -1326,8 +1326,8 @@ msgstr " Compleció definida per l'usuari (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni-compleció (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Suggeriment d'ortografia (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Suggeriment d'ortografia (^S^N^P)" # i C-x C-p msgid " Keyword Local completion (^N^P)" diff --git a/src/po/cleanup.vim b/src/po/cleanup.vim index 1af188a..5e1b967 100644 --- a/src/po/cleanup.vim +++ b/src/po/cleanup.vim @@ -9,24 +9,24 @@ let s:was_diff = &diff setl nodiff " untranslated message preceded by c-format or comment -silent g/^#, c-format\n#/.d -silent g/^#\..*\n#/.d +silent g/^#, c-format\n#/.d _ +silent g/^#\..*\n#/.d _ " c-format comments have no effect, the check.vim scripts checks it. " But they might still be useful? -" silent g/^#, c-format$/d +" silent g/^#, c-format$/d _ -silent g/^#[:~] /d +silent g/^#[:~] /d _ silent g/^#, fuzzy\(, .*\)\=\nmsgid ""\@!/.+1,/^$/-1s/^/#\~ / silent g/^msgstr"/s//msgstr "/ silent g/^msgid"/s//msgid "/ silent g/^msgstr ""\(\n"\)\@!/?^msgid?,.s/^/#\~ / " Comments only useful for the translator -silent g/^#\. /d +silent g/^#\./d _ " clean up empty lines -silent g/^\n\n\n/.d +silent g/^\n\n\n/.d _ silent! %s/\n\+\%$// if s:was_diff diff --git a/src/po/cs.cp1250.po b/src/po/cs.cp1250.po index bed2595..24209c9 100644 --- a/src/po/cs.cp1250.po +++ b/src/po/cs.cp1250.po @@ -13,7 +13,7 @@ msgstr "" "Last-Translator: Jiøí Pavlovský <jpavlovsky@mbox.vol.cz>\n" "Language-Team: Czech <cs@li.org>\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=cp1250\n" +"Content-Type: text/plain; charset=CP1250\n" "Content-Transfer-Encoding: 8bit\n" msgid "E82: Cannot allocate any buffer, exiting..." diff --git a/src/po/da.po b/src/po/da.po index 80cc6fe..4cb212a 100644 --- a/src/po/da.po +++ b/src/po/da.po @@ -412,8 +412,8 @@ msgstr " Fuldførelse af brugerdefineret (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Fuldførelse af omni (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Staveforslag (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Staveforslag (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Fuldførelse af nøgleord local (^N^P)" diff --git a/src/po/de.po b/src/po/de.po index f0f00d7..99a62db 100644 --- a/src/po/de.po +++ b/src/po/de.po @@ -1376,8 +1376,8 @@ msgstr " Benutzerdefinierte Vervollständigung (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni-Vervollständigung (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Vorschlag der Rechtschreibprüfung (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Vorschlag der Rechtschreibprüfung (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokale Stichwort-Vervollständigung(^N^P)" diff --git a/src/po/eo.po b/src/po/eo.po index a9aaefa..3f86652 100644 --- a/src/po/eo.po +++ b/src/po/eo.po @@ -2616,8 +2616,8 @@ msgstr " Kompletigo difinita de uzanto (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Kompletigo Omni (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Sugesto de literumo (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Sugesto de literumo (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Kompletigo loka de Ålosilvorto (^N/^P)" diff --git a/src/po/es.po b/src/po/es.po index f4a02fa..8b072d8 100644 --- a/src/po/es.po +++ b/src/po/es.po @@ -1351,8 +1351,8 @@ msgstr " Completar definido por usuario (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Completar con método Omni (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Sugerencia de ortografÃa (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Sugerencia de ortografÃa (^S^N^P)" # Scroll has its own msgs, in its place there is the msg for local # * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL) -- Acevedo diff --git a/src/po/fi.po b/src/po/fi.po index d2fd336..9dc24d3 100644 --- a/src/po/fi.po +++ b/src/po/fi.po @@ -1325,8 +1325,8 @@ msgstr " Käyttäjän määrittelemä täydennys (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omnitäydennys (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Oikaisulukuehdotus (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Oikaisulukuehdotus (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Avainsanan paikallinen täydennys (^N^P)" diff --git a/src/po/fixfilenames.vim b/src/po/fixfilenames.vim index 04bc079..2344b3b 100644 --- a/src/po/fixfilenames.vim +++ b/src/po/fixfilenames.vim @@ -3,9 +3,11 @@ set shortmess+=A -for name in argv()[1:] - let jsname = fnamemodify(name, ":t:r") .. ".js" - exe "%s+" .. jsname .. "+" .. substitute(name, '\\', '/', 'g') .. "+" +let s:namenum = 0 +for s:name in argv()[1:] + let s:jsname = fnamemodify(s:name, ":t:r") .. s:namenum .. ".js" + exe "%s+" .. s:jsname .. "+" .. substitute(s:name, '\\', '/', 'g') .. "+ge" + let s:namenum +=1 endfor write diff --git a/src/po/fr.po b/src/po/fr.po index 27f11eb..3a55f8d 100644 --- a/src/po/fr.po +++ b/src/po/fr.po @@ -2738,8 +2738,8 @@ msgstr " Complètement défini par l'utilisateur (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Complètement selon le type de fichier (Omni) (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Suggestion d'orthographe (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Suggestion d'orthographe (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Complètement local de mot-clé (^N/^P)" diff --git a/src/po/ga.po b/src/po/ga.po index e81ef69..cd1a029 100644 --- a/src/po/ga.po +++ b/src/po/ga.po @@ -1401,8 +1401,8 @@ msgstr " Comhlánú saincheaptha (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Comhlánú Omni (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Moladh litrithe (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Moladh litrithe (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Comhlánú logánta lorgfhocal (^N^P)" diff --git a/src/po/hu.po b/src/po/hu.po index 0a11847..221cf33 100644 --- a/src/po/hu.po +++ b/src/po/hu.po @@ -264,8 +264,8 @@ msgstr " Felhasználó által definiált kiegészÃtés (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni kiegészÃtés (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " HelyesÃrási javaslat (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " HelyesÃrási javaslat (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Kulcsszó helyi kiegészÃtés (^N^P)" diff --git a/src/po/it.po b/src/po/it.po index fde1c23..78c2130 100644 --- a/src/po/it.po +++ b/src/po/it.po @@ -14,8 +14,8 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-28 09:50+0200\n" -"PO-Revision-Date: 2024-03-06 15:00+0100\n" +"POT-Creation-Date: 2024-08-11 10:10+0200\n" +"PO-Revision-Date: 2024-08-11 10:36+0100\n" "Last-Translator: Antonio Colombo <azc100@gmail.com>\n" "Language-Team: Italian\n" "Language: it\n" @@ -583,16 +583,16 @@ msgid "Greetings, Vim user!" msgstr "Salve, utente Vim!" msgid "Already only one tab page" -msgstr "C'è già un'unica pagina di linguette" +msgstr "C'è già un'unica pagina di schede" msgid "Edit File in new tab page" -msgstr "Apri il File in una nuova pagina di linguette" +msgstr "Apri il File in una nuova pagina di schede" msgid "Edit File in new window" msgstr "Apri il File in una nuova finestra" msgid "Tab page %d" -msgstr "Pagina di linguette %d" +msgstr "Pagina di schede %d" msgid "No swap file" msgstr "Non posso creare un file di swap" @@ -895,13 +895,13 @@ msgid "Vim: Received \"die\" request from session manager\n" msgstr "Vim: Ricevuta richiesta \"die\" dal Session Manager\n" msgid "Close tab" -msgstr "Chiudi linguetta" +msgstr "Chiudi scheda" msgid "New tab" -msgstr "Nuova linguetta" +msgstr "Nuova scheda" msgid "Open Tab..." -msgstr "Apri linguetta..." +msgstr "Apri scheda..." msgid "Vim: Main window unexpectedly destroyed\n" msgstr "Vim: Finestra principale distrutta inaspettatamente\n" @@ -946,7 +946,7 @@ msgid "&Undo" msgstr "&U Disfa" msgid "Open tab..." -msgstr "Apri linguetta..." +msgstr "Apri scheda..." msgid "Find string" msgstr "Trova stringa" @@ -1287,8 +1287,8 @@ msgstr " Completamento definito dall'utente (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Completamento globale (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Suggerimento ortografico (s^N^P)" +msgid " Spelling suggestion (^s^N^P)" +msgstr " Suggerimento ortografico (^s^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Completamento Parola Locale (^N^P)" @@ -1604,7 +1604,7 @@ msgid "--noplugin\t\tDon't load plugin scripts" msgstr "--noplugin\t\tNon caricare script plugin" msgid "-p[N]\t\tOpen N tab pages (default: one for each file)" -msgstr "-o[N]\t\tApri N pagine di linguette (predefinito: una per ogni file)" +msgstr "-o[N]\t\tApri N pagine di schede (predefinito: una per ogni file)" msgid "-o[N]\t\tOpen N windows (default: one for each file)" msgstr "-o[N]\t\tApri N finestre (predefinito: una per ogni file)" @@ -1667,7 +1667,7 @@ msgid "" "--remote-tab[-wait][-silent] <files> As --remote but use tab page per file" msgstr "" "--remote-tab[-wait][-silent] <file> Come --remote, ma apre una pagina di " -"linguette per file" +"schede per file" msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit" msgstr "--remote-send <tasti>\tInvia <tasti> a un server Vim ed esci" @@ -5538,9 +5538,6 @@ msgstr "E612: Troppi 'sign' definiti" msgid "E613: Unknown printer font: %s" msgstr "E613: Carattere di stampa sconosciuto: %s" -msgid "E614: Class required" -msgstr "E614: Classe richiesta" - msgid "E616: Object required for argument %d" msgstr "E616: Object richiesto per argomento %d" @@ -6045,7 +6042,7 @@ msgid "E783: Duplicate char in MAP entry" msgstr "E783: Carattere duplicato nell'elemento MAP" msgid "E784: Cannot close last tab page" -msgstr "E784: Non posso chiudere l'ultima pagina di linguette" +msgstr "E784: Non posso chiudere l'ultima pagina di schede" msgid "E785: complete() can only be used in Insert mode" msgstr "E785: complete() può essere usata solo in modalità inserimento" @@ -6747,7 +6744,7 @@ msgid "E996: Cannot lock a register" msgstr "E996: Non posso bloccare un registro" msgid "E997: Tabpage not found: %d" -msgstr "E997: Pagina-di-linguette non trovata: %d" +msgstr "E997: Pagina-di-schede non trovata: %d" msgid "E998: Reduce of an empty %s with no initial value" msgstr "" @@ -7715,7 +7712,7 @@ msgstr "E1307: Argomento %d: Tenta di modificare la costante %s" msgid "E1308: Cannot resize a window in another tab page" msgstr "" -"E1308: Non posso ridimensionare una finestra in un'altra pagine di linguette" +"E1308: Non posso ridimensionare una finestra in un'altra pagine di schede" msgid "E1309: Cannot change mappings while listing" msgstr "E1309: Non posso modificare mappature mentre le sto elencando" @@ -7749,21 +7746,12 @@ msgstr "E1317: Dichiarazione di variabile Object non valida: %s" msgid "E1318: Not a valid command in a class: %s" msgstr "E1318: Comando non valido in una Classe: %s" -msgid "E1319: Using a Class as a Number" -msgstr "E1319: Uso di una Classe come un Numero" - msgid "E1320: Using an Object as a Number" msgstr "E1320: Uso di un Object come un Numero" -msgid "E1321: Using a Class as a Float" -msgstr "E1321: Uso di una Classe come un Numero-a-virgola-mobile" - msgid "E1322: Using an Object as a Float" msgstr "E1322: Uso di un Object come un Numero-a-virgola-mobile" -msgid "E1323: Using a Class as a String" -msgstr "E1323: Uso di una Classe come una Stringa" - msgid "E1324: Using an Object as a String" msgstr "E1324: Uso di un Object come una Stringa" @@ -7794,8 +7782,8 @@ msgstr "" msgid "E1332: public variable name cannot start with underscore: %s" msgstr "" -"E1332: Il nome di un elemento public non può iniziare con il trattino " -"basso: %s" +"E1332: Il nome di un elemento public non può iniziare con il trattino basso: " +"%s" msgid "E1333: Cannot access protected variable \"%s\" in class \"%s\"" msgstr "" @@ -8004,9 +7992,6 @@ msgstr "E1393: Il Tipo può essere definito solo negli script Vim9" msgid "E1394: Type name must start with an uppercase letter: %s" msgstr "E1394: Il nome di un Tipo deve iniziare con una lettera maiuscola: %s" -msgid "E1395: Type alias \"%s\" cannot be modified" -msgstr "E1395: Il Tipo alias \"%s\" non può essere modificato" - msgid "E1396: Type alias \"%s\" already exists" msgstr "E1396: Il Tipo alias \"%s\" esiste già " @@ -8019,15 +8004,6 @@ msgstr "E1398: Manca il tipo del Tipo alias" msgid "E1399: Type can only be used in a script" msgstr "E1399: \"Tipo\" si può usare solo in uno script" -msgid "E1400: Using type alias \"%s\" as a Number" -msgstr "E1400: Uso del Tipo alias \"%s\" come un Numero" - -msgid "E1401: Using type alias \"%s\" as a Float" -msgstr "E1401: Uso del Tipo alias \"%s\" come un Numero-a-virgola-mobile" - -msgid "E1402: Using type alias \"%s\" as a String" -msgstr "E1402: Uso del Tipo alias \"%s\" come una Stringa" - msgid "E1403: Type alias \"%s\" cannot be used as a value" msgstr "E1403: Impossibile usare il Tipo alias \"%s\" come valore" @@ -8037,9 +8013,6 @@ msgstr "E1404: Impossibile usare \"Abstract\" in un'Interfaccia" msgid "E1405: Class \"%s\" cannot be used as a value" msgstr "E1405: Impossibile usare Classe \"%s\" come valore" -msgid "E1406: Cannot use a Class as a variable or value" -msgstr "E1406: Impossibile usare una Classe come variabile o valore" - msgid "E1407: Cannot use a Typealias as a variable or value" msgstr "E1407: Impossibile usare un Tipo alias come variabile o valore" @@ -8158,8 +8131,8 @@ msgid "E1512: Wrong character width for field \"%s\"" msgstr "E1512: Larghezza carattere errata per campo \"%s\"" msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled" -msgstr "E1513: Non riesco a passare a un altro buffer. Opzione " -"'winfixbuf' attiva" +msgstr "" +"E1513: Non riesco a passare a un altro buffer. Opzione 'winfixbuf' attiva" #. type of cmdline window or 0 #. result of cmdline window or 0 @@ -8362,10 +8335,10 @@ msgid "unable to unset option %s which does not have global value" msgstr "impossibile rimuovere l'opzione %s che non ha un valore globale" msgid "attempt to refer to deleted tab page" -msgstr "tentativo di riferimento a pagina di linguette cancellata" +msgstr "tentativo di riferimento a pagina di schede cancellata" msgid "no such tab page" -msgstr "pagina di linguette inesistente" +msgstr "pagina di schede inesistente" msgid "attempt to refer to deleted window" msgstr "tentativo di riferimento a una finestra cancellata" @@ -8399,7 +8372,7 @@ msgstr "atteso Object vim.Window, ottenuto %s" msgid "failed to find window in the current tab page" msgstr "" -"non è stato possibile trovare la finestra nella pagina di linguette corrente" +"non è stato possibile trovare la finestra nella pagina di schede corrente" msgid "did not switch to the specified window" msgstr "passaggio alla finestra specificata non effettuato" @@ -8408,7 +8381,7 @@ msgid "expected vim.TabPage object, but got %s" msgstr "atteso Object vim.TabPage, ottenuto %s" msgid "did not switch to the specified tab page" -msgstr "passaggio alla pagina di linguette specificata non effettuato" +msgstr "passaggio alla pagina di schede specificata non effettuato" msgid "failed to run the code" msgstr "esecuzione del codice non riuscita" @@ -8988,24 +8961,28 @@ msgid "name of the winpty dynamic library" msgstr "nome della libreria dinamica winpty" msgid "multiple tab pages" -msgstr "più di una pagina di linguette" +msgstr "più di una pagina di schede" msgid "0, 1 or 2; when to use a tab pages line" -msgstr "0, 1 o 2; utilizzo della riga che descrive pagine di linguette" +msgstr "0, 1 o 2; utilizzo della riga che descrive pagine di schede" + +msgid "behaviour when closing tab pages: left, uselast or empty" +msgstr "" +"comportamento alla chiusura di pagine di schede: left, uselast o empty" msgid "maximum number of tab pages to open for -p and \"tab all\"" msgstr "" -"massimo numero di pagine di linguette da aprire\n" +"massimo numero di pagine di schede da aprire\n" "per -p e \"tab all\"" msgid "custom tab pages line" -msgstr "personalizzazione riga che descrive le pagine di linguette" +msgstr "personalizzazione riga che descrive le pagine di schede" msgid "custom tab page label for the GUI" -msgstr "personalizzazione etichetta per le pagine di linguette nella GUI" +msgstr "personalizzazione etichetta per le pagine di schede nella GUI" msgid "custom tab page tooltip for the GUI" -msgstr "personalizzazione suggerimento per le pagine di linguette nella GUI" +msgstr "personalizzazione suggerimento per le pagine di schede nella GUI" msgid "terminal" msgstr "terminale" diff --git a/src/po/ja.euc-jp.po b/src/po/ja.euc-jp.po index 362be9e..ced4cd9 100644 --- a/src/po/ja.euc-jp.po +++ b/src/po/ja.euc-jp.po @@ -3,7 +3,7 @@ # Do ":help uganda" in Vim to read copying and usage conditions. # Do ":help credits" in Vim to see a list of people who contributed. # -# Copyright (C) 2001-2023 MURAOKA Taro <koron.kaoriya@gmail.com>, +# Copyright (C) 2001-2024 MURAOKA Taro <koron.kaoriya@gmail.com>, # vim-jp <http://vim-jp.org/> # # THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE. @@ -12,10 +12,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Vim 9.0\n" +"Project-Id-Version: Vim 9.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-18 16:41+0900\n" -"PO-Revision-Date: 2023-12-19 12:45+0900\n" +"POT-Creation-Date: 2024-07-23 10:59+0900\n" +"PO-Revision-Date: 2024-08-15 12:54+0900\n" "Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n" "Language-Team: Japanese <https://github.com/vim-jp/lang-ja>\n" "Language: ja\n" @@ -175,6 +175,9 @@ msgstr " (file %d of %d)" msgid " (file (%d) of %d)" msgstr " (file (%d) of %d)" +msgid "[Command Line]" +msgstr "[¥³¥Þ¥ó¥É¥é¥¤¥ó]" + msgid "[Prompt]" msgstr "[¥×¥í¥ó¥×¥È]" @@ -439,10 +442,6 @@ msgstr "ÊÒ²¾Ì¾" msgid "Bopomofo" msgstr "Ãí²»»úÊì" -msgid "Not enough memory to set references, garbage collection aborted!" -msgstr "" -"¥¬¡¼¥Ù¥Ã¥¸¥³¥ì¥¯¥·¥ç¥ó¤òÃæ»ß¤·¤Þ¤·¤¿! »²¾È¤òºîÀ®¤¹¤ë¤Î¤Ë¥á¥â¥ê¤¬ÉÔ¤·¤Þ¤·¤¿" - msgid "" "\n" "\tLast set from " @@ -688,9 +687,6 @@ msgstr "¥¨¥é¡¼" msgid "Interrupt" msgstr "³ä¹þ¤ß" -msgid "[Command Line]" -msgstr "[¥³¥Þ¥ó¥É¥é¥¤¥ó]" - msgid "is a directory" msgstr "¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹" @@ -854,6 +850,10 @@ msgid "+-%s%3ld line: " msgid_plural "+-%s%3ld lines: " msgstr[0] "+-%s%3ld ¹Ô: " +msgid "Not enough memory to set references, garbage collection aborted!" +msgstr "" +"¥¬¡¼¥Ù¥Ã¥¸¥³¥ì¥¯¥·¥ç¥ó¤òÃæ»ß¤·¤Þ¤·¤¿! »²¾È¤òºîÀ®¤¹¤ë¤Î¤Ë¥á¥â¥ê¤¬ÉÔ¤·¤Þ¤·¤¿" + msgid "No match at cursor, finding next" msgstr "¥«¡¼¥½¥ë¤Î°ÌÃ֤˥ޥåÁ¤Ï¤¢¤ê¤Þ¤»¤ó¡¢¼¡¤ò¸¡º÷¤·¤Æ¤¤¤Þ¤¹" @@ -1337,8 +1337,8 @@ msgstr " ¥æ¡¼¥¶¡¼ÄêµÁÊä´° (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " ¥ª¥à¥ËÊä´° (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Ä֤꽤Àµ¸õÊä (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Ä֤꽤Àµ¸õÊä (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ¶É½ê¥¡¼¥ï¡¼¥ÉÊä´° (^N^P)" @@ -1416,6 +1416,9 @@ msgstr "mapnew() ¤Î°ú¿ô" msgid "filter() argument" msgstr "filter() ¤Î°ú¿ô" +msgid "foreach() argument" +msgstr "foreach() ¤Î°ú¿ô" + msgid "extendnew() argument" msgstr "extendnew() ¤Î°ú¿ô" @@ -2454,6 +2457,9 @@ msgstr "%s ¤Ø (%s ¾å¤Î)" msgid "Printing '%s'" msgstr "°õºþ¤·¤Æ¤¤¤Þ¤¹: '%s'" +#~ msgid "DefaultFontNameForWindows" +#~ msgstr "" + #, c-format msgid "Opening the X display took %ld msec" msgstr "X¥µ¡¼¥Ð¡¼¤Ø¤ÎÀܳ¤Ë %ld ¥ß¥êÉ䫤«¤ê¤Þ¤·¤¿" @@ -3394,8 +3400,8 @@ msgid "%s returning %s" msgstr "%s ¤¬ %s ¤òÊÖ¤·¤Þ¤·¤¿" #, c-format -msgid "Function %s does not need compiling" -msgstr "´Ø¿ô %s ¤Ï¥³¥ó¥Ñ¥¤¥ë¤ÎɬÍפ¬¤¢¤ê¤Þ¤»¤ó" +msgid "Function %s%s%s does not need compiling" +msgstr "´Ø¿ô %s%s%s ¤Ï¥³¥ó¥Ñ¥¤¥ë¤ÎɬÍפ¬¤¢¤ê¤Þ¤»¤ó" #, c-format msgid "%s (%s, compiled %s)" @@ -3554,6 +3560,9 @@ msgstr " Âè2¥æ¡¼¥¶¡¼ vimrc: \"" msgid " 3rd user vimrc file: \"" msgstr " Âè3¥æ¡¼¥¶¡¼ vimrc: \"" +msgid " 4th user vimrc file: \"" +msgstr " Âè4¥æ¡¼¥¶¡¼ vimrc: \"" + msgid " user exrc file: \"" msgstr " ¥æ¡¼¥¶¡¼ exrc: \"" @@ -4158,6 +4167,10 @@ msgid "E105: Using :loadkeymap not in a sourced file" msgstr "E105: :source ¤Ç¼è¹þ¤à¥Õ¥¡¥¤¥ë°Ê³°¤Ç¤Ï :loadkeymap ¤ò»È¤¨¤Þ¤»¤ó" #, c-format +msgid "E106: Unsupported diff output format: %s" +msgstr "E106: ¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤diff½ÐÎÏ¥Õ¥©¡¼¥Þ¥Ã¥È¤Ç¤¹: %s" + +#, c-format msgid "E107: Missing parentheses: %s" msgstr "E107: ¥«¥Ã¥³ '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s" @@ -4486,8 +4499,8 @@ msgstr "E196: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¹ç»ú¤Ï¤¢¤ê¤Þ¤»¤ó" msgid "E197: Cannot set language to \"%s\"" msgstr "E197: ¸À¸ì¤ò \"%s\" ¤ËÀßÄê¤Ç¤¤Þ¤»¤ó" -msgid "E199: Active window or buffer deleted" -msgstr "E199: ¥¢¥¯¥Æ¥£¥Ö¤Ê¥¦¥£¥ó¥É¥¦¤«¥Ð¥Ã¥Õ¥¡¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿" +msgid "E199: Active window or buffer changed or deleted" +msgstr "E199: ¥¢¥¯¥Æ¥£¥Ö¤Ê¥¦¥£¥ó¥É¥¦¤«¥Ð¥Ã¥Õ¥¡¤¬Êѹ¹¤Þ¤¿¤Ïºï½ü¤µ¤ì¤Þ¤·¤¿" msgid "E200: *ReadPre autocommands made the file unreadable" msgstr "E200: *ReadPre ¼«Æ°¥³¥Þ¥ó¥É ¤¬¥Õ¥¡¥¤¥ë¤òÆɹþÉԲĤˤ·¤Þ¤·¤¿" @@ -5857,9 +5870,6 @@ msgstr "E612: sign¤ÎÄêµÁ¤¬Â¿²á¤®¤Þ¤¹" msgid "E613: Unknown printer font: %s" msgstr "E613: ̤ÃΤΥץê¥ó¥¿¥ª¥×¥·¥ç¥ó¤Ç¤¹: %s" -msgid "E614: Class required" -msgstr "E614: ¥¯¥é¥¹¤¬É¬ÍפǤ¹" - #, c-format msgid "E616: Object required for argument %d" msgstr "E616: °ú¿ô %d ¤Ë¤Ï¥ª¥Ö¥¸¥§¥¯¥È¤¬É¬ÍפǤ¹" @@ -6696,7 +6706,7 @@ msgid "E862: Cannot use g: here" msgstr "E862: ¤³¤³¤Ç¤Ï g: ¤Ï»È¤¨¤Þ¤»¤ó" msgid "E863: Not allowed for a terminal in a popup window" -msgstr "E863: üËö¤Ï¥Ý¥Ã¥×¥¢¥Ã¥×¥¦¥£¥ó¥É¥¦¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó" +msgstr "E863: ¥Ý¥Ã¥×¥¢¥Ã¥×¥¦¥£¥ó¥É¥¦Æâ¤ÎüËö¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó" #, no-c-format msgid "" @@ -6753,6 +6763,10 @@ msgstr "" msgid "E876: (NFA regexp) Not enough space to store the whole NFA" msgstr "E876: (NFA Àµµ¬É½¸½) NFAÁ´ÂΤòÊݸ¤¹¤ë¤Ë¤Ï¶õ¤¥¹¥Ú¡¼¥¹¤¬Â¤ê¤Þ¤»¤ó" +#, c-format +msgid "E877: (NFA regexp) Invalid character class: %d" +msgstr "E877: (NFA Àµµ¬É½¸½) ̵¸ú¤Êʸ»ú¥¯¥é¥¹¤Ç¤¹: %d" + msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!" msgstr "" "E878: (NFA Àµµ¬É½¸½) ¸½ºß²£ÃÇÃæ¤Î¥Ö¥é¥ó¥Á¤Ë½½Ê¬¤Ê¥á¥â¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó!" @@ -8319,21 +8333,12 @@ msgstr "E1317: ÉÔÀµ¤Ê¥ª¥Ö¥¸¥§¥¯¥ÈÊÑ¿ô¤ÎÀë¸À¤Ç¤¹: %s" msgid "E1318: Not a valid command in a class: %s" msgstr "E1318: ¥¯¥é¥¹Æâ¤Ç¤Ï»È¤¨¤Ê¤¤¥³¥Þ¥ó¥É¤Ç¤¹: %s" -msgid "E1319: Using a Class as a Number" -msgstr "E1319: ¥¯¥é¥¹¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" - msgid "E1320: Using an Object as a Number" msgstr "E1320: ¥ª¥Ö¥¸¥§¥¯¥È¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" -msgid "E1321: Using a Class as a Float" -msgstr "E1321: ¥¯¥é¥¹¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" - msgid "E1322: Using an Object as a Float" msgstr "E1322: ¥ª¥Ö¥¸¥§¥¯¥È¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" -msgid "E1323: Using a Class as a String" -msgstr "E1323: ¥¯¥é¥¹¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" - msgid "E1324: Using an Object as a String" msgstr "E1324: ¥ª¥Ö¥¸¥§¥¯¥È¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" @@ -8362,14 +8367,14 @@ msgid "E1330: Invalid type for object variable: %s" msgstr "E1330: ¥ª¥Ö¥¸¥§¥¯¥ÈÊÑ¿ô¤È¤·¤Æ̵¸ú¤Ê·¿¤Ç¤¹: %s" msgid "" -"E1331: Public must be followed by \"var\" or \"static\" or \"final\" or " +"E1331: public must be followed by \"var\" or \"static\" or \"final\" or " "\"const\"" msgstr "" "E1331: public ¤Î¸å¤í¤Ë \"var\", \"static\", \"final\" ¤Þ¤¿¤Ï \"const\" ¤¬É¬Í×" "¤Ç¤¹" #, c-format -msgid "E1332: Public variable name cannot start with underscore: %s" +msgid "E1332: public variable name cannot start with underscore: %s" msgstr "E1332: ¥Ñ¥Ö¥ê¥Ã¥¯ÊÑ¿ô̾¤Ï¥¢¥ó¥À¡¼¥¹¥³¥¢¤Ç»Ï¤á¤ë¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó: %s" #, c-format @@ -8575,10 +8580,10 @@ msgstr "" "E1386: ¥ª¥Ö¥¸¥§¥¯¥È¥á¥½¥Ã¥É \"%s\" ¤Ï¥¯¥é¥¹ \"%s\" ¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò»È¤¦¤³¤È¤Î" "¤ß¤Ç¥¢¥¯¥»¥¹¤Ç¤¤Þ¤¹" -msgid "E1387: Public variable not supported in an interface" +msgid "E1387: public variable not supported in an interface" msgstr "E1387: ¥¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹Æâ¤Ç¥Ñ¥Ö¥ê¥Ã¥¯ÊÑ¿ô¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" -msgid "E1388: Public keyword not supported for a method" +msgid "E1388: public keyword not supported for a method" msgstr "E1388: ¥¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹Æâ¤Ç public ¥¡¼¥ï¡¼¥É¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" msgid "E1389: Missing name after implements" @@ -8608,10 +8613,6 @@ msgid "E1394: Type name must start with an uppercase letter: %s" msgstr "E1394: ·¿¤Î̾Á°¤Ï±ÑÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s" #, c-format -msgid "E1395: Type alias \"%s\" cannot be modified" -msgstr "E1395: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤ÏÊѹ¹¤Ç¤¤Þ¤»¤ó" - -#, c-format msgid "E1396: Type alias \"%s\" already exists" msgstr "E1396: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤Ï´û¤Ë¸ºß¤·¤Þ¤¹" @@ -8625,18 +8626,6 @@ msgid "E1399: Type can only be used in a script" msgstr "E1399: ·¿¤Ï¥¹¥¯¥ê¥×¥È¤ÎÃæ¤Ç¤Î¤ß»ÈÍѤǤ¤Þ¤¹" #, c-format -msgid "E1400: Using type alias \"%s\" as a Number" -msgstr "E1400: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" - -#, c-format -msgid "E1401: Using type alias \"%s\" as a Float" -msgstr "E1401: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" - -#, c-format -msgid "E1402: Using type alias \"%s\" as a String" -msgstr "E1402: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" - -#, c-format msgid "E1403: Type alias \"%s\" cannot be used as a value" msgstr "E1403: ·¿¥¨¥¤¥ê¥¢¥¹ \"%s\" ¤òÃͤȤ·¤Æ»È¤¦¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó" @@ -8647,9 +8636,6 @@ msgstr "E1404: abstract ¤ò¥¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹Æâ¤Ç»È¤¦¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó" msgid "E1405: Class \"%s\" cannot be used as a value" msgstr "E1405: ¥¯¥é¥¹ \"%s\" ¤òÃͤȤ·¤Æ»È¤¦¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó" -msgid "E1406: Cannot use a Class as a variable or value" -msgstr "E1406: ¥¯¥é¥¹¤òÊÑ¿ô¤äÃͤȤ·¤Æ»È¤¦¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó" - msgid "E1407: Cannot use a Typealias as a variable or value" msgstr "E1407: ·¿¥¨¥¤¥ê¥¢¥¹¤òÊÑ¿ô¤äÃͤȤ·¤Æ»È¤¦¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó" @@ -8665,6 +8651,76 @@ msgid "E1410: Const variable not supported in an interface" msgstr "E1410: ¥¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹Æâ¤Ç const ÊÑ¿ô¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" #, c-format +msgid "E1411: Missing dot after object \"%s\"" +msgstr "E1411: ¥ª¥Ö¥¸¥§¥¯¥È \"%s\" ¤Î¸å¤Ë¥É¥Ã¥È¤¬¤¢¤ê¤Þ¤»¤ó" + +#, c-format +msgid "E1412: Builtin object method \"%s\" not supported" +msgstr "E1412: ÁȤ߹þ¤ß¥ª¥Ö¥¸¥§¥¯¥È¥á¥½¥Ã¥É \"%s\" ¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" + +msgid "E1413: Builtin class method not supported" +msgstr "E1413: ÁȤ߹þ¤ß¥¯¥é¥¹¥á¥½¥Ã¥É¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" + +msgid "E1414: Enum can only be defined in Vim9 script" +msgstr "E1414: Îóµó·¿¤Ï Vim9 script ¤ÎÃæ¤Ç¤Î¤ßÄêµÁ¤Ç¤¤Þ¤¹" + +#, c-format +msgid "E1415: Enum name must start with an uppercase letter: %s" +msgstr "E1415: Îóµó·¿¤Î̾Á°¤Ï±ÑÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s" + +msgid "E1416: Enum cannot extend a class or enum" +msgstr "E1416: Îóµó·¿¤Ï¥¯¥é¥¹¤äÎóµó·¿¤ò³ÈÄ¥¤Ç¤¤Þ¤»¤ó" + +msgid "E1417: Abstract cannot be used in an Enum" +msgstr "E1417: abstract ¤òÎóµó·¿Æâ¤Ç»È¤¦¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó" + +#, c-format +msgid "E1418: Invalid enum value declaration: %s" +msgstr "E1418: ÉÔÀµ¤ÊÎóµóÃͤÎÀë¸À¤Ç¤¹: %s" + +#, c-format +msgid "E1419: Not a valid command in an Enum: %s" +msgstr "E1419: Îóµó·¿Æâ¤Ç¤Ï»È¤¨¤Ê¤¤¥³¥Þ¥ó¥É¤Ç¤¹: %s" + +msgid "E1420: Missing :endenum" +msgstr "E1420: :endenum ¤¬¤¢¤ê¤Þ¤»¤ó" + +#, c-format +msgid "E1421: Enum \"%s\" cannot be used as a value" +msgstr "E1421: Îóµó·¿ \"%s\" ¤òÃͤȤ·¤Æ»È¤¦¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó" + +#, c-format +msgid "E1422: Enum value \"%s\" not found in enum \"%s\"" +msgstr "E1422: ÎóµóÃÍ \"%s\" ¤¬Îóµó·¿ \"%s\" Æâ¤Ç¸«¤Ä¤«¤ê¤Þ¤»¤ó" + +#, c-format +msgid "E1423: Enum value \"%s.%s\" cannot be modified" +msgstr "E1423: ÎóµóÃÍ \"%s.%s\" ¤ÏÊѹ¹¤Ç¤¤Þ¤»¤ó" + +#, c-format +msgid "E1424: Using an Enum \"%s\" as a Number" +msgstr "E1424: Îóµó·¿ \"%s\" ¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" + +#, c-format +msgid "E1425: Using an Enum \"%s\" as a String" +msgstr "E1425: Îóµó·¿ \"%s\" ¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" + +#, c-format +msgid "E1426: Enum \"%s\" ordinal value cannot be modified" +msgstr "E1426: Îóµó·¿ \"%s\" ¤Î½ç½øÃͤÏÊѹ¹¤Ç¤¤Þ¤»¤ó" + +#, c-format +msgid "E1427: Enum \"%s\" name cannot be modified" +msgstr "E1427: Îóµó·¿ \"%s\" ¤Î̾Á°¤ÏÊѹ¹¤Ç¤¤Þ¤»¤ó" + +#, c-format +msgid "E1428: Duplicate enum value: %s" +msgstr "E1428: ÎóµóÃͤ¬½ÅÊ£¤·¤Æ¤¤¤Þ¤¹: %s" + +msgid "E1429: Class can only be used in a script" +msgstr "E1429: ¥¯¥é¥¹¤Ï¥¹¥¯¥ê¥×¥È¤ÎÃæ¤Ç¤Î¤ß»ÈÍѤǤ¤Þ¤¹" + +#, c-format msgid "E1500: Cannot mix positional and non-positional arguments: %s" msgstr "E1500: °ÌÃÖ°ú¿ô¤ÈÈó°ÌÃÖ°ú¿ô¤òº®¤¼¤ë¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó: %s" @@ -8708,6 +8764,17 @@ msgstr "E1509: ³Èĥ°À¤ÎÆɹþ¤ß¤Þ¤¿¤Ï½ñ¹þ¤ß¤Ç¥¨¥é¡¼¤¬µ¯¤¤Þ¤·¤¿" msgid "E1510: Value too large: %s" msgstr "E1510: Ãͤ¬Â礲᤮¤Þ¤¹: %s" +#, c-format +msgid "E1511: Wrong number of characters for field \"%s\"" +msgstr "E1511: ¥Õ¥£¡¼¥ë¥É \"%s\" ¤Îʸ»ú¿ô¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹" + +#, c-format +msgid "E1512: Wrong character width for field \"%s\"" +msgstr "E1512: ¥Õ¥£¡¼¥ë¥É \"%s\" ¤Îʸ»úÉý¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹" + +msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled" +msgstr "E1513: ¥Ð¥Ã¥Õ¥¡¤òÀÚ¤êÂؤ¨¤é¤ì¤Þ¤»¤ó¡£'winfixbuf' ¤¬Í¸ú²½¤µ¤ì¤Æ¤¤¤Þ¤¹" + msgid "--No lines in buffer--" msgstr "--¥Ð¥Ã¥Õ¥¡¤Ë¹Ô¤¬¤¢¤ê¤Þ¤»¤ó--" @@ -9096,7 +9163,7 @@ msgid "\" Hit <Enter> on an index line to jump there." msgstr "\" ¥¤¥ó¥Ç¥Ã¥¯¥¹¹Ô¤Ç <Enter> ¤òÂǤĤȡ¢¤½¤³¤Ë¥¸¥ã¥ó¥×¤·¤Þ¤¹¡£" msgid "\" Hit <Space> on a \"set\" line to refresh it." -msgstr "\" \"set\" ¹Ô¤Ç <Spece> ¤òÂǤĤȡ¢ºÇ¿·¤ÎÃͤ¬Æɹþ¤Þ¤ì¤Þ¤¹¡£" +msgstr "\" \"set\" ¹Ô¤Ç <Space> ¤òÂǤĤȡ¢ºÇ¿·¤ÎÃͤ¬Æɹþ¤Þ¤ì¤Þ¤¹¡£" msgid "important" msgstr "½ÅÍ×" @@ -9415,6 +9482,9 @@ msgstr "¸½ºß¤Î¥¦¥£¥ó¥É¥¦¤Ë»È¤ï¤ì¤ëºÇ¾®¹Ô¿ô" msgid "minimal number of lines used for any window" msgstr "Ǥ°Õ¤Î¥¦¥£¥ó¥É¥¦¤Ë»È¤ï¤ì¤ëºÇ¾®¹Ô¿ô" +msgid "keep window focused on a single buffer" +msgstr "¥¦¥£¥ó¥É¥¦¤¬Ê̤ΥХåե¡¤ËÀÚ¤êÂؤï¤é¤Ê¤¤¤è¤¦¤Ë¤¹¤ë" + msgid "keep the height of the window" msgstr "¥¦¥£¥ó¥É¥¦¤Î¹â¤µ¤òÊݤÄ" @@ -9490,6 +9560,9 @@ msgstr "Ê£¿ô¥¿¥Ö¥Ú¡¼¥¸" msgid "0, 1 or 2; when to use a tab pages line" msgstr "0, 1 ¤Þ¤¿¤Ï 2; ¥¿¥Ö¥Ú¡¼¥¸¹Ô¤ò¤¤¤Ä»È¤¦¤«" +msgid "behaviour when closing tab pages: left, uselast or empty" +msgstr "¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë¤È¤¤ÎµóÆ°: left, uselast ¤Þ¤¿¤Ï empty" + msgid "maximum number of tab pages to open for -p and \"tab all\"" msgstr "-p ¤È \"tab all\" ¤Ç³«¤«¤ì¤ë¥¿¥Ö¥Ú¡¼¥¸¤ÎºÇÂç¿ô" diff --git a/src/po/ja.po b/src/po/ja.po index 5464bcc..5bcf8e1 100644 --- a/src/po/ja.po +++ b/src/po/ja.po @@ -3,7 +3,7 @@ # Do ":help uganda" in Vim to read copying and usage conditions. # Do ":help credits" in Vim to see a list of people who contributed. # -# Copyright (C) 2001-2023 MURAOKA Taro <koron.kaoriya@gmail.com>, +# Copyright (C) 2001-2024 MURAOKA Taro <koron.kaoriya@gmail.com>, # vim-jp <http://vim-jp.org/> # # THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE. @@ -12,10 +12,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Vim 9.0\n" +"Project-Id-Version: Vim 9.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-18 16:41+0900\n" -"PO-Revision-Date: 2023-12-19 12:45+0900\n" +"POT-Creation-Date: 2024-07-23 10:59+0900\n" +"PO-Revision-Date: 2024-08-15 12:54+0900\n" "Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n" "Language-Team: Japanese <https://github.com/vim-jp/lang-ja>\n" "Language: ja\n" @@ -175,6 +175,9 @@ msgstr " (file %d of %d)" msgid " (file (%d) of %d)" msgstr " (file (%d) of %d)" +msgid "[Command Line]" +msgstr "[コマンドライン]" + msgid "[Prompt]" msgstr "[プãƒãƒ³ãƒ—ト]" @@ -439,10 +442,6 @@ msgstr "片仮å" msgid "Bopomofo" msgstr "注音å—æ¯" -msgid "Not enough memory to set references, garbage collection aborted!" -msgstr "" -"ガーベッジコレクションをä¸æ¢ã—ã¾ã—ãŸ! å‚照を作æˆã™ã‚‹ã®ã«ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¾ã—ãŸ" - msgid "" "\n" "\tLast set from " @@ -688,9 +687,6 @@ msgstr "エラー" msgid "Interrupt" msgstr "割込ã¿" -msgid "[Command Line]" -msgstr "[コマンドライン]" - msgid "is a directory" msgstr "ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™" @@ -854,6 +850,10 @@ msgid "+-%s%3ld line: " msgid_plural "+-%s%3ld lines: " msgstr[0] "+-%s%3ld è¡Œ: " +msgid "Not enough memory to set references, garbage collection aborted!" +msgstr "" +"ガーベッジコレクションをä¸æ¢ã—ã¾ã—ãŸ! å‚照を作æˆã™ã‚‹ã®ã«ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¾ã—ãŸ" + msgid "No match at cursor, finding next" msgstr "カーソルã®ä½ç½®ã«ãƒžãƒƒãƒã¯ã‚ã‚Šã¾ã›ã‚“ã€æ¬¡ã‚’検索ã—ã¦ã„ã¾ã™" @@ -1337,8 +1337,8 @@ msgstr " ユーザー定義補完 (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " オムニ補完 (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " 綴り修æ£å€™è£œ (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " 綴り修æ£å€™è£œ (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " 局所ã‚ーワード補完 (^N^P)" @@ -1416,6 +1416,9 @@ msgstr "mapnew() ã®å¼•æ•°" msgid "filter() argument" msgstr "filter() ã®å¼•æ•°" +msgid "foreach() argument" +msgstr "foreach() ã®å¼•æ•°" + msgid "extendnew() argument" msgstr "extendnew() ã®å¼•æ•°" @@ -2454,6 +2457,9 @@ msgstr "%s 㸠(%s 上ã®)" msgid "Printing '%s'" msgstr "å°åˆ·ã—ã¦ã„ã¾ã™: '%s'" +#~ msgid "DefaultFontNameForWindows" +#~ msgstr "" + #, c-format msgid "Opening the X display took %ld msec" msgstr "Xサーãƒãƒ¼ã¸ã®æŽ¥ç¶šã« %ld ミリ秒ã‹ã‹ã‚Šã¾ã—ãŸ" @@ -3394,8 +3400,8 @@ msgid "%s returning %s" msgstr "%s ㌠%s ã‚’è¿”ã—ã¾ã—ãŸ" #, c-format -msgid "Function %s does not need compiling" -msgstr "関数 %s ã¯ã‚³ãƒ³ãƒ‘イルã®å¿…è¦ãŒã‚ã‚Šã¾ã›ã‚“" +msgid "Function %s%s%s does not need compiling" +msgstr "関数 %s%s%s ã¯ã‚³ãƒ³ãƒ‘イルã®å¿…è¦ãŒã‚ã‚Šã¾ã›ã‚“" #, c-format msgid "%s (%s, compiled %s)" @@ -3554,6 +3560,9 @@ msgstr " 第2ユーザー vimrc: \"" msgid " 3rd user vimrc file: \"" msgstr " 第3ユーザー vimrc: \"" +msgid " 4th user vimrc file: \"" +msgstr " 第4ユーザー vimrc: \"" + msgid " user exrc file: \"" msgstr " ユーザー exrc: \"" @@ -4158,6 +4167,10 @@ msgid "E105: Using :loadkeymap not in a sourced file" msgstr "E105: :source ã§å–込むファイル以外ã§ã¯ :loadkeymap を使ãˆã¾ã›ã‚“" #, c-format +msgid "E106: Unsupported diff output format: %s" +msgstr "E106: サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„diff出力フォーマットã§ã™: %s" + +#, c-format msgid "E107: Missing parentheses: %s" msgstr "E107: カッコ '(' ãŒã‚ã‚Šã¾ã›ã‚“: %s" @@ -4486,8 +4499,8 @@ msgstr "E196: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«åˆå—ã¯ã‚ã‚Šã¾ã›ã‚“" msgid "E197: Cannot set language to \"%s\"" msgstr "E197: 言語を \"%s\" ã«è¨å®šã§ãã¾ã›ã‚“" -msgid "E199: Active window or buffer deleted" -msgstr "E199: アクティブãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‹ãƒãƒƒãƒ•ã‚¡ãŒå‰Šé™¤ã•ã‚Œã¾ã—ãŸ" +msgid "E199: Active window or buffer changed or deleted" +msgstr "E199: アクティブãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‹ãƒãƒƒãƒ•ã‚¡ãŒå¤‰æ›´ã¾ãŸã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ" msgid "E200: *ReadPre autocommands made the file unreadable" msgstr "E200: *ReadPre 自動コマンド ãŒãƒ•ã‚¡ã‚¤ãƒ«ã‚’èªè¾¼ä¸å¯ã«ã—ã¾ã—ãŸ" @@ -5857,9 +5870,6 @@ msgstr "E612: signã®å®šç¾©ãŒå¤šéŽãŽã¾ã™" msgid "E613: Unknown printer font: %s" msgstr "E613: 未知ã®ãƒ—リンタオプションã§ã™: %s" -msgid "E614: Class required" -msgstr "E614: クラスãŒå¿…è¦ã§ã™" - #, c-format msgid "E616: Object required for argument %d" msgstr "E616: 引数 %d ã«ã¯ã‚ªãƒ–ジェクトãŒå¿…è¦ã§ã™" @@ -6696,7 +6706,7 @@ msgid "E862: Cannot use g: here" msgstr "E862: ã“ã“ã§ã¯ g: ã¯ä½¿ãˆã¾ã›ã‚“" msgid "E863: Not allowed for a terminal in a popup window" -msgstr "E863: 端末ã¯ãƒãƒƒãƒ—アップウィンドウã§ã¯è¨±ã•ã‚Œã¾ã›ã‚“" +msgstr "E863: ãƒãƒƒãƒ—アップウィンドウ内ã®ç«¯æœ«ã§ã¯è¨±ã•ã‚Œã¾ã›ã‚“" #, no-c-format msgid "" @@ -6753,6 +6763,10 @@ msgstr "" msgid "E876: (NFA regexp) Not enough space to store the whole NFA" msgstr "E876: (NFA æ£è¦è¡¨ç¾) NFA全体をä¿å˜ã™ã‚‹ã«ã¯ç©ºãスペースãŒè¶³ã‚Šã¾ã›ã‚“" +#, c-format +msgid "E877: (NFA regexp) Invalid character class: %d" +msgstr "E877: (NFA æ£è¦è¡¨ç¾) 無効ãªæ–‡å—クラスã§ã™: %d" + msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!" msgstr "" "E878: (NFA æ£è¦è¡¨ç¾) ç¾åœ¨æ¨ªæ–ä¸ã®ãƒ–ランãƒã«å分ãªãƒ¡ãƒ¢ãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“!" @@ -8319,21 +8333,12 @@ msgstr "E1317: ä¸æ£ãªã‚ªãƒ–ジェクト変数ã®å®£è¨€ã§ã™: %s" msgid "E1318: Not a valid command in a class: %s" msgstr "E1318: クラス内ã§ã¯ä½¿ãˆãªã„コマンドã§ã™: %s" -msgid "E1319: Using a Class as a Number" -msgstr "E1319: クラスを数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" - msgid "E1320: Using an Object as a Number" msgstr "E1320: オブジェクトを数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" -msgid "E1321: Using a Class as a Float" -msgstr "E1321: クラスを浮動å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" - msgid "E1322: Using an Object as a Float" msgstr "E1322: オブジェクトを浮動å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" -msgid "E1323: Using a Class as a String" -msgstr "E1323: クラスを文å—列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" - msgid "E1324: Using an Object as a String" msgstr "E1324: オブジェクトを文å—列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" @@ -8362,14 +8367,14 @@ msgid "E1330: Invalid type for object variable: %s" msgstr "E1330: オブジェクト変数ã¨ã—ã¦ç„¡åŠ¹ãªåž‹ã§ã™: %s" msgid "" -"E1331: Public must be followed by \"var\" or \"static\" or \"final\" or " +"E1331: public must be followed by \"var\" or \"static\" or \"final\" or " "\"const\"" msgstr "" "E1331: public ã®å¾Œã‚ã« \"var\", \"static\", \"final\" ã¾ãŸã¯ \"const\" ãŒå¿…è¦" "ã§ã™" #, c-format -msgid "E1332: Public variable name cannot start with underscore: %s" +msgid "E1332: public variable name cannot start with underscore: %s" msgstr "E1332: パブリック変数åã¯ã‚¢ãƒ³ãƒ€ãƒ¼ã‚¹ã‚³ã‚¢ã§å§‹ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“: %s" #, c-format @@ -8575,10 +8580,10 @@ msgstr "" "E1386: オブジェクトメソッド \"%s\" ã¯ã‚¯ãƒ©ã‚¹ \"%s\" ã®ã‚ªãƒ–ジェクトを使ã†ã“ã¨ã®" "ã¿ã§ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™" -msgid "E1387: Public variable not supported in an interface" +msgid "E1387: public variable not supported in an interface" msgstr "E1387: インターフェイス内ã§ãƒ‘ブリック変数ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“" -msgid "E1388: Public keyword not supported for a method" +msgid "E1388: public keyword not supported for a method" msgstr "E1388: インターフェイス内㧠public ã‚ーワードã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“" msgid "E1389: Missing name after implements" @@ -8608,10 +8613,6 @@ msgid "E1394: Type name must start with an uppercase letter: %s" msgstr "E1394: åž‹ã®åå‰ã¯è‹±å¤§æ–‡å—ã§å§‹ã¾ã‚‰ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“: %s" #, c-format -msgid "E1395: Type alias \"%s\" cannot be modified" -msgstr "E1395: 型エイリアス \"%s\" ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" - -#, c-format msgid "E1396: Type alias \"%s\" already exists" msgstr "E1396: 型エイリアス \"%s\" ã¯æ—¢ã«å˜åœ¨ã—ã¾ã™" @@ -8625,18 +8626,6 @@ msgid "E1399: Type can only be used in a script" msgstr "E1399: åž‹ã¯ã‚¹ã‚¯ãƒªãƒ—トã®ä¸ã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" #, c-format -msgid "E1400: Using type alias \"%s\" as a Number" -msgstr "E1400: 型エイリアス \"%s\" を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" - -#, c-format -msgid "E1401: Using type alias \"%s\" as a Float" -msgstr "E1401: 型エイリアス \"%s\" を浮動å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" - -#, c-format -msgid "E1402: Using type alias \"%s\" as a String" -msgstr "E1402: 型エイリアス \"%s\" ã‚’æ–‡å—列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" - -#, c-format msgid "E1403: Type alias \"%s\" cannot be used as a value" msgstr "E1403: 型エイリアス \"%s\" を値ã¨ã—ã¦ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" @@ -8647,9 +8636,6 @@ msgstr "E1404: abstract をインターフェイス内ã§ä½¿ã†ã“ã¨ã¯ã§ãã msgid "E1405: Class \"%s\" cannot be used as a value" msgstr "E1405: クラス \"%s\" を値ã¨ã—ã¦ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" -msgid "E1406: Cannot use a Class as a variable or value" -msgstr "E1406: クラスを変数や値ã¨ã—ã¦ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" - msgid "E1407: Cannot use a Typealias as a variable or value" msgstr "E1407: 型エイリアスを変数や値ã¨ã—ã¦ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" @@ -8665,6 +8651,76 @@ msgid "E1410: Const variable not supported in an interface" msgstr "E1410: インターフェイス内㧠const 変数ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“" #, c-format +msgid "E1411: Missing dot after object \"%s\"" +msgstr "E1411: オブジェクト \"%s\" ã®å¾Œã«ãƒ‰ãƒƒãƒˆãŒã‚ã‚Šã¾ã›ã‚“" + +#, c-format +msgid "E1412: Builtin object method \"%s\" not supported" +msgstr "E1412: 組ã¿è¾¼ã¿ã‚ªãƒ–ジェクトメソッド \"%s\" ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“" + +msgid "E1413: Builtin class method not supported" +msgstr "E1413: 組ã¿è¾¼ã¿ã‚¯ãƒ©ã‚¹ãƒ¡ã‚½ãƒƒãƒ‰ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“" + +msgid "E1414: Enum can only be defined in Vim9 script" +msgstr "E1414: 列挙型㯠Vim9 script ã®ä¸ã§ã®ã¿å®šç¾©ã§ãã¾ã™" + +#, c-format +msgid "E1415: Enum name must start with an uppercase letter: %s" +msgstr "E1415: 列挙型ã®åå‰ã¯è‹±å¤§æ–‡å—ã§å§‹ã¾ã‚‰ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“: %s" + +msgid "E1416: Enum cannot extend a class or enum" +msgstr "E1416: 列挙型ã¯ã‚¯ãƒ©ã‚¹ã‚„列挙型を拡張ã§ãã¾ã›ã‚“" + +msgid "E1417: Abstract cannot be used in an Enum" +msgstr "E1417: abstract を列挙型内ã§ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#, c-format +msgid "E1418: Invalid enum value declaration: %s" +msgstr "E1418: ä¸æ£ãªåˆ—挙値ã®å®£è¨€ã§ã™: %s" + +#, c-format +msgid "E1419: Not a valid command in an Enum: %s" +msgstr "E1419: 列挙型内ã§ã¯ä½¿ãˆãªã„コマンドã§ã™: %s" + +msgid "E1420: Missing :endenum" +msgstr "E1420: :endenum ãŒã‚ã‚Šã¾ã›ã‚“" + +#, c-format +msgid "E1421: Enum \"%s\" cannot be used as a value" +msgstr "E1421: 列挙型 \"%s\" を値ã¨ã—ã¦ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#, c-format +msgid "E1422: Enum value \"%s\" not found in enum \"%s\"" +msgstr "E1422: 列挙値 \"%s\" ãŒåˆ—挙型 \"%s\" 内ã§è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" + +#, c-format +msgid "E1423: Enum value \"%s.%s\" cannot be modified" +msgstr "E1423: 列挙値 \"%s.%s\" ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#, c-format +msgid "E1424: Using an Enum \"%s\" as a Number" +msgstr "E1424: 列挙型 \"%s\" を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" + +#, c-format +msgid "E1425: Using an Enum \"%s\" as a String" +msgstr "E1425: 列挙型 \"%s\" ã‚’æ–‡å—列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" + +#, c-format +msgid "E1426: Enum \"%s\" ordinal value cannot be modified" +msgstr "E1426: 列挙型 \"%s\" ã®é †åºå€¤ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#, c-format +msgid "E1427: Enum \"%s\" name cannot be modified" +msgstr "E1427: 列挙型 \"%s\" ã®åå‰ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#, c-format +msgid "E1428: Duplicate enum value: %s" +msgstr "E1428: 列挙値ãŒé‡è¤‡ã—ã¦ã„ã¾ã™: %s" + +msgid "E1429: Class can only be used in a script" +msgstr "E1429: クラスã¯ã‚¹ã‚¯ãƒªãƒ—トã®ä¸ã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" + +#, c-format msgid "E1500: Cannot mix positional and non-positional arguments: %s" msgstr "E1500: ä½ç½®å¼•æ•°ã¨éžä½ç½®å¼•æ•°ã‚’æ··ãœã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“: %s" @@ -8708,6 +8764,17 @@ msgstr "E1509: 拡張属性ã®èªè¾¼ã¿ã¾ãŸã¯æ›¸è¾¼ã¿ã§ã‚¨ãƒ©ãƒ¼ãŒèµ·ãã msgid "E1510: Value too large: %s" msgstr "E1510: 値ãŒå¤§ãéŽãŽã¾ã™: %s" +#, c-format +msgid "E1511: Wrong number of characters for field \"%s\"" +msgstr "E1511: フィールド \"%s\" ã®æ–‡å—æ•°ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#, c-format +msgid "E1512: Wrong character width for field \"%s\"" +msgstr "E1512: フィールド \"%s\" ã®æ–‡å—å¹…ãŒé–“é•ã£ã¦ã„ã¾ã™" + +msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled" +msgstr "E1513: ãƒãƒƒãƒ•ã‚¡ã‚’切り替ãˆã‚‰ã‚Œã¾ã›ã‚“。'winfixbuf' ãŒæœ‰åŠ¹åŒ–ã•ã‚Œã¦ã„ã¾ã™" + msgid "--No lines in buffer--" msgstr "--ãƒãƒƒãƒ•ã‚¡ã«è¡ŒãŒã‚ã‚Šã¾ã›ã‚“--" @@ -9096,7 +9163,7 @@ msgid "\" Hit <Enter> on an index line to jump there." msgstr "\" インデックス行㧠<Enter> を打ã¤ã¨ã€ãã“ã«ã‚¸ãƒ£ãƒ³ãƒ—ã—ã¾ã™ã€‚" msgid "\" Hit <Space> on a \"set\" line to refresh it." -msgstr "\" \"set\" 行㧠<Spece> を打ã¤ã¨ã€æœ€æ–°ã®å€¤ãŒèªè¾¼ã¾ã‚Œã¾ã™ã€‚" +msgstr "\" \"set\" 行㧠<Space> を打ã¤ã¨ã€æœ€æ–°ã®å€¤ãŒèªè¾¼ã¾ã‚Œã¾ã™ã€‚" msgid "important" msgstr "é‡è¦" @@ -9415,6 +9482,9 @@ msgstr "ç¾åœ¨ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«ä½¿ã‚れる最å°è¡Œæ•°" msgid "minimal number of lines used for any window" msgstr "ä»»æ„ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«ä½¿ã‚れる最å°è¡Œæ•°" +msgid "keep window focused on a single buffer" +msgstr "ウィンドウãŒåˆ¥ã®ãƒãƒƒãƒ•ã‚¡ã«åˆ‡ã‚Šæ›¿ã‚らãªã„よã†ã«ã™ã‚‹" + msgid "keep the height of the window" msgstr "ウィンドウã®é«˜ã•ã‚’ä¿ã¤" @@ -9490,6 +9560,9 @@ msgstr "複数タブページ" msgid "0, 1 or 2; when to use a tab pages line" msgstr "0, 1 ã¾ãŸã¯ 2; タブページ行をã„ã¤ä½¿ã†ã‹" +msgid "behaviour when closing tab pages: left, uselast or empty" +msgstr "タブページを閉ã˜ã‚‹ã¨ãã®æŒ™å‹•: left, uselast ã¾ãŸã¯ empty" + msgid "maximum number of tab pages to open for -p and \"tab all\"" msgstr "-p 㨠\"tab all\" ã§é–‹ã‹ã‚Œã‚‹ã‚¿ãƒ–ページã®æœ€å¤§æ•°" diff --git a/src/po/ja.sjis.po b/src/po/ja.sjis.po index 589fd5a..7505121 100644 --- a/src/po/ja.sjis.po +++ b/src/po/ja.sjis.po @@ -3,7 +3,7 @@ # Do ":help uganda" in Vim to read copying and usage conditions. # Do ":help credits" in Vim to see a list of people who contributed. # -# Copyright (C) 2001-2023 MURAOKA Taro <koron.kaoriya@gmail.com>, +# Copyright (C) 2001-2024 MURAOKA Taro <koron.kaoriya@gmail.com>, # vim-jp <http://vim-jp.org/> # # THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE. @@ -12,10 +12,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Vim 9.0\n" +"Project-Id-Version: Vim 9.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-18 16:41+0900\n" -"PO-Revision-Date: 2023-12-19 12:45+0900\n" +"POT-Creation-Date: 2024-07-23 10:59+0900\n" +"PO-Revision-Date: 2024-08-15 12:54+0900\n" "Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n" "Language-Team: Japanese <https://github.com/vim-jp/lang-ja>\n" "Language: ja\n" @@ -175,6 +175,9 @@ msgstr " (file %d of %d)" msgid " (file (%d) of %d)" msgstr " (file (%d) of %d)" +msgid "[Command Line]" +msgstr "[ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“]" + msgid "[Prompt]" msgstr "[ƒvƒƒ“ƒvƒg]" @@ -439,10 +442,6 @@ msgstr "•Ð‰¼–¼" msgid "Bopomofo" msgstr "’‰¹Žš•ê" -msgid "Not enough memory to set references, garbage collection aborted!" -msgstr "" -"ƒK[ƒxƒbƒWƒRƒŒƒNƒVƒ‡ƒ“‚𒆎~‚µ‚Ü‚µ‚½! ŽQÆ‚ð쬂·‚é‚̂Ƀƒ‚ƒŠ‚ª•s‘«‚µ‚Ü‚µ‚½" - msgid "" "\n" "\tLast set from " @@ -688,9 +687,6 @@ msgstr "ƒGƒ‰[" msgid "Interrupt" msgstr "Š„ž‚Ý" -msgid "[Command Line]" -msgstr "[ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“]" - msgid "is a directory" msgstr "‚̓fƒBƒŒƒNƒgƒŠ‚Å‚·" @@ -854,6 +850,10 @@ msgid "+-%s%3ld line: " msgid_plural "+-%s%3ld lines: " msgstr[0] "+-%s%3ld s: " +msgid "Not enough memory to set references, garbage collection aborted!" +msgstr "" +"ƒK[ƒxƒbƒWƒRƒŒƒNƒVƒ‡ƒ“‚𒆎~‚µ‚Ü‚µ‚½! ŽQÆ‚ð쬂·‚é‚̂Ƀƒ‚ƒŠ‚ª•s‘«‚µ‚Ü‚µ‚½" + msgid "No match at cursor, finding next" msgstr "ƒJ[ƒ\\ƒ‹‚̈ʒu‚Ƀ}ƒbƒ`‚Í‚ ‚è‚Ü‚¹‚ñAŽŸ‚ðŒŸõ‚µ‚Ä‚¢‚Ü‚·" @@ -1337,8 +1337,8 @@ msgstr " ƒ†[ƒU[’è‹`•âŠ® (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " ƒIƒ€ƒj•âŠ® (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " ’Ô‚èC³Œó•â (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " ’Ô‚èC³Œó•â (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ‹ÇŠƒL[ƒ[ƒh•âŠ® (^N^P)" @@ -1416,6 +1416,9 @@ msgstr "mapnew() ‚̈ø”" msgid "filter() argument" msgstr "filter() ‚̈ø”" +msgid "foreach() argument" +msgstr "foreach() ‚̈ø”" + msgid "extendnew() argument" msgstr "extendnew() ‚̈ø”" @@ -2454,6 +2457,9 @@ msgstr "%s ‚Ö (%s ã‚Ì)" msgid "Printing '%s'" msgstr "ˆóü‚µ‚Ä‚¢‚Ü‚·: '%s'" +#~ msgid "DefaultFontNameForWindows" +#~ msgstr "" + #, c-format msgid "Opening the X display took %ld msec" msgstr "XƒT[ƒo[‚Ö‚ÌÚ‘±‚É %ld ƒ~ƒŠ•b‚©‚©‚è‚Ü‚µ‚½" @@ -3394,8 +3400,8 @@ msgid "%s returning %s" msgstr "%s ‚ª %s ‚ð•Ô‚µ‚Ü‚µ‚½" #, c-format -msgid "Function %s does not need compiling" -msgstr "ŠÖ” %s ‚̓Rƒ“ƒpƒCƒ‹‚Ì•K—v‚ª‚ ‚è‚Ü‚¹‚ñ" +msgid "Function %s%s%s does not need compiling" +msgstr "ŠÖ” %s%s%s ‚̓Rƒ“ƒpƒCƒ‹‚Ì•K—v‚ª‚ ‚è‚Ü‚¹‚ñ" #, c-format msgid "%s (%s, compiled %s)" @@ -3554,6 +3560,9 @@ msgstr " ‘æ2ƒ†[ƒU[ vimrc: \"" msgid " 3rd user vimrc file: \"" msgstr " ‘æ3ƒ†[ƒU[ vimrc: \"" +msgid " 4th user vimrc file: \"" +msgstr " ‘æ4ƒ†[ƒU[ vimrc: \"" + msgid " user exrc file: \"" msgstr " ƒ†[ƒU[ exrc: \"" @@ -4158,6 +4167,10 @@ msgid "E105: Using :loadkeymap not in a sourced file" msgstr "E105: :source ‚ÅŽæž‚Þƒtƒ@ƒCƒ‹ˆÈŠO‚Å‚Í :loadkeymap ‚ðŽg‚¦‚Ü‚¹‚ñ" #, c-format +msgid "E106: Unsupported diff output format: %s" +msgstr "E106: ƒTƒ|[ƒg‚µ‚Ä‚¢‚È‚¢diffo—̓tƒH[ƒ}ƒbƒg‚Å‚·: %s" + +#, c-format msgid "E107: Missing parentheses: %s" msgstr "E107: ƒJƒbƒR '(' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s" @@ -4486,8 +4499,8 @@ msgstr "E196: ‚±‚̃o[ƒWƒ‡ƒ“‚ɇŽš‚Í‚ ‚è‚Ü‚¹‚ñ" msgid "E197: Cannot set language to \"%s\"" msgstr "E197: Œ¾Œê‚ð \"%s\" ‚ÉÝ’è‚Å‚«‚Ü‚¹‚ñ" -msgid "E199: Active window or buffer deleted" -msgstr "E199: ƒAƒNƒeƒBƒu‚ȃEƒBƒ“ƒhƒE‚©ƒoƒbƒtƒ@‚ªíœ‚³‚ê‚Ü‚µ‚½" +msgid "E199: Active window or buffer changed or deleted" +msgstr "E199: ƒAƒNƒeƒBƒu‚ȃEƒBƒ“ƒhƒE‚©ƒoƒbƒtƒ@‚ª•ÏX‚Ü‚½‚Í휂³‚ê‚Ü‚µ‚½" msgid "E200: *ReadPre autocommands made the file unreadable" msgstr "E200: *ReadPre Ž©“®ƒRƒ}ƒ“ƒh ‚ªƒtƒ@ƒCƒ‹‚ð“Çž•s‰Â‚É‚µ‚Ü‚µ‚½" @@ -5857,9 +5870,6 @@ msgstr "E612: sign‚Ì’è‹`‚ª‘½‰ß‚¬‚Ü‚·" msgid "E613: Unknown printer font: %s" msgstr "E613: –¢’m‚̃vƒŠƒ“ƒ^ƒIƒvƒVƒ‡ƒ“‚Å‚·: %s" -msgid "E614: Class required" -msgstr "E614: ƒNƒ‰ƒX‚ª•K—v‚Å‚·" - #, c-format msgid "E616: Object required for argument %d" msgstr "E616: ˆø” %d ‚ɂ̓IƒuƒWƒFƒNƒg‚ª•K—v‚Å‚·" @@ -6696,7 +6706,7 @@ msgid "E862: Cannot use g: here" msgstr "E862: ‚±‚±‚Å‚Í g: ‚ÍŽg‚¦‚Ü‚¹‚ñ" msgid "E863: Not allowed for a terminal in a popup window" -msgstr "E863: ’[––‚̓|ƒbƒvƒAƒbƒvƒEƒBƒ“ƒhƒE‚Å‚Í‹–‚³‚ê‚Ü‚¹‚ñ" +msgstr "E863: ƒ|ƒbƒvƒAƒbƒvƒEƒBƒ“ƒhƒE“à‚Ì’[––‚Å‚Í‹–‚³‚ê‚Ü‚¹‚ñ" #, no-c-format msgid "" @@ -6753,6 +6763,10 @@ msgstr "" msgid "E876: (NFA regexp) Not enough space to store the whole NFA" msgstr "E876: (NFA ³‹K•\\Œ») NFA‘S‘Ì‚ð•Û‘¶‚·‚é‚ɂ͋󂫃Xƒy[ƒX‚ª‘«‚è‚Ü‚¹‚ñ" +#, c-format +msgid "E877: (NFA regexp) Invalid character class: %d" +msgstr "E877: (NFA ³‹K•\\Œ») –³Œø‚È•¶ŽšƒNƒ‰ƒX‚Å‚·: %d" + msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!" msgstr "" "E878: (NFA ³‹K•\\Œ») Œ»Ý‰¡’f’†‚̃uƒ‰ƒ“ƒ`‚É\\•ª‚ȃƒ‚ƒŠ‚ðŠ„‚è“–‚Ä‚ç‚ê‚Ü‚¹‚ñ!" @@ -8319,21 +8333,12 @@ msgstr "E1317: •s³‚ȃIƒuƒWƒFƒNƒg•Ï”‚Ì錾‚Å‚·: %s" msgid "E1318: Not a valid command in a class: %s" msgstr "E1318: ƒNƒ‰ƒX“à‚Å‚ÍŽg‚¦‚È‚¢ƒRƒ}ƒ“ƒh‚Å‚·: %s" -msgid "E1319: Using a Class as a Number" -msgstr "E1319: ƒNƒ‰ƒX‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" - msgid "E1320: Using an Object as a Number" msgstr "E1320: ƒIƒuƒWƒFƒNƒg‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" -msgid "E1321: Using a Class as a Float" -msgstr "E1321: ƒNƒ‰ƒX‚ð•‚“®¬”“_”‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" - msgid "E1322: Using an Object as a Float" msgstr "E1322: ƒIƒuƒWƒFƒNƒg‚ð•‚“®¬”“_”‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" -msgid "E1323: Using a Class as a String" -msgstr "E1323: ƒNƒ‰ƒX‚𕶎š—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" - msgid "E1324: Using an Object as a String" msgstr "E1324: ƒIƒuƒWƒFƒNƒg‚𕶎š—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" @@ -8362,14 +8367,14 @@ msgid "E1330: Invalid type for object variable: %s" msgstr "E1330: ƒIƒuƒWƒFƒNƒg•Ï”‚Æ‚µ‚Ä–³Œø‚ÈŒ^‚Å‚·: %s" msgid "" -"E1331: Public must be followed by \"var\" or \"static\" or \"final\" or " +"E1331: public must be followed by \"var\" or \"static\" or \"final\" or " "\"const\"" msgstr "" "E1331: public ‚ÌŒã‚ë‚É \"var\", \"static\", \"final\" ‚Ü‚½‚Í \"const\" ‚ª•K—v" "‚Å‚·" #, c-format -msgid "E1332: Public variable name cannot start with underscore: %s" +msgid "E1332: public variable name cannot start with underscore: %s" msgstr "E1332: ƒpƒuƒŠƒbƒN•Ï”–¼‚̓Aƒ“ƒ_[ƒXƒRƒA‚ÅŽn‚߂邱‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ: %s" #, c-format @@ -8575,10 +8580,10 @@ msgstr "" "E1386: ƒIƒuƒWƒFƒNƒgƒƒ\\ƒbƒh \"%s\" ‚̓Nƒ‰ƒX \"%s\" ‚̃IƒuƒWƒFƒNƒg‚ðŽg‚¤‚±‚Æ‚Ì" "‚݂ŃAƒNƒZƒX‚Å‚«‚Ü‚·" -msgid "E1387: Public variable not supported in an interface" +msgid "E1387: public variable not supported in an interface" msgstr "E1387: ƒCƒ“ƒ^[ƒtƒFƒCƒX“à‚ŃpƒuƒŠƒbƒN•Ï”‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ" -msgid "E1388: Public keyword not supported for a method" +msgid "E1388: public keyword not supported for a method" msgstr "E1388: ƒCƒ“ƒ^[ƒtƒFƒCƒX“à‚Å public ƒL[ƒ[ƒh‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ" msgid "E1389: Missing name after implements" @@ -8608,10 +8613,6 @@ msgid "E1394: Type name must start with an uppercase letter: %s" msgstr "E1394: Œ^‚Ì–¼‘O‚͉p‘啶Žš‚ÅŽn‚Ü‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ: %s" #, c-format -msgid "E1395: Type alias \"%s\" cannot be modified" -msgstr "E1395: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ" - -#, c-format msgid "E1396: Type alias \"%s\" already exists" msgstr "E1396: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚ÍŠù‚É‘¶Ý‚µ‚Ü‚·" @@ -8625,18 +8626,6 @@ msgid "E1399: Type can only be used in a script" msgstr "E1399: Œ^‚̓XƒNƒŠƒvƒg‚Ì’†‚Å‚Ì‚ÝŽg—p‚Å‚«‚Ü‚·" #, c-format -msgid "E1400: Using type alias \"%s\" as a Number" -msgstr "E1400: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" - -#, c-format -msgid "E1401: Using type alias \"%s\" as a Float" -msgstr "E1401: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚ð•‚“®¬”“_”‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" - -#, c-format -msgid "E1402: Using type alias \"%s\" as a String" -msgstr "E1402: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚𕶎š—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" - -#, c-format msgid "E1403: Type alias \"%s\" cannot be used as a value" msgstr "E1403: Œ^ƒGƒCƒŠƒAƒX \"%s\" ‚ð’l‚Æ‚µ‚ÄŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ" @@ -8647,9 +8636,6 @@ msgstr "E1404: abstract ‚ðƒCƒ“ƒ^[ƒtƒFƒCƒX“à‚ÅŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ" msgid "E1405: Class \"%s\" cannot be used as a value" msgstr "E1405: ƒNƒ‰ƒX \"%s\" ‚ð’l‚Æ‚µ‚ÄŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ" -msgid "E1406: Cannot use a Class as a variable or value" -msgstr "E1406: ƒNƒ‰ƒX‚ð•Ï”‚â’l‚Æ‚µ‚ÄŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ" - msgid "E1407: Cannot use a Typealias as a variable or value" msgstr "E1407: Œ^ƒGƒCƒŠƒAƒX‚ð•Ï”‚â’l‚Æ‚µ‚ÄŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ" @@ -8665,6 +8651,76 @@ msgid "E1410: Const variable not supported in an interface" msgstr "E1410: ƒCƒ“ƒ^[ƒtƒFƒCƒX“à‚Å const •Ï”‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ" #, c-format +msgid "E1411: Missing dot after object \"%s\"" +msgstr "E1411: ƒIƒuƒWƒFƒNƒg \"%s\" ‚ÌŒã‚Ƀhƒbƒg‚ª‚ ‚è‚Ü‚¹‚ñ" + +#, c-format +msgid "E1412: Builtin object method \"%s\" not supported" +msgstr "E1412: ‘g‚Ýž‚݃IƒuƒWƒFƒNƒgƒƒ\\ƒbƒh \"%s\" ‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ" + +msgid "E1413: Builtin class method not supported" +msgstr "E1413: ‘g‚Ýž‚݃Nƒ‰ƒXƒƒ\\ƒbƒh‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ" + +msgid "E1414: Enum can only be defined in Vim9 script" +msgstr "E1414: —ñ‹“Œ^‚Í Vim9 script ‚Ì’†‚Å‚Ì‚Ý’è‹`‚Å‚«‚Ü‚·" + +#, c-format +msgid "E1415: Enum name must start with an uppercase letter: %s" +msgstr "E1415: —ñ‹“Œ^‚Ì–¼‘O‚͉p‘啶Žš‚ÅŽn‚Ü‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ: %s" + +msgid "E1416: Enum cannot extend a class or enum" +msgstr "E1416: —ñ‹“Œ^‚̓Nƒ‰ƒX‚â—ñ‹“Œ^‚ðŠg’£‚Å‚«‚Ü‚¹‚ñ" + +msgid "E1417: Abstract cannot be used in an Enum" +msgstr "E1417: abstract ‚ð—ñ‹“Œ^“à‚ÅŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ" + +#, c-format +msgid "E1418: Invalid enum value declaration: %s" +msgstr "E1418: •s³‚È—ñ‹“’l‚Ì錾‚Å‚·: %s" + +#, c-format +msgid "E1419: Not a valid command in an Enum: %s" +msgstr "E1419: —ñ‹“Œ^“à‚Å‚ÍŽg‚¦‚È‚¢ƒRƒ}ƒ“ƒh‚Å‚·: %s" + +msgid "E1420: Missing :endenum" +msgstr "E1420: :endenum ‚ª‚ ‚è‚Ü‚¹‚ñ" + +#, c-format +msgid "E1421: Enum \"%s\" cannot be used as a value" +msgstr "E1421: —ñ‹“Œ^ \"%s\" ‚ð’l‚Æ‚µ‚ÄŽg‚¤‚±‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ" + +#, c-format +msgid "E1422: Enum value \"%s\" not found in enum \"%s\"" +msgstr "E1422: —ñ‹“’l \"%s\" ‚ª—ñ‹“Œ^ \"%s\" “à‚ÅŒ©‚‚©‚è‚Ü‚¹‚ñ" + +#, c-format +msgid "E1423: Enum value \"%s.%s\" cannot be modified" +msgstr "E1423: —ñ‹“’l \"%s.%s\" ‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ" + +#, c-format +msgid "E1424: Using an Enum \"%s\" as a Number" +msgstr "E1424: —ñ‹“Œ^ \"%s\" ‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" + +#, c-format +msgid "E1425: Using an Enum \"%s\" as a String" +msgstr "E1425: —ñ‹“Œ^ \"%s\" ‚𕶎š—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·" + +#, c-format +msgid "E1426: Enum \"%s\" ordinal value cannot be modified" +msgstr "E1426: —ñ‹“Œ^ \"%s\" ‚̇˜’l‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ" + +#, c-format +msgid "E1427: Enum \"%s\" name cannot be modified" +msgstr "E1427: —ñ‹“Œ^ \"%s\" ‚Ì–¼‘O‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ" + +#, c-format +msgid "E1428: Duplicate enum value: %s" +msgstr "E1428: —ñ‹“’l‚ªd•¡‚µ‚Ä‚¢‚Ü‚·: %s" + +msgid "E1429: Class can only be used in a script" +msgstr "E1429: ƒNƒ‰ƒX‚̓XƒNƒŠƒvƒg‚Ì’†‚Å‚Ì‚ÝŽg—p‚Å‚«‚Ü‚·" + +#, c-format msgid "E1500: Cannot mix positional and non-positional arguments: %s" msgstr "E1500: ˆÊ’uˆø”‚Æ”ñˆÊ’uˆø”‚𬂺‚邱‚Æ‚Í‚Å‚«‚Ü‚¹‚ñ: %s" @@ -8708,6 +8764,17 @@ msgstr "E1509: Šg’£‘®«‚Ì“Çž‚Ý‚Ü‚½‚Í‘ž‚݂ŃGƒ‰[‚ª‹N‚«‚Ü‚µ‚½" msgid "E1510: Value too large: %s" msgstr "E1510: ’l‚ª‘å‚«‰ß‚¬‚Ü‚·: %s" +#, c-format +msgid "E1511: Wrong number of characters for field \"%s\"" +msgstr "E1511: ƒtƒB[ƒ‹ƒh \"%s\" ‚Ì•¶Žš”‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·" + +#, c-format +msgid "E1512: Wrong character width for field \"%s\"" +msgstr "E1512: ƒtƒB[ƒ‹ƒh \"%s\" ‚Ì•¶Žš•‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·" + +msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled" +msgstr "E1513: ƒoƒbƒtƒ@‚ðØ‚è‘Ö‚¦‚ç‚ê‚Ü‚¹‚ñB'winfixbuf' ‚ª—LŒø‰»‚³‚ê‚Ä‚¢‚Ü‚·" + msgid "--No lines in buffer--" msgstr "--ƒoƒbƒtƒ@‚És‚ª‚ ‚è‚Ü‚¹‚ñ--" @@ -9096,7 +9163,7 @@ msgid "\" Hit <Enter> on an index line to jump there." msgstr "\" ƒCƒ“ƒfƒbƒNƒXs‚Å <Enter> ‚ð‘ł‚ÆA‚»‚±‚ɃWƒƒƒ“ƒv‚µ‚Ü‚·B" msgid "\" Hit <Space> on a \"set\" line to refresh it." -msgstr "\" \"set\" s‚Å <Spece> ‚ð‘ł‚ÆAÅV‚Ì’l‚ª“Çž‚Ü‚ê‚Ü‚·B" +msgstr "\" \"set\" s‚Å <Space> ‚ð‘ł‚ÆAÅV‚Ì’l‚ª“Çž‚Ü‚ê‚Ü‚·B" msgid "important" msgstr "d—v" @@ -9415,6 +9482,9 @@ msgstr "Œ»Ý‚̃EƒBƒ“ƒhƒE‚ÉŽg‚í‚ê‚éŬs”" msgid "minimal number of lines used for any window" msgstr "”CˆÓ‚̃EƒBƒ“ƒhƒE‚ÉŽg‚í‚ê‚éŬs”" +msgid "keep window focused on a single buffer" +msgstr "ƒEƒBƒ“ƒhƒE‚ª•Ê‚̃oƒbƒtƒ@‚ÉØ‚è‘Ö‚í‚ç‚È‚¢‚悤‚É‚·‚é" + msgid "keep the height of the window" msgstr "ƒEƒBƒ“ƒhƒE‚Ì‚‚³‚ð•Û‚Â" @@ -9490,6 +9560,9 @@ msgstr "•¡”ƒ^ƒuƒy[ƒW" msgid "0, 1 or 2; when to use a tab pages line" msgstr "0, 1 ‚Ü‚½‚Í 2; ƒ^ƒuƒy[ƒWs‚ð‚¢‚ÂŽg‚¤‚©" +msgid "behaviour when closing tab pages: left, uselast or empty" +msgstr "ƒ^ƒuƒy[ƒW‚ð•Â‚¶‚é‚Æ‚«‚Ì‹““®: left, uselast ‚Ü‚½‚Í empty" + msgid "maximum number of tab pages to open for -p and \"tab all\"" msgstr "-p ‚Æ \"tab all\" ‚ÅŠJ‚©‚ê‚éƒ^ƒuƒy[ƒW‚ÌÅ‘å”" diff --git a/src/po/ko.UTF-8.po b/src/po/ko.UTF-8.po index a9ee0ca..f7714ae 100644 --- a/src/po/ko.UTF-8.po +++ b/src/po/ko.UTF-8.po @@ -411,8 +411,8 @@ msgstr " ì‚¬ìš©ìž ì •ì˜ ì™„ì„± (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni 완성 (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " 단어 ì œì•ˆ (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " 단어 ì œì•ˆ (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ë‚±ë§ ë¡œì»¬ 완성 (^N^P)" diff --git a/src/po/ko.po b/src/po/ko.po index 00fb486..2b3c785 100644 --- a/src/po/ko.po +++ b/src/po/ko.po @@ -1,8 +1,8 @@ -# Generated from ko.UTF-8.po, DO NOT EDIT +# Korean translation for Vim # # FIRST AUTHOR SungHyun Nam <goweol@gmail.com>, 2000-2018 # -# Original translations. +# Generated from ko.UTF-8.po, DO NOT EDIT. # msgid "" msgstr "" @@ -14,7 +14,7 @@ msgstr "" "Language-Team: Korean\n" "Language: ko\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=euc-kr\n" +"Content-Type: text/plain; charset=EUC-KR\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" @@ -411,8 +411,8 @@ msgstr " »ç¿ëÀÚ Á¤ÀÇ ¿Ï¼º (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni ¿Ï¼º (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " ´Ü¾î Á¦¾È (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " ´Ü¾î Á¦¾È (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ³¹¸» ·ÎÄà ¿Ï¼º (^N^P)" diff --git a/src/po/nb.po b/src/po/nb.po index d9f527b..957b99d 100644 --- a/src/po/nb.po +++ b/src/po/nb.po @@ -283,9 +283,8 @@ msgstr " Brukerdefinert fullføring (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni-fullføring (^O^N^P)" -#, fuzzy -#~ msgid " Spelling suggestion (s^N^P)" -#~ msgstr " Staveforslag (^S^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Staveforslag (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokal nøkkelordfullføring (^N^P)" diff --git a/src/po/nl.po b/src/po/nl.po index 09f281b..6ac59ca 100644 --- a/src/po/nl.po +++ b/src/po/nl.po @@ -287,8 +287,8 @@ msgstr " gebruikergedefinieerde voltooiing (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " omni-voltooiing (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " spellingsuggestie (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " spellingsuggestie (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " lokaal-trefwoordvoltooiing (^N^P)" diff --git a/src/po/no.po b/src/po/no.po index d9f527b..957b99d 100644 --- a/src/po/no.po +++ b/src/po/no.po @@ -283,9 +283,8 @@ msgstr " Brukerdefinert fullføring (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni-fullføring (^O^N^P)" -#, fuzzy -#~ msgid " Spelling suggestion (s^N^P)" -#~ msgstr " Staveforslag (^S^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Staveforslag (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokal nøkkelordfullføring (^N^P)" diff --git a/src/po/pl.UTF-8.po b/src/po/pl.UTF-8.po index c9036a3..39064f6 100644 --- a/src/po/pl.UTF-8.po +++ b/src/po/pl.UTF-8.po @@ -298,8 +298,8 @@ msgstr "DopeÅ‚nianie zdefiniowane przez użytkownika (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni uzupeÅ‚nianie (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr "Propozycja pisowni (^L^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr "Propozycja pisowni (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokalne dopeÅ‚nianie słów kluczowych (^N^P)" diff --git a/src/po/pl.cp1250.po b/src/po/pl.cp1250.po index 9280d2f..6f9b66d 100644 --- a/src/po/pl.cp1250.po +++ b/src/po/pl.cp1250.po @@ -17,7 +17,7 @@ msgstr "" "Language-Team: Polish\n" "Language: pl\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=cp1250\n" +"Content-Type: text/plain; charset=CP1250\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " @@ -298,8 +298,8 @@ msgstr "Dope³nianie zdefiniowane przez u¿ytkownika (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni uzupe³nianie (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr "Propozycja pisowni (^L^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr "Propozycja pisowni (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokalne dope³nianie s³ów kluczowych (^N^P)" diff --git a/src/po/pl.po b/src/po/pl.po index f10897d..aebc33f 100644 --- a/src/po/pl.po +++ b/src/po/pl.po @@ -298,8 +298,8 @@ msgstr "Dope³nianie zdefiniowane przez u¿ytkownika (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni uzupe³nianie (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr "Propozycja pisowni (^L^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr "Propozycja pisowni (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokalne dope³nianie s³ów kluczowych (^N^P)" diff --git a/src/po/pt_BR.po b/src/po/pt_BR.po index 3a8844a..1cf15b5 100644 --- a/src/po/pt_BR.po +++ b/src/po/pt_BR.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: Vim 8.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-09-10 11:11-0300\n" -"PO-Revision-Date: 2017-09-10 11:12-0300\n" +"PO-Revision-Date: 2024-08-23 18:04+0200\n" "Last-Translator: Eduardo S. Dobay <edudobay@gmail.com>\n" "Language-Team: Brazilian Portuguese\n" "Language: pt_BR\n" @@ -226,20 +226,20 @@ msgstr "E898: socket() em channel_open()" # TODO: Capitalise first word of message? msgid "E903: Received command with non-string argument" -msgstr "E903: comando recebido com argumento não-string" +msgstr "E903: Comando recebido com argumento não-string" # TODO: Capitalise first word of message? msgid "E904: Last argument for expr/call must be a number" -msgstr "E904: último argumento para expr/call deve ser numérico" +msgstr "E904: Último argumento para expr/call deve ser numérico" # TODO: Capitalise first word of message? msgid "E904: Third argument for call must be a list" -msgstr "E904: terceiro argumento para call deve ser uma lista" +msgstr "E904: Terceiro argumento para call deve ser uma lista" #, c-format # TODO: Capitalise first word of message? msgid "E905: Received unknown command: %s" -msgstr "E905: comando desconhecido recebido: %s" +msgstr "E905: Comando desconhecido recebido: %s" #, c-format # TODO: Capitalise first word of message? @@ -273,7 +273,7 @@ msgstr "E915: buffer in_io requer definição de in_buf ou in_name" #, c-format # TODO: Capitalise first word of message? msgid "E918: Buffer must be loaded: %s" -msgstr "E918: buffer precisa ser carregado: %s" +msgstr "E918: Buffer precisa ser carregado: %s" msgid "E821: File is encrypted with unknown method" msgstr "E821: Arquivo criptografado com método desconhecido" @@ -406,8 +406,8 @@ msgstr " Completar definido pelo usuário (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Completação inteligente (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Sugestão de ortografia (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Sugestão de ortografia (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Completar palavra-chave local (^N^P)" @@ -536,7 +536,7 @@ msgstr "E940: ImpossÃvel travar ou destravar variável %s" # TODO: Capitalise first word of message? msgid "E743: Variable nested too deep for (un)lock" -msgstr "E743: variável aninhada demais para (des)bloquear" +msgstr "E743: Variável aninhada demais para (des)bloquear" msgid "E109: Missing ':' after '?'" msgstr "E109: ':' faltando depois de '?'" @@ -590,7 +590,7 @@ msgstr "" # TODO: Capitalise first word of message? msgid "E724: Variable nested too deep for displaying" -msgstr "E724: variável aninhada demais para ser exibida" +msgstr "E724: Variável aninhada demais para ser exibida" msgid "E805: Using a Float as a Number" msgstr "E805: Float usado como Número" @@ -669,7 +669,7 @@ msgstr "E742: Não é possÃvel mudar valor de %s" # TODO: Capitalise first word of message? msgid "E698: Variable nested too deep for making a copy" -msgstr "E698: variável aninhada demais para fazer uma cópia" +msgstr "E698: Variável aninhada demais para fazer uma cópia" msgid "" "\n" @@ -739,7 +739,7 @@ msgstr "E786: Intervalos não são permitidos" # TODO: Capitalise first word of message? msgid "E916: Not a valid job" -msgstr "E916: não é um trabalho válido" +msgstr "E916: Não é um trabalho válido" msgid "E701: Invalid type for len()" msgstr "E701: Tipo inválido para len()" @@ -808,7 +808,7 @@ msgstr "(Inválido)" #, c-format # TODO: Capitalise first word of message? msgid "E935: Invalid submatch number: %d" -msgstr "E935: número inválido para subpadrão: %d" +msgstr "E935: Número inválido para subpadrão: %d" msgid "E677: Error writing temp file" msgstr "E677: Erro ao gravar o arquivo temporário" @@ -1107,7 +1107,7 @@ msgstr "E157: ID de sinal inválido: %ld" #, c-format msgid "E885: Not possible to change sign %s" -msgstr "E885: Não é possÃvel mudar o sinal %s" +msgstr "E885: Não é possÃvel alterar o sinal %s" msgid " (NOT FOUND)" msgstr " (NÃO ENCONTRADO)" @@ -1184,7 +1184,7 @@ msgstr "E165: ImpossÃvel ir além do último arquivo" #, c-format # TODO: Capitalise first word of message? msgid "E666: Compiler not supported: %s" -msgstr "E666: compilador não suportado: %s" +msgstr "E666: Compilador não suportado: %s" #, c-format msgid "Searching for \"%s\" in \"%s\"" @@ -1409,6 +1409,9 @@ msgstr "E784: Não é possÃvel fechar a última aba" msgid "Already only one tab page" msgstr "Já há apenas uma aba" +msgid "Edit File in new tab page" +msgstr "Editar arquivo na nova aba" + msgid "Edit File in new window" msgstr "Editar arquivo em nova janela" @@ -1653,7 +1656,7 @@ msgstr "" "# Histórico de %s (mais recente primeiro):\n" msgid "Command Line" -msgstr "linha de comando" +msgstr "Linha de comando" msgid "Search String" msgstr "expressões de busca" @@ -1725,7 +1728,7 @@ msgid "[socket]" msgstr "[socket]" msgid "[character special]" -msgstr "[dispositivo de caractere]" +msgstr "[caractere especial]" msgid "[CR missing]" msgstr "[CR faltando]" @@ -1838,7 +1841,7 @@ msgstr " ERRO DE CONVERSÃO" #, c-format msgid " in line %ld;" -msgstr "na linha %ld;" +msgstr " na linha %ld;" msgid "[Device]" msgstr "[Dispositivo]" diff --git a/src/po/ru.cp1251.po b/src/po/ru.cp1251.po index 05d10e0..d598cbf 100644 --- a/src/po/ru.cp1251.po +++ b/src/po/ru.cp1251.po @@ -475,8 +475,7 @@ msgstr "" # :!~ Restorer #, c-format msgid "xchacha20v2: using custom algorithm \"%d\" for Key derivation." -msgstr "" -"XChaCha20v2: äëÿ ïîëó÷åíèÿ êëþ÷à ïðèìåí¸í íåñòàíäàðòíûé àëãîðèòì \"%d\"" +msgstr "XChaCha20v2: äëÿ ïîëó÷åíèÿ êëþ÷à ïðèìåí¸í íåñòàíäàðòíûé àëãîðèòì \"%d\"" # #Restorer: âûâîäèòñÿ ïðè çíà÷åíèè 'verbose'>0 # :!~ Restorer @@ -722,8 +721,7 @@ msgstr "" # :!~ Restorer msgid "called inputrestore() more often than inputsave()" msgstr "" -"Êîëè÷åñòâî âûçîâîâ ôóíêöèè inputrestore() ïðåâûøàåò âûçîâû ôóíêöèè " -"inputsave()" +"Êîëè÷åñòâî âûçîâîâ ôóíêöèè inputrestore() ïðåâûøàåò âûçîâû ôóíêöèè inputsave()" # #Restorer: íàïðèìåð, êîìàíäà `:ascii` è `ga` # #Restorer: åñëè ïîäêëþ÷åí êîìïîíåíò +digraphs è äëÿ ñèìâîëà åñòü äèãðàô @@ -1243,8 +1241,7 @@ msgstr "[íåò ñèìâîëà çàâåðøåíèÿ ñòðîêè]" msgid "" "W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as " "well" -msgstr "" -"W12: Âíèìàíèå! Íå ñâÿçàííûå èçìåíåíèÿ ñîäåðæèìîãî áóôåðà è ôàéëà \"%s\"" +msgstr "W12: Âíèìàíèå! Íå ñâÿçàííûå èçìåíåíèÿ ñîäåðæèìîãî áóôåðà è ôàéëà \"%s\"" # :!~ Restorer msgid "See \":help W12\" for more info." @@ -1264,8 +1261,7 @@ msgstr "×òîáû ïîëó÷èòü äîïîëíèòåëüíóþ èíôîðìàöèþ, íàáåðèòå `:help W11`" #, c-format msgid "W16: Warning: Mode of file \"%s\" has changed since editing started" msgstr "" -"W16: Âíèìàíèå! Ïîñëå ñ÷èòûâàíèÿ â áóôåð, èçìåíåíû ïðàâà äîñòóïà ê ôàéëó " -"\"%s\"" +"W16: Âíèìàíèå! Ïîñëå ñ÷èòûâàíèÿ â áóôåð, èçìåíåíû ïðàâà äîñòóïà ê ôàéëó \"%s\"" # :!~ Restorer msgid "See \":help W16\" for more info." @@ -1958,12 +1954,10 @@ msgstr "âûïîëíåíèå ïðåðâàíî ïîëüçîâàòåëåì" # :!~ Restorer msgid "cannot create buffer/window command: object is being deleted" msgstr "" -"îáúåêò áóôåðà èëè îêíà â ïðîöåññå óäàëåíèÿ. Íå óäàëîñü ñîçäàòü äëÿ íèõ " -"êîìàíäó" +"îáúåêò áóôåðà èëè îêíà â ïðîöåññå óäàëåíèÿ. Íå óäàëîñü ñîçäàòü äëÿ íèõ êîìàíäó" # :!~ Restorer -msgid "" -"cannot register callback command: buffer/window is already being deleted" +msgid "cannot register callback command: buffer/window is already being deleted" msgstr "" "îáúåêò áóôåðà èëè îêíà â ïðîöåññå óäàëåíèÿ. Íå óäàëîñü çàðåãèñòðèðîâàòü " "êîìàíäó" @@ -2045,7 +2039,7 @@ msgid " Omni completion (^O^N^P)" msgstr " Ïîäñòàíîâêà ïî êîíòåêñòó CTRL+O è CTRL+N èëè CTRL+P" # :!~ Restorer -msgid " Spelling suggestion (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" msgstr " Ïîäñòàíîâêà âàðèàíòîâ íàïèñàíèÿ CTRL+S è CTRL+N èëè CTRL+P" # :!~ Restorer @@ -2248,8 +2242,7 @@ msgstr "" # :!~ Restorer msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n" -msgstr "" -"Ïðîãðàììà Vim. Äàííàÿ âåðñèÿ ïðîãðàììû íå ðàáîòàåò â òåðìèíàëå Cygwin\n" +msgstr "Ïðîãðàììà Vim. Äàííàÿ âåðñèÿ ïðîãðàììû íå ðàáîòàåò â òåðìèíàëå Cygwin\n" # :!~ Restorer msgid "Vim: Warning: Output is not to a terminal\n" @@ -2481,8 +2474,7 @@ msgstr "--not-a-term\t\tÍå ñîîáùàòü îá îòñóòñòâèè òåðìèíàëà äëÿ ââîäà-âûâîäà" # :!~ Restorer msgid "--gui-dialog-file {fname} For testing: write dialog text" -msgstr "" -"--gui-dialog-file {ôàéë} Çàïèñü ñîîáùåíèé äèàëîãîâûõ îêîí. Äëÿ îòëàäêè" +msgstr "--gui-dialog-file {ôàéë} Çàïèñü ñîîáùåíèé äèàëîãîâûõ îêîí. Äëÿ îòëàäêè" # :!~ Restorer msgid "--ttyfail\t\tExit if input or output is not a terminal" @@ -2564,13 +2556,11 @@ msgstr "-X\t\t\tÇàïóñê ïðîãðàììû áåç ïîäêëþ÷åíèÿ ê X-ñåðâåðó" # :!~ Restorer msgid "--remote <files>\tEdit <files> in a Vim server if possible" -msgstr "" -"--remote <ôàéëû>\tÐåäàêòèðîâàíèå <ôàéëîâ> íà Vim-ñåðâåðå, åñëè äîñòóïåí" +msgstr "--remote <ôàéëû>\tÐåäàêòèðîâàíèå <ôàéëîâ> íà Vim-ñåðâåðå, åñëè äîñòóïåí" # :!~ Restorer msgid "--remote-silent <files> Same, don't complain if there is no server" -msgstr "" -"--remote-silent <ôàéëû> Òî æå, íî íå ñîîáùàòü î íåäîñòóïíîñòè ñåðâåðà" +msgstr "--remote-silent <ôàéëû> Òî æå, íî íå ñîîáùàòü î íåäîñòóïíîñòè ñåðâåðà" # #Restorer: äîáàâèë ïàðó ïðîáåëüíûõ ñèìâîëîâ, äàáû ïîäðàâíÿòü ñîîáùåíèå # ~!: earlier @@ -2580,8 +2570,7 @@ msgstr "" "--remote-wait <ôàéëû> Òî æå, ÷òî è --remote, íî ñ îæèäàíèåì çàâåðøåíèÿ" # :!~ Restorer -msgid "" -"--remote-wait-silent <files> Same, don't complain if there is no server" +msgid "--remote-wait-silent <files> Same, don't complain if there is no server" msgstr "" "--remote-wait-silent <ôàéëû> Òî æå, íî íå ñîîáùàòü î íåäîñòóïíîñòè ñåðâåðà" @@ -2614,8 +2603,7 @@ msgstr "--startuptime <ôàéë>\tÇàïèñàòü õðîíîìåòðàæ çàïóñêà ïðîãðàììû â <ôàéë>" # :!~ Restorer msgid "--log <file>\t\tStart logging to <file> early" -msgstr "" -"--log <ôàéë>\t\tÇàïèñü ïðîòîêîëà ðàáîòû ñ ýòàïà èíèöèàëèçàöèè ïðîãðàììû" +msgstr "--log <ôàéë>\t\tÇàïèñü ïðîòîêîëà ðàáîòû ñ ýòàïà èíèöèàëèçàöèè ïðîãðàììû" # :!~ Restorer msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo" @@ -2715,8 +2703,7 @@ msgstr "" # :!~ Restorer msgid "--role <role>\tSet a unique role to identify the main window" -msgstr "" -"--role <ðîëü>\tÇàäàòü óíèêàëüíóþ <ðîëü> ãëàâíîãî îêíà äëÿ èäåíòèôèêàöèè" +msgstr "--role <ðîëü>\tÇàäàòü óíèêàëüíóþ <ðîëü> ãëàâíîãî îêíà äëÿ èäåíòèôèêàöèè" # :!~ Restorer msgid "--socketid <xid>\tOpen Vim inside another GTK widget" @@ -2841,8 +2828,7 @@ msgstr "Äëÿ âîññòàíîâëåíèÿ ýòîãî ôàéëà, èñïîëüçóéòå ïðîãðàììó Vim âåðñèè 3.0\n" # :!~ Restorer msgid " cannot be used on this computer.\n" -msgstr "" -" íåñîâìåñòèì ñ ïðîãðàììíî-àïïàðàòíîé àðõèòåêòóðîé äàííîãî êîìïüþòåðà.\n" +msgstr " íåñîâìåñòèì ñ ïðîãðàììíî-àïïàðàòíîé àðõèòåêòóðîé äàííîãî êîìïüþòåðà.\n" # ~!: earlier msgid "The file was created on " @@ -3098,8 +3084,7 @@ msgid "" " [not usable on this computer]" msgstr "" "\n" -" [íåñîâìåñòèì ñ ïðîãðàììíî-àïïàðàòíîé àðõèòåêòóðîé äàííîãî " -"êîìïüþòåðà]" +" [íåñîâìåñòèì ñ ïðîãðàììíî-àïïàðàòíîé àðõèòåêòóðîé äàííîãî êîìïüþòåðà]" # :!~ Restorer msgid " [cannot be read]" @@ -3169,8 +3154,7 @@ msgstr "" "(1) Âîçìîæíî, ðåäàêòèðîâàíèå ýòîãî æå ôàéëà âûïîëíÿåòñÿ â äðóãîé ïðîãðàììå\n" " íà ýòîì æå êîìïüþòåðå èëè ïî ñåòåâîìó ïîäêëþ÷åíèþ.\n" "\n" -" ýòîì ñëó÷àå ëó÷øå íå ðåäàêòèðîâàòü ýòîò ôàéë èëè äåëàòü ýòî " -"îñìîòðèòåëüíî,\n" +" ýòîì ñëó÷àå ëó÷øå íå ðåäàêòèðîâàòü ýòîò ôàéë èëè äåëàòü ýòî îñìîòðèòåëüíî,\n" "÷òîáû íå ïîÿâèëîñü äâà âàðèàíòà îäíîãî è òîãî æå ôàéëà.\n" "Áóäüòå âíèìàòåëüíû è åù¸ ðàç âñ¸ ïðîâåðüòå.\n" "\n" @@ -3495,8 +3479,8 @@ msgid "" "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte " "%lld of %lld" msgstr "" -"Êîëîíêà %s èç %s; ñòðîêà %ld èç %ld; ñëîâî %lld èç %lld; ëèòåðà %lld èç " -"%lld; áàéò %lld èç %lld" +"Êîëîíêà %s èç %s; ñòðîêà %ld èç %ld; ñëîâî %lld èç %lld; ëèòåðà %lld èç %lld; " +"áàéò %lld èç %lld" # #Restorer: äîáàâëÿåòñÿ ê ñîîáùåíèþ î ïîçèöèè êàðåòêè èç ïðåäûäóùèõ msgid # #Restorer: âñòàâèë ïðîáåë ïåðåä ñêîáêîé, ïîñìîòðèì, êàê áóäåò âûãëÿäåòü @@ -3509,8 +3493,7 @@ msgstr " (+%lld ñ ó÷¸òîì ÌÏÁ)" # :!~ Restorer msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'" msgstr "" -"W17: Äëÿ ðàáîòû ñ àðàáñêîé ïèñüìåííîñòüþ ââåäèòå êîìàíäó `:set " -"encoding=utf-8`" +"W17: Äëÿ ðàáîòû ñ àðàáñêîé ïèñüìåííîñòüþ ââåäèòå êîìàíäó `:set encoding=utf-8`" # #Restorer: âûâîäèòñÿ ïî êîìàíäå `:set termcap` # :!~ Restorer @@ -3559,8 +3542,7 @@ msgstr "Ïðîãðàììà VIM. Íå óäàëîñü îòîáðàçèòü îêíî íà ýêðàíå!\n" # :!~ Restorer msgid "Need Amigados version 2.04 or later\n" -msgstr "" -"Òðåáóåòñÿ îïåðàöèîííàÿ ñèñòåìà Amigados âåðñèè 2.04 èëè áîëåå ïîçäíåé\n" +msgstr "Òðåáóåòñÿ îïåðàöèîííàÿ ñèñòåìà Amigados âåðñèè 2.04 èëè áîëåå ïîçäíåé\n" # :!~ Restorer #, c-format @@ -3858,8 +3840,7 @@ msgstr "Íå óäàëîñü îòêðûòü ôàéë \"%s\"" # :!~ Restorer msgid "cannot have both a list and a \"what\" argument" msgstr "" -"â ôóíêöèè setqflist(). Äîëæåí áûòü óêàçàí ëèáî ïåðâûé, ëèáî ïîñëåäíèé " -"àðãóìåíò" +"â ôóíêöèè setqflist(). Äîëæåí áûòü óêàçàí ëèáî ïåðâûé, ëèáî ïîñëåäíèé àðãóìåíò" # #Restorer: âûâîäèòñÿ ïðè 'verbose'>0 # :!~ Restorer @@ -4308,8 +4289,7 @@ msgstr " ôàéëå %s íà ñòðîêå %d íåäîïóñòèìîå çíà÷åíèå ïðàâèëà COMPOUNDMIN %s" # :!~ Restorer #, c-format msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s" -msgstr "" -" ôàéëå %s íà ñòðîêå %d íåäîïóñòèìîå çíà÷åíèå ïðàâèëà COMPOUNDSYLMAX %s" +msgstr " ôàéëå %s íà ñòðîêå %d íåäîïóñòèìîå çíà÷åíèå ïðàâèëà COMPOUNDSYLMAX %s" # :!~ Restorer #, c-format @@ -4321,8 +4301,7 @@ msgstr "" #, c-format msgid "Different combining flag in continued affix block in %s line %d: %s" msgstr "" -" ôàéëå %s íà ñòðîêå %d íåäîïóñòèìûé ïðèçíàê êîìáèíèðîâàíèÿ áëîêîâ àôôèêñîâ " -"%s" +" ôàéëå %s íà ñòðîêå %d íåäîïóñòèìûé ïðèçíàê êîìáèíèðîâàíèÿ áëîêîâ àôôèêñîâ %s" # :!~ Restorer #, c-format @@ -4351,8 +4330,7 @@ msgstr " ôàéëå %s íà ñòðîêå %d íåäîïóñòèìîå äëÿ âûïîëíåíèÿ ïîèñêà óñëîâèå %s" # :!~ Restorer #, c-format msgid "Expected REP(SAL) count in %s line %d" -msgstr "" -" ôàéëå %s íà ñòðîêå %d äëÿ ïðàâèë REP èëè REPSAL íå óêàçàíî êîëè÷åñòâî" +msgstr " ôàéëå %s íà ñòðîêå %d äëÿ ïðàâèë REP èëè REPSAL íå óêàçàíî êîëè÷åñòâî" # :!~ Restorer #, c-format @@ -4539,8 +4517,7 @@ msgstr "Îöåíêà èñïîëüçîâàíèÿ ïàìÿòè ïðè âûïîëíåíèè: %d áàéò" # :!~ Restorer msgid "Warning: both compounding and NOBREAK specified" -msgstr "" -"Âíèìàíèå! Óêàçàíû êàê ïðàâèëà äëÿ ñîñòàâíûõ ñëîâ, òàê è ïðàâèëî NOBREAK" +msgstr "Âíèìàíèå! Óêàçàíû êàê ïðàâèëà äëÿ ñîñòàâíûõ ñëîâ, òàê è ïðàâèëî NOBREAK" # :!~ Restorer #, c-format @@ -5307,32 +5284,28 @@ msgstr "Íåñ÷àñòíûì äåòÿì Óãàíäû òðåáóåòñÿ âàøà ïîìîùü!" # :!~ Restorer msgid "type :help iccf<Enter> for information " msgstr "" -"íàáåðèòå :help iccf<ENTER> ÷òîáû óçíàòü îá ýòîì " -"ïîäðîáíåå " +"íàáåðèòå :help iccf<ENTER> ÷òîáû óçíàòü îá ýòîì ïîäðîáíåå " # #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé # #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ # :!~ Restorer msgid "type :q<Enter> to exit " msgstr "" -"íàáåðèòå :q<ENTER> ÷òîáû çàâåðøèòü ðàáîòó ñ " -"ïðîãðàììîé " +"íàáåðèòå :q<ENTER> ÷òîáû çàâåðøèòü ðàáîòó ñ ïðîãðàììîé " # #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé # #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ # :!~ Restorer msgid "type :help<Enter> or <F1> for on-line help" msgstr "" -"íàáåðèòå :help<ENTER> èëè íàæìèòå <F1> ÷òîáû îçíàêîìèòüñÿ ñ " -"äîêóìåíòàöèåé " +"íàáåðèòå :help<ENTER> èëè íàæìèòå <F1> ÷òîáû îçíàêîìèòüñÿ ñ äîêóìåíòàöèåé " # #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé # #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ # :!~ Restorer msgid "type :help version9<Enter> for version info" msgstr "" -"íàáåðèòå :help version9<ENTER> ÷òîáû óçíàòü ïîäðîáíåå îá ýòîé " -"âåðñèè" +"íàáåðèòå :help version9<ENTER> ÷òîáû óçíàòü ïîäðîáíåå îá ýòîé âåðñèè" # :!~ Restorer msgid "Running in Vi compatible mode" @@ -5343,61 +5316,53 @@ msgstr "Ïðîãðàììà ðàáîòàåò â ðåæèìå ñîâìåñòèìîñòè ñ ðåäàêòîðîì Vi" # :!~ Restorer msgid "type :set nocp<Enter> for Vim defaults" msgstr "" -"íàáåðèòå :set nocp<ENTER> ÷òîáû àêòèâèðîâàòü âîçìîæíîñòè " -"Vim " +"íàáåðèòå :set nocp<ENTER> ÷òîáû àêòèâèðîâàòü âîçìîæíîñòè Vim " # #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé # #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ # :!~ Restorer msgid "type :help cp-default<Enter> for info on this" msgstr "" -"íàáåðèòå :help cp-default<ENTER> ÷òîáû óçíàòü îá ýòîì " -"ïîäðîáíåå " +"íàáåðèòå :help cp-default<ENTER> ÷òîáû óçíàòü îá ýòîì ïîäðîáíåå " # #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé # #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ # :!~ Restorer msgid "menu Help->Orphans for information " msgstr "" -"ìåíþ Ñïðàâêà->Áëàãîòâîðèòåëüíîñòü ÷òîáû óçíàòü îá ýòîì " -"ïîäðîáíåå" +"ìåíþ Ñïðàâêà->Áëàãîòâîðèòåëüíîñòü ÷òîáû óçíàòü îá ýòîì ïîäðîáíåå" # #Restorer: âûâîäèòñÿ òîëüêî â ÃÈÏ ïðè çàïóñêå gVim Easy # :!~ Restorer msgid "Running modeless, typed text is inserted" msgstr "" -"Óïðîù¸ííûé âàðèàíò. Âñ¸ ÷òî íàáèðàåòñÿ, ñ÷èòàåòñÿ òåêñòîì è ïîìåùàåòñÿ â " -"áóôåð" +"Óïðîù¸ííûé âàðèàíò. Âñ¸ ÷òî íàáèðàåòñÿ, ñ÷èòàåòñÿ òåêñòîì è ïîìåùàåòñÿ â áóôåð" # #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé # #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ # :!~ Restorer msgid "menu Edit->Global Settings->Toggle Insert Mode " msgstr "" -"ìåíþ Ïðàâêà->Îáùèå ïàðàìåòðû->Ðåæèì âñòàâêè ÷òîáû ïåðåêëþ÷àòü " -"èç " +"ìåíþ Ïðàâêà->Îáùèå ïàðàìåòðû->Ðåæèì âñòàâêè ÷òîáû ïåðåêëþ÷àòü èç " # #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé # :!~ Restorer msgid " for two modes " msgstr "" -" ðåæèìà âñòàâêè â ðåæèì " -"êîìàíä" +" ðåæèìà âñòàâêè â ðåæèì êîìàíä" # #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé # #Restorer: âûðàâíèâàåòñÿ ïî ñàìîìó äëèííîìó ïîäîáíîìó ñîîáùåíèþ # :!~ Restorer msgid "menu Edit->Global Settings->Toggle Vi Compatible" msgstr "" -"ìåíþ Ïðàâêà->Îáùèå ïàðàìåòðû->Ñîâìåñòèìîñòü ñ Vi ÷òîáû " -"àêòèâèðîâàòü " +"ìåíþ Ïðàâêà->Îáùèå ïàðàìåòðû->Ñîâìåñòèìîñòü ñ Vi ÷òîáû àêòèâèðîâàòü " # #Restorer: ïðîáåëû íå óáèðàòü, ñäåëàíî äëÿ âûðàâíèâàíèÿ ñîîáùåíèé # :!~ Restorer msgid " for Vim defaults " msgstr "" -" âîçìîæíîñòè ðåäàêòîðà " -"Vim " +" âîçìîæíîñòè ðåäàêòîðà Vim " # :!~ Restorer msgid "Sponsor Vim development!" @@ -5426,8 +5391,7 @@ msgstr "" # :!~ Restorer msgid "menu Help->Sponsor/Register for information " msgstr "" -"ìåíþ Ñïðàâêà->Ñîäåéñòâèå è ðåãèñòðàöèÿ ÷òîáû óçíàòü îá ýòîì " -"ïîäðîáíåå" +"ìåíþ Ñïðàâêà->Ñîäåéñòâèå è ðåãèñòðàöèÿ ÷òîáû óçíàòü îá ýòîì ïîäðîáíåå" # #Restorer: ïîäñòàâëÿåòñÿ â «E1016: Cannot declare a %s variable: %s» êàê # #Restorer: ïåðâàÿ %s. Ìîæåò ëó÷øå íå ïåðåâîäèòü? Ïîêà ñäåëàë. Âûãëÿäèò òàê @@ -6120,8 +6084,7 @@ msgstr "E108: Íå ñóùåñòâóåò ïåðåìåííîé \"%s\"" # :!~ Restorer msgid "E109: Missing ':' after '?'" -msgstr "" -"E109: Îòñóòñòâóåò ñèìâîë äâîåòî÷èÿ ':' â îïåðàòîðå ïðîâåðêè óñëîâèÿ `?`" +msgstr "E109: Îòñóòñòâóåò ñèìâîë äâîåòî÷èÿ ':' â îïåðàòîðå ïðîâåðêè óñëîâèÿ `?`" # :!~ Restorer msgid "E110: Missing ')'" @@ -6237,8 +6200,7 @@ msgstr "E131: Óäàëåíèå íå âûïîëíåíî. Ýòà ôóíêöèÿ ñåé÷àñ èñïîëüçóåòñÿ %s" # :!~ Restorer msgid "E132: Function call depth is higher than 'maxfuncdepth'" msgstr "" -"E132: Êîëè÷åñòâî âûçîâîâ ôóíêöèé ïðåâûøàåò çíà÷åíèå â ïàðàìåòðå " -"'maxfuncdepth'" +"E132: Êîëè÷åñòâî âûçîâîâ ôóíêöèé ïðåâûøàåò çíà÷åíèå â ïàðàìåòðå 'maxfuncdepth'" # :!~ Restorer msgid "E133: :return not inside a function" @@ -6258,8 +6220,7 @@ msgstr "" # :!~ Restorer msgid "E136: viminfo: Too many errors, skipping rest of file" msgstr "" -"E136: Îáíàðóæåíî ìíîæåñòâî îøèáîê â viminfo-ôàéëå. Ñ÷èòûâàíèå ôàéëà " -"ïðåêðàùåíî" +"E136: Îáíàðóæåíî ìíîæåñòâî îøèáîê â viminfo-ôàéëå. Ñ÷èòûâàíèå ôàéëà ïðåêðàùåíî" # :!~ Restorer #, c-format @@ -6565,8 +6526,7 @@ msgstr "E199: Óäàëåíèå èëè èçìåíåíèå òåêóùåãî îêíà èëè áóôåðà" # :!~ Restorer msgid "E200: *ReadPre autocommands made the file unreadable" msgstr "" -"E200:  ðåçóëüòàòå äåéñòâèé àâòîêîìàíä ïî ñîáûòèÿì *ReadPre ôàéë ñòàë " -"íå÷èòàåì" +"E200:  ðåçóëüòàòå äåéñòâèé àâòîêîìàíä ïî ñîáûòèÿì *ReadPre ôàéë ñòàë íå÷èòàåì" # :!~ Restorer msgid "E201: *ReadPre autocommands must not change current buffer" @@ -6800,8 +6760,7 @@ msgstr "E250:  íàáîðå øðèôòîâ %s îòñóòñòâóþò øðèôòû ñî ñëåäóþùèìè ñèìâîëàìè:" # :!~ Restorer msgid "E251: VIM instance registry property is badly formed. Deleted!" msgstr "" -"E251: Óäàëåíî çàðåãèñòðèðîâàííîå ïðîãðàììîé Vim ñâîéñòâî íåäîïóñòèìîãî " -"ôîðìàòà" +"E251: Óäàëåíî çàðåãèñòðèðîâàííîå ïðîãðàììîé Vim ñâîéñòâî íåäîïóñòèìîãî ôîðìàòà" # :!~ Restorer #, c-format @@ -6853,11 +6812,9 @@ msgstr "E262: Îøèáêà ïðè ñ÷èòûâàíèè èç áàçû äàííûõ cscope íîìåð %d" # :!~ Restorer msgid "" -"E263: Sorry, this command is disabled, the Python library could not be " -"loaded." +"E263: Sorry, this command is disabled, the Python library could not be loaded." msgstr "" -"E263: Íå óäàëîñü ïîäêëþ÷èòü ôàéë áèáëèîòåêè ÿçûêà Python. Êîìàíäà íå " -"âûïîëíåíà" +"E263: Íå óäàëîñü ïîäêëþ÷èòü ôàéë áèáëèîòåêè ÿçûêà Python. Êîìàíäà íå âûïîëíåíà" # :!~ Restorer msgid "E264: Python: Error initialising I/O objects" @@ -6953,8 +6910,7 @@ msgstr "E286: Îøèáêà ïðè çàïóñêå ñëóæáû ìåòîäà ââîäà" # :!~ Restorer msgid "E287: Warning: Could not set destroy callback to IM" msgstr "" -"E287: Âíèìàíèå! Íå óäàëîñü íàçíà÷èòü ôóíêöèþ äëÿ îñòàíîâêè ñëóæáû ìåòîäà " -"ââîäà" +"E287: Âíèìàíèå! Íå óäàëîñü íàçíà÷èòü ôóíêöèþ äëÿ îñòàíîâêè ñëóæáû ìåòîäà ââîäà" # :!~ Restorer msgid "E288: Input method doesn't support any style" @@ -6963,8 +6919,7 @@ msgstr "E288: Ñëóæáà ìåòîäà ââîäà íå ïîääåðæèâàåò ñòèëè îòîáðàæåíèÿ" # #Restorer: âûâîäèòñÿ òîëüêî ïðè çíà÷åíèè ïàðàìåòðà 'verbose'>0 # :!~ Restorer msgid "E289: Input method doesn't support my preedit type" -msgstr "" -"E289: Ñëóæáà ìåòîäà ââîäà íå ïîääåðæèâàåò íàçíà÷åííûé ñòèëü îòîáðàæåíèÿ" +msgstr "E289: Ñëóæáà ìåòîäà ââîäà íå ïîääåðæèâàåò íàçíà÷åííûé ñòèëü îòîáðàæåíèÿ" # #Restorer: âûâîäèòñÿ äëÿ ôóíêöèè matchaddpos() # :!~ Restorer @@ -7039,16 +6994,14 @@ msgstr "E309: Íå óäàëîñü ñ÷èòàòü áëîê íîìåð 1 èç %s" #, c-format msgid "E310: Block 1 ID wrong (%s not a .swp file?)" msgstr "" -"E310: Íåäîïóñòèìûé èäåíòèôèêàòîð â áëîêå 1 (âîçìîæíî, ýòî íå ôàéë ïîäêà÷êè " -"%s)" +"E310: Íåäîïóñòèìûé èäåíòèôèêàòîð â áëîêå 1 (âîçìîæíî, ýòî íå ôàéë ïîäêà÷êè %s)" # ~!: earlier msgid "E311: Recovery Interrupted" msgstr "E311: Âîññòàíîâëåíèå ïðåðâàíî" # :!~ Restorer -msgid "" -"E312: Errors detected while recovering; look for lines starting with ???" +msgid "E312: Errors detected while recovering; look for lines starting with ???" msgstr "E312: Îøèáêè ïðè âîññòàíîâëåíèè. Òàêèå ñòðîêè ïîìå÷åíû ñèìâîëàìè ???" # :!~ Restorer @@ -7110,8 +7063,7 @@ msgstr "" # :!~ Restorer msgid "E333: Menu path must lead to a menu item" -msgstr "" -"E333: Öåïî÷êà ïóíêòîâ ìåíþ äîëæíà îêàí÷èâàòüñÿ èñïîëíÿåìûì ïóíêòîì ìåíþ" +msgstr "E333: Öåïî÷êà ïóíêòîâ ìåíþ äîëæíà îêàí÷èâàòüñÿ èñïîëíÿåìûì ïóíêòîì ìåíþ" # :!~ Restorer #, c-format @@ -7143,8 +7095,7 @@ msgstr "E339: Ïðåâûøåíà äëèíà ðåãóëÿðíîãî âûðàæåíèÿ" # :!~ Restorer msgid "E340: Internal error; if you can reproduce please report a bug" msgstr "" -"E340: Âíóòðåííÿÿ îøèáêà. Åñëè âîçìîæíî å¸ âîñïðîèçâåñòè, ñîîáùèòå " -"ðàçðàáîò÷èêó" +"E340: Âíóòðåííÿÿ îøèáêà. Åñëè âîçìîæíî å¸ âîñïðîèçâåñòè, ñîîáùèòå ðàçðàáîò÷èêó" # :!~ Restorer #, c-format @@ -7240,8 +7191,8 @@ msgstr "E359: Óñòàíîâêà ðåæèìà ýêðàíà íå ïîääåðæèâàåòñÿ" # :!~ Restorer msgid "E360: Cannot execute shell with -f option" msgstr "" -"E360: Íå óäàëîñü âûçâàòü êîìàíäíóþ îáîëî÷êó. Ïðîãðàììà çàïóùåíà ñ àðãóìåíòîì " -"-f" +"E360: Íå óäàëîñü âûçâàòü êîìàíäíóþ îáîëî÷êó. Ïðîãðàììà çàïóùåíà ñ àðãóìåíòîì -" +"f" # :!~ Restorer msgid "E362: Using a boolean value as a Float" @@ -7303,8 +7254,7 @@ msgstr "E373:  ôîðìàòíîé ñòðîêå íåïðåäâèäåííîå ïîÿâëåíèå ñïåöèôèêàòîðà %%%c" # :!~ Restorer msgid "E374: Missing ] in format string" -msgstr "" -"E374: Íå óêàçàí ñèìâîë çàêðûâàþùåé êâàäðàòíîé ñêîáêè â ôîðìàòíîé ñòðîêå" +msgstr "E374: Íå óêàçàí ñèìâîë çàêðûâàþùåé êâàäðàòíîé ñêîáêè â ôîðìàòíîé ñòðîêå" # :!~ Restorer #, c-format @@ -7339,8 +7289,7 @@ msgstr "E381: Äîñòèãíóòà âåðõíÿÿ ãðàíèöà ñïèñêà ðåçóëüòàòîâ" # :!~ Restorer msgid "E382: Cannot write, 'buftype' option is set" -msgstr "" -"E382: Íåâîçìîæíà çàïèñü áóôåðà ïðè òåêóùåì çíà÷åíèè ïàðàìåòðà 'buftype'" +msgstr "E382: Íåâîçìîæíà çàïèñü áóôåðà ïðè òåêóùåì çíà÷åíèè ïàðàìåòðà 'buftype'" # :!~ Restorer #, c-format @@ -7477,8 +7426,7 @@ msgstr "E411: Íå íàéäåíà ãðóïïó ïîäñâåòêè %s" # :!~ Restorer #, c-format msgid "E412: Not enough arguments: \":highlight link %s\"" -msgstr "" -"E412: Óêàçàíû íå âñå òðåáóåìûå ïàðàìåòðû â êîìàíäå `:highlight link %s`" +msgstr "E412: Óêàçàíû íå âñå òðåáóåìûå ïàðàìåòðû â êîìàíäå `:highlight link %s`" # :!~ Restorer #, c-format @@ -7606,8 +7554,7 @@ msgstr "E441: Îòñóòñòâóåò îêíî ïðîñìîòðà" # :!~ Restorer msgid "E442: Can't split topleft and botright at the same time" -msgstr "" -"E442: Íå äîïóñêàåòñÿ îäíîâðåìåííîå óêàçàíèå êîìàíä :topleft è :botright" +msgstr "E442: Íå äîïóñêàåòñÿ îäíîâðåìåííîå óêàçàíèå êîìàíä :topleft è :botright" # :!~ Restorer msgid "E443: Cannot rotate when another window is split" @@ -7942,8 +7889,7 @@ msgstr "E503: Êîôå åù¸ íå ãîòîâ" # #Restorer: îøèáêà E504: # :!~ Restorer msgid "is read-only (cannot override: \"W\" in 'cpoptions')" -msgstr "" -"ôàéë òîëüêî äëÿ ÷òåíèÿ (÷òîáû çàïèñàòü, óáåðèòå ôëàã 'W' â 'cpoptions')" +msgstr "ôàéë òîëüêî äëÿ ÷òåíèÿ (÷òîáû çàïèñàòü, óáåðèòå ôëàã 'W' â 'cpoptions')" # #Restorer: îøèáêà E505: # :!~ Restorer @@ -8279,8 +8225,7 @@ msgstr "íåäîïóñòèìûé íà÷àëüíûé ñèìâîë" # #Restorer: âûâîäèòñÿ êàê îøèáêà E576: # :!~ Restorer msgid "Missing '>'" -msgstr "" -"îòñóòñòâóåò ñèìâîë çàêðûâàþùåé óãëîâîé ñêîáêè â çàïèñè æóðíàëà çàêëàäîê" +msgstr "îòñóòñòâóåò ñèìâîë çàêðûâàþùåé óãëîâîé ñêîáêè â çàïèñè æóðíàëà çàêëàäîê" # #Restorer: âûâîäèòñÿ êàê îøèáêà E577: # :!~ Restorer @@ -8422,8 +8367,7 @@ msgstr "E607: Íåñêîëüêî ñëåäóþùèõ îäíà çà äðóãîé êîìàíä :finally" # :!~ Restorer msgid "E608: Cannot :throw exceptions with 'Vim' prefix" msgstr "" -"E608:  íàçíà÷åííûõ ïîëüçîâàòåëåì èñêëþ÷åíèÿõ çàïðåùåíî óêàçàíèå ïðèñòàâêè " -"VIM" +"E608:  íàçíà÷åííûõ ïîëüçîâàòåëåì èñêëþ÷åíèÿõ çàïðåùåíî óêàçàíèå ïðèñòàâêè VIM" # :!~ Restorer #, c-format @@ -8634,8 +8578,7 @@ msgstr "E658: Ïîòåðÿíî ñîåäèíåíèå ñðåäû ðàçðàáîòêè NetBeans ñ áóôåðîì %d" # :!~ Restorer msgid "E659: Cannot invoke Python recursively" msgstr "" -"E659:  äàííîé âåðñèè ïðîãðàììû íå äîïóñêàåòñÿ ðåêóðñèâíûé âûçîâ êîìàíä " -"Python" +"E659:  äàííîé âåðñèè ïðîãðàììû íå äîïóñêàåòñÿ ðåêóðñèâíûé âûçîâ êîìàíä Python" # :!~ Restorer #, c-format @@ -8767,14 +8710,12 @@ msgstr "E686:  ôóíêöèè %s òèï àðãóìåíòà äîëæåí áûòü List" # :!~ Restorer msgid "E687: Less targets than List items" msgstr "" -"E687: Êîëè÷åñòâî ïåðåìåííûõ ìåíüøå êîëè÷åñòâà ïðèñâàèâàåìûõ çíà÷åíèé " -"âûðàæåíèÿ" +"E687: Êîëè÷åñòâî ïåðåìåííûõ ìåíüøå êîëè÷åñòâà ïðèñâàèâàåìûõ çíà÷åíèé âûðàæåíèÿ" # :!~ Restorer msgid "E688: More targets than List items" msgstr "" -"E688: Êîëè÷åñòâî ïåðåìåííûõ áîëüøå êîëè÷åñòâà ïðèñâàèâàåìûõ çíà÷åíèé " -"âûðàæåíèÿ" +"E688: Êîëè÷åñòâî ïåðåìåííûõ áîëüøå êîëè÷åñòâà ïðèñâàèâàåìûõ çíà÷åíèé âûðàæåíèÿ" # :!~ Restorer #, c-format @@ -8811,8 +8752,7 @@ msgstr "E695: Íå äîïóñêàåòñÿ óêàçàíèå èíäåêñà äëÿ ïåðåìåííûõ ñ òèïîì Funcref" #, c-format msgid "E696: Missing comma in List: %s" msgstr "" -"E696:  äàííûõ òèï List íå óêàçàí ñèìâîë çàïÿòîé, êàê ðàçäåëèòåëü ýëåìåíòîâ " -"%s" +"E696:  äàííûõ òèï List íå óêàçàí ñèìâîë çàïÿòîé, êàê ðàçäåëèòåëü ýëåìåíòîâ %s" # :!~ Restorer #, c-format @@ -8848,8 +8788,7 @@ msgstr "E703: Îæèäàëñÿ òèï äàííûõ Number, à ïîëó÷åí Funcref" #, c-format msgid "E704: Funcref variable name must start with a capital: %s" msgstr "" -"E704: Íàèìåíîâàíèå ïåðåìåííîé ñ òèïîì Funcref äîëæíî áûòü ñ ïðîïèñíîé áóêâû " -"%s" +"E704: Íàèìåíîâàíèå ïåðåìåííîé ñ òèïîì Funcref äîëæíî áûòü ñ ïðîïèñíîé áóêâû %s" # :!~ Restorer #, c-format @@ -9253,8 +9192,7 @@ msgstr "E787: Ñîäåðæèìîå áóôåðà áûëî íåïðåäâèäåííî èçìåíåíî" # :!~ Restorer msgid "E788: Not allowed to edit another buffer now" msgstr "" -"E788: Çàïðåùåíà ïðàâêà áóôåðîâ, åñëè åñòü èçìåíåíèÿ â áóôåðå òîëüêî äëÿ " -"÷òåíèÿ" +"E788: Çàïðåùåíà ïðàâêà áóôåðîâ, åñëè åñòü èçìåíåíèÿ â áóôåðå òîëüêî äëÿ ÷òåíèÿ" # :!~ Restorer #, c-format @@ -9388,8 +9326,7 @@ msgstr "" # :!~ Restorer msgid "E814: Cannot close window, only autocmd window would remain" -msgstr "" -"E814: Íå óäàëîñü çàêðûòü òåêóùåå îêíî. Èñïîëíÿþòñÿ àêòèâíûå àâòîêîìàíäû" +msgstr "E814: Íå óäàëîñü çàêðûòü òåêóùåå îêíî. Èñïîëíÿþòñÿ àêòèâíûå àâòîêîìàíäû" # :!~ Restorer msgid "" @@ -9440,8 +9377,7 @@ msgstr "E823: Ôàéë ïîâðåæä¸í èëè íå ÿâëÿåòñÿ ôàéëîì èçìåíåíèé %s" # :!~ Restorer #, c-format msgid "E824: Incompatible undo file: %s" -msgstr "" -"E824: Íå ïîääåðæèâàåìàÿ äàííîé ïðîãðàììîé Vim âåðñèÿ ôàéëà èçìåíåíèé %s" +msgstr "E824: Íå ïîääåðæèâàåìàÿ äàííîé ïðîãðàììîé Vim âåðñèÿ ôàéëà èçìåíåíèé %s" # :!~ Restorer #, c-format @@ -9476,8 +9412,7 @@ msgstr "E830: Íå íàéäåíî èçìåíåíèå íîìåð %ld" # :!~ Restorer #, c-format msgid "E832: Non-encrypted file has encrypted undo file: %s" -msgstr "" -"E832: Ðåäàêòèðóåìûé ôàéë íå øèôðîâàí, íî øèôðîâàí åãî ôàéë èçìåíåíèé %s" +msgstr "E832: Ðåäàêòèðóåìûé ôàéë íå øèôðîâàí, íî øèôðîâàí åãî ôàéë èçìåíåíèé %s" # :!~ Restorer #, c-format @@ -9497,13 +9432,11 @@ msgstr "E835: Êîíôëèêò çíà÷åíèé ïàðàìåòðîâ 'ambiwidth' è 'fillchars'" # :!~ Restorer msgid "E836: This Vim cannot execute :python after using :py3" -msgstr "" -"E836:  äàííîé âåðñèè çàïðåù¸í âûçîâ êîìàíäû :python ïîñëå êîìàíäû :py3" +msgstr "E836:  äàííîé âåðñèè çàïðåù¸í âûçîâ êîìàíäû :python ïîñëå êîìàíäû :py3" # :!~ Restorer msgid "E837: This Vim cannot execute :py3 after using :python" -msgstr "" -"E837:  äàííîé âåðñèè çàïðåù¸í âûçîâ êîìàíäû :py3 ïîñëå êîìàíäû :python" +msgstr "E837:  äàííîé âåðñèè çàïðåù¸í âûçîâ êîìàíäû :py3 ïîñëå êîìàíäû :python" # :!~ Restorer msgid "E838: NetBeans is not supported with this GUI" @@ -9514,8 +9447,7 @@ msgstr "" # :!~ Restorer msgid "E840: Completion function deleted text" msgstr "" -"E840: Ôóíêöèÿ, çàäàííàÿ ïîëüçîâàòåëåì äëÿ ïîäñòàíîâêè, âûçâàëà óäàëåíèå " -"òåêñòà" +"E840: Ôóíêöèÿ, çàäàííàÿ ïîëüçîâàòåëåì äëÿ ïîäñòàíîâêè, âûçâàëà óäàëåíèå òåêñòà" # :!~ Restorer msgid "E841: Reserved name, cannot be used for user defined command" @@ -9613,8 +9545,8 @@ msgstr "" # :!~ Restorer msgid "E860: Need 'id' and 'type' or 'types' with 'both'" msgstr "" -"E860: Åñëè çàäàí êëþ÷ \"both\", óêàæèòå çíà÷åíèå êëþ÷åé \"id\" è \"type\" " -"èëè \"types\"" +"E860: Åñëè çàäàí êëþ÷ \"both\", óêàæèòå çíà÷åíèå êëþ÷åé \"id\" è \"type\" èëè " +"\"types\"" # :!~ Restorer msgid "E861: Cannot open a second popup with a terminal" @@ -9726,11 +9658,9 @@ msgstr "E882: Îøèáêà ïðè âûïîëíåíèè ñðàâíåíèÿ â ôóíêöèè ïîèñêà äóáëèêàòîâ" # :!~ Restorer msgid "" -"E883: Search pattern and expression register may not contain two or more " -"lines" +"E883: Search pattern and expression register may not contain two or more lines" msgstr "" -"E883: Ðåãèñòð ïîèñêà è ðåãèñòð âûðàæåíèÿ íå ìîãóò ñîäåðæàòü áîëåå îäíîé " -"ñòðîêè" +"E883: Ðåãèñòð ïîèñêà è ðåãèñòð âûðàæåíèÿ íå ìîãóò ñîäåðæàòü áîëåå îäíîé ñòðîêè" # :!~ Restorer #, c-format @@ -9790,8 +9720,7 @@ msgid "" "E895: Sorry, this command is disabled, the MzScheme's racket/base module " "could not be loaded." msgstr "" -"E895: Íå ïîäêëþ÷åí ìîäóëü racket/base äëÿ ÿçûêà MzScheme. Êîìàíäà íå " -"âûïîëíåíà" +"E895: Íå ïîäêëþ÷åí ìîäóëü racket/base äëÿ ÿçûêà MzScheme. Êîìàíäà íå âûïîëíåíà" # :!~ Restorer #, c-format @@ -9842,8 +9771,7 @@ msgstr "E903: Àðãóìåíòû ïîëó÷åííîé êîìàíäû íå çàêëþ÷åíû â äâîéíûå êàâû÷êè" # :!~ Restorer msgid "E904: Last argument for expr/call must be a number" msgstr "" -"E904: Òèï äàííûõ ïîñëåäíåãî ïàðàìåòðà êîìàíäû expr èëè call äîëæåí áûòü " -"Number" +"E904: Òèï äàííûõ ïîñëåäíåãî ïàðàìåòðà êîìàíäû expr èëè call äîëæåí áûòü Number" # #Restorer: âûâîäèòñÿ ïðè 'verbose'>3 # :!~ Restorer @@ -9897,8 +9825,8 @@ msgstr "E914: Îæèäàëñÿ òèï äàííûõ Float, à ïîëó÷åí Channel" # :!~ Restorer msgid "E915: in_io buffer requires in_buf or in_name to be set" msgstr "" -"E915: Ïðè óñòàíîâêå êëþ÷ó in_io çíà÷åíèÿ buffer, òðåáóåòñÿ çàäàòü êëþ÷ " -"in_buf èëè in_name" +"E915: Ïðè óñòàíîâêå êëþ÷ó in_io çíà÷åíèÿ buffer, òðåáóåòñÿ çàäàòü êëþ÷ in_buf " +"èëè in_name" # :!~ Restorer msgid "E916: Not a valid job" @@ -9922,8 +9850,7 @@ msgstr "E919:  êàòàëîãàõ, óêàçàííûõ â ïàðàìåòðå '%s', íå íàéäåíî \"%s\"" # :!~ Restorer msgid "E920: _io file requires _name to be set" msgstr "" -"E920: Ïðè óñòàíîâêå êëþ÷àì *_io çíà÷åíèÿ file, òðåáóåòñÿ çàäàòü è êëþ÷è " -"*_name" +"E920: Ïðè óñòàíîâêå êëþ÷àì *_io çíà÷åíèÿ file, òðåáóåòñÿ çàäàòü è êëþ÷è *_name" # :!~ Restorer msgid "E921: Invalid callback argument" @@ -10293,8 +10220,7 @@ msgstr "E997: Íå óäàëîñü íàéòè âêëàäêó ïîä íîìåðîì %d" # :!~ Restorer #, c-format msgid "E998: Reduce of an empty %s with no initial value" -msgstr "" -"E998: Ôóíêöèÿ reduce() âûçâàíà äëÿ ïóñòîãî %s è áåç íà÷àëüíîãî çíà÷åíèÿ" +msgstr "E998: Ôóíêöèÿ reduce() âûçâàíà äëÿ ïóñòîãî %s è áåç íà÷àëüíîãî çíà÷åíèÿ" # :!~ Restorer #, c-format @@ -10480,8 +10406,7 @@ msgstr "E1034: Îáíàðóæåíî èñïîëüçîâàíèå çàðåçåðâèðîâàííîãî ñëîâà â %s" # :!~ Restorer #, no-c-format msgid "E1035: % requires number arguments" -msgstr "" -"E1035: Äëÿ îïåðàöèè äåëåíèå ñ îñòàòêîì òèï îïåðàíäîâ äîëæåí áûòü Number" +msgstr "E1035: Äëÿ îïåðàöèè äåëåíèå ñ îñòàòêîì òèï îïåðàíäîâ äîëæåí áûòü Number" # :!~ Restorer #, c-format @@ -10592,8 +10517,7 @@ msgstr "E1059: Çàïðåù¸í ïðîáåëüíûé ñèìâîë ïåðåä ñèìâîëîì äâîåòî÷èå â %s" # :!~ Restorer #, c-format msgid "E1060: Expected dot after name: %s" -msgstr "" -"E1060:  êîìàíäå :import îòñóòñòâóåò ñèìâîë òî÷êè ïîñëå íàèìåíîâàíèÿ %s" +msgstr "E1060:  êîìàíäå :import îòñóòñòâóåò ñèìâîë òî÷êè ïîñëå íàèìåíîâàíèÿ %s" # :!~ Restorer #, c-format @@ -10654,8 +10578,7 @@ msgstr "E1073: Íàèìåíîâàíèå ôóíêöèè óæå îïðåäåëåíî %s" # :!~ Restorer msgid "E1074: No white space allowed after dot" -msgstr "" -"E1074: Çàïðåù¸í ïðîáåëüíûé ñèìâîë ïîñëå ñèìâîëà òî÷êè â êîìàíäå :import" +msgstr "E1074: Çàïðåù¸í ïðîáåëüíûé ñèìâîë ïîñëå ñèìâîëà òî÷êè â êîìàíäå :import" # :!~ Restorer #, c-format @@ -10841,13 +10764,11 @@ msgstr "" # :!~ Restorer msgid "E1116: \"assert_fails()\" fifth argument must be a string" msgstr "" -"E1116:  ôóíêöèè assert_fails() çíà÷åíèåì àðãóìåíòà íîìåð 5 äîëæíà áûòü " -"ñòðîêà" +"E1116:  ôóíêöèè assert_fails() çíà÷åíèåì àðãóìåíòà íîìåð 5 äîëæíà áûòü ñòðîêà" # :!~ Restorer msgid "E1117: Cannot use ! with nested :def" -msgstr "" -"E1117: Íå äîïóñêàåòñÿ óêàçàíèå ìîäèôèêàòîðà ! äëÿ âëîæåííûõ êîìàíä :def" +msgstr "E1117: Íå äîïóñêàåòñÿ óêàçàíèå ìîäèôèêàòîðà ! äëÿ âëîæåííûõ êîìàíä :def" # :!~ Restorer msgid "E1118: Cannot change locked list" @@ -10856,8 +10777,7 @@ msgstr "E1118: Èçìåíåíèå ñïèñêà íå âûïîëíåíî. Óñòàíîâëåíà áëîêèðîâêà ñïèñêà" # :!~ Restorer msgid "E1119: Cannot change locked list item" msgstr "" -"E1119: Èçìåíåíèå ýëåìåíòà ñïèñêà íå âûïîëíåíî. Óñòàíîâëåíà áëîêèðîâêà " -"ýëåìåíòà" +"E1119: Èçìåíåíèå ýëåìåíòà ñïèñêà íå âûïîëíåíî. Óñòàíîâëåíà áëîêèðîâêà ýëåìåíòà" # :!~ Restorer msgid "E1120: Cannot change dict" @@ -10936,8 +10856,7 @@ msgstr "E1135: Îæèäàëîñü ëîãè÷åñêîå çíà÷åíèå, à ïîëó÷åí String \"%s\"" # :!~ Restorer msgid "E1136: <Cmd> mapping must end with <CR> before second <Cmd>" msgstr "" -"E1136: Íàçíà÷àåìàÿ êîìàíäà <Cmd> äîëæíà çàâåðøàåòñÿ <CR> ïåðåä ñëåäóþùåé " -"<Cmd>" +"E1136: Íàçíà÷àåìàÿ êîìàíäà <Cmd> äîëæíà çàâåðøàåòñÿ <CR> ïåðåä ñëåäóþùåé <Cmd>" # :!~ Restorer msgid "E1138: Using a Bool as a Number" @@ -11041,8 +10960,7 @@ msgstr "E1159: Íå äîïóñêàåòñÿ ðàçáèåíèå îêíà îäíîâðåìåííî ñ çàêðûòèåì áóôåðà" # :!~ Restorer msgid "E1160: Cannot use a default for variable arguments" msgstr "" -"E1160: Íå äîïóñêàåòñÿ óêàçàíèå çíà÷åíèÿ ïî óìîë÷àíèþ äëÿ îñòàòî÷íûõ " -"ïàðàìåòðîâ" +"E1160: Íå äîïóñêàåòñÿ óêàçàíèå çíà÷åíèÿ ïî óìîë÷àíèþ äëÿ îñòàòî÷íûõ ïàðàìåòðîâ" # :!~ Restorer #, c-format @@ -11187,8 +11105,7 @@ msgstr "E1187: Ïðîèçîøëà îøèáêà ïðè îáðàáîòêå ôàéëà defaults.vim" # :!~ Restorer msgid "E1188: Cannot open a terminal from the command line window" -msgstr "" -"E1188: Íå äîïóñêàåòñÿ ïåðåõîä â îêíî òåðìèíàëà èç îêíà êîìàíäíîé ñòðîêè" +msgstr "E1188: Íå äîïóñêàåòñÿ ïåðåõîä â îêíî òåðìèíàëà èç îêíà êîìàíäíîé ñòðîêè" # :!~ Restorer #, c-format @@ -11318,8 +11235,7 @@ msgid "E1215: Digraph must be one character: %s" msgstr "E1215: Ñàì äèãðàô äîëæåí áûòü çàäàí êàê îäèí ñèìâîë, à íå %s" # :!~ Restorer -msgid "" -"E1216: digraph_setlist() argument must be a list of lists with two items" +msgid "E1216: digraph_setlist() argument must be a list of lists with two items" msgstr "" "E1216:  ôóíêöèè digraph_setlist() òèï àðãóìåíòà äîëæåí áûòü List, ãäå " "âëîæåííûå òèïû List ñîäåðæàò äâà ýëåìåíòà" @@ -11390,14 +11306,12 @@ msgstr "" # :!~ Restorer #, c-format msgid "E1229: Expected dictionary for using key \"%s\", but got %s" -msgstr "" -"E1229: Îæèäàëñÿ òèï Dictionary äëÿ îáðàáîòêè êëþ÷à \"%s\", à ïîëó÷åí %s" +msgstr "E1229: Îæèäàëñÿ òèï Dictionary äëÿ îáðàáîòêè êëþ÷à \"%s\", à ïîëó÷åí %s" # :!~ Restorer msgid "E1230: Encryption: sodium_mlock() failed" msgstr "" -"E1230: Îøèáêà øèôðîâàíèÿ. Ïðîèçîø¸ë ñáîé â áèáëèîòå÷íîé ôóíêöèè " -"sodium_mlock()" +"E1230: Îøèáêà øèôðîâàíèÿ. Ïðîèçîø¸ë ñáîé â áèáëèîòå÷íîé ôóíêöèè sodium_mlock()" # :!~ Restorer #, c-format @@ -11744,8 +11658,7 @@ msgstr "" #, c-format msgid "E1301: String, Number, List or Blob required for argument %d" msgstr "" -"E1301: Òèï äàííûõ àðãóìåíòà íîìåð %d äîëæåí áûòü String, Number, List èëè " -"BLOB" +"E1301: Òèï äàííûõ àðãóìåíòà íîìåð %d äîëæåí áûòü String, Number, List èëè BLOB" # :!~ Restorer msgid "E1302: Script variable was deleted" @@ -11764,8 +11677,7 @@ msgid "E1304: Cannot use type with this variable: %s" msgstr "E1304: Íå äîïóñêàåòñÿ óêàçûâàòü òèïà äàííûõ äëÿ ïåðåìåííîé %s" # :!~ Restorer -msgid "" -"E1305: Cannot use \"length\", \"end_col\" and \"end_lnum\" with \"text\"" +msgid "E1305: Cannot use \"length\", \"end_col\" and \"end_lnum\" with \"text\"" msgstr "" "E1305: Íåäîïóñòèìî óêàçûâàòü êëþ÷è \"length\", \"end_col\" è \"end_lnum\" c " "êëþ÷îì \"text\"" @@ -11917,8 +11829,8 @@ msgstr "E1337: Ó êëàññà \"%2$s\" îòñóòñòâóåò ïåðåìåííàÿ êëàññà \"%1$s\"" # :!~ Restorer msgid "" -"E1339: Cannot add a textprop with text after using a textprop with a " -"negative id" +"E1339: Cannot add a textprop with text after using a textprop with a negative " +"id" msgstr "" "E1339: Çàïðåùåíà âñòàâêà âèðòóàëüíîãî òåêñòà ïîñëå ïðèìåíåíèÿ îòðèöàòåëüíîãî " "çíà÷åíèÿ ÈÄ" @@ -12056,11 +11968,10 @@ msgstr "" # :!~ Restorer msgid "" -"E1368: Static must be followed by \"var\" or \"def\" or \"final\" or " -"\"const\"" +"E1368: Static must be followed by \"var\" or \"def\" or \"final\" or \"const\"" msgstr "" -"E1368: Ïîñëå êëþ÷åâîãî ñëîâà \"static\" òðåáóåòñÿ êîìàíäà :var èëè :def, " -"ëèáî êëþ÷åâîå ñëîâî \"final\" èëè \"const\"" +"E1368: Ïîñëå êëþ÷åâîãî ñëîâà \"static\" òðåáóåòñÿ êîìàíäà :var èëè :def, ëèáî " +"êëþ÷åâîå ñëîâî \"final\" èëè \"const\"" # :!~ Restorer #, c-format @@ -12079,8 +11990,7 @@ msgstr "E1371: Ïîñëå êëþ÷åâîãî ñëîâà \"abstract\" òðåáóåòñÿ êîìàíäà :def" #, c-format msgid "E1372: Abstract method \"%s\" cannot be defined in a concrete class" msgstr "" -"E1372: Íå äîïóñêàåòñÿ îïðåäåëåíèå â ðåàëüíîì êëàññå àáñòðàêòíîãî ìåòîäà " -"\"%s\"" +"E1372: Íå äîïóñêàåòñÿ îïðåäåëåíèå â ðåàëüíîì êëàññå àáñòðàêòíîãî ìåòîäà \"%s\"" # :!~ Restorer #, c-format @@ -12129,8 +12039,8 @@ msgstr "E1381: Ê èíòåðôåéñó íåïðèìåíèìî êëþ÷åâîå ñëîâî \"implements\"" #, c-format msgid "E1382: Variable \"%s\": type mismatch, expected %s but got %s" msgstr "" -"E1382: Íåñîîòâåòñòâóþùèé òèï äàííûõ ïåðåìåííîé \"%s\". Îæèäàëñÿ %s, à " -"ïîëó÷åí %s" +"E1382: Íåñîîòâåòñòâóþùèé òèï äàííûõ ïåðåìåííîé \"%s\". Îæèäàëñÿ %s, à ïîëó÷åí " +"%s" # :!~ Restorer #, c-format @@ -12268,8 +12178,8 @@ msgstr "E1408: Èíòåðôåéñû íå ïîääåðæèâàþò ôèíàëèçèðîâàííûå ïåðåìåííûå" #, c-format msgid "E1409: Cannot change read-only variable \"%s\" in class \"%s\"" msgstr "" -"E1409: Íå äîïóñêàåòñÿ èçìåíåíèå äîñòóïíîé òîëüêî äëÿ ÷òåíèÿ ïåðåìåííîé " -"\"%s\" êëàññà \"%s\"" +"E1409: Íå äîïóñêàåòñÿ èçìåíåíèå äîñòóïíîé òîëüêî äëÿ ÷òåíèÿ ïåðåìåííîé \"%s\" " +"êëàññà \"%s\"" # :!~ Restorer msgid "E1410: Const variable not supported in an interface" @@ -12385,8 +12295,7 @@ msgstr "" #, c-format msgid "E1503: Positional argument %d out of bounds: %s" msgstr "" -"E1503: Ñïåöèôèêàòîð ïîçèöèè íîìåð %d íå ñîîòâåòñòâóåò êîëè÷åñòâó àðãóìåíòîâ " -"%s" +"E1503: Ñïåöèôèêàòîð ïîçèöèè íîìåð %d íå ñîîòâåòñòâóåò êîëè÷åñòâó àðãóìåíòîâ %s" # :!~ Restorer #, c-format @@ -12413,8 +12322,7 @@ msgstr "" # :!~ Restorer msgid "E1509: Error occurred when reading or writing extended attribute" -msgstr "" -"E1509: Ïðîèçîøëà îøèáêà ïðè ñ÷èòûâàíèè èëè çàïèñè ðàñøèðåííîãî àòðèáóòà" +msgstr "E1509: Ïðîèçîøëà îøèáêà ïðè ñ÷èòûâàíèè èëè çàïèñè ðàñøèðåííîãî àòðèáóòà" # :!~ Restorer #, c-format @@ -12635,8 +12543,8 @@ msgstr "èíäåêñ ñïèñêà âûõîäèò çà ãðàíèöû äèàïàçîíà" #, c-format msgid "internal error: failed to get Vim list item %d" msgstr "" -"âíóòðåííÿÿ îøèáêà. Íå óäàëîñü ïîëó÷èòü èç îáúåêòà Vim.List ýëåìåíò ñ " -"èíäåêñîì %d" +"âíóòðåííÿÿ îøèáêà. Íå óäàëîñü ïîëó÷èòü èç îáúåêòà Vim.List ýëåìåíò ñ èíäåêñîì " +"%d" # :!~ Restorer msgid "slice step cannot be zero" @@ -12923,8 +12831,7 @@ msgid "(global or local to buffer)" msgstr "(îáëàñòü äåéñòâèÿ: îáùèé èëè òîëüêî äëÿ áóôåðà)" # :!~ Restorer -msgid "" -"\" Each \"set\" line shows the current value of an option (on the left)." +msgid "\" Each \"set\" line shows the current value of an option (on the left)." msgstr "" "\"  ñòðîêàõ, íà÷èíàþùèõñÿ ñî ñëîâà «set», ïîêàçàíî òåêóùåå çíà÷åíèå " "ïàðàìåòðîâ" @@ -12938,16 +12845,13 @@ msgstr "" # :!~ Restorer msgid "\" A boolean option will be toggled." msgstr "" -"\" äëÿ ïàðàìåòðîâ-ïåðåêëþ÷àòåëåé áóäåò èçìåíåíî çíà÷åíèå íà " -"ïðîòèâîïîëîæíîå;" +"\" äëÿ ïàðàìåòðîâ-ïåðåêëþ÷àòåëåé áóäåò èçìåíåíî çíà÷åíèå íà ïðîòèâîïîëîæíîå;" # :!~ Restorer msgid "" -"\" For other options you can edit the value before hitting " -"<Enter>." +"\" For other options you can edit the value before hitting <Enter>." msgstr "" -"\" äëÿ äðóãèõ ïàðàìåòðîâ íåîáõîäèìî ïåðåä ýòèì îòðåäàêòèðîâàòü èõ " -"çíà÷åíèÿ" +"\" äëÿ äðóãèõ ïàðàìåòðîâ íåîáõîäèìî ïåðåä ýòèì îòðåäàêòèðîâàòü èõ çíà÷åíèÿ" # :!~ Restorer msgid "\" Hit <Enter> on a help line to open a help window on this option." @@ -13739,8 +13643,7 @@ msgstr "" # :!~ Restorer msgid "" -"\"last\", \"buffer\" or \"current\": which directory used for the file " -"browser" +"\"last\", \"buffer\" or \"current\": which directory used for the file browser" msgstr "" "êàòàëîã, èñïîëüçóåìûé äëÿ îêîí îòêðûòèÿ è ñîõðàíåíèÿ ôàéëîâ\n" "Âîçìîæíûå çíà÷åíèÿ: \"last\", \"buffer\" èëè \"current\"" diff --git a/src/po/ru.po b/src/po/ru.po index 13589d0..a679b4f 100644 --- a/src/po/ru.po +++ b/src/po/ru.po @@ -2039,7 +2039,7 @@ msgid " Omni completion (^O^N^P)" msgstr " ПодÑтановка по контекÑту CTRL+O и CTRL+N или CTRL+P" # :!~ Restorer -msgid " Spelling suggestion (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" msgstr " ПодÑтановка вариантов напиÑÐ°Ð½Ð¸Ñ CTRL+S и CTRL+N или CTRL+P" # :!~ Restorer diff --git a/src/po/sk.cp1250.po b/src/po/sk.cp1250.po index 36fd347..8521351 100644 --- a/src/po/sk.cp1250.po +++ b/src/po/sk.cp1250.po @@ -15,7 +15,7 @@ msgstr "" "Last-Translator: Lubomir Host <rajo@platon.sk>\n" "Language-Team: Slovak <sk-i18n@lists.linux.sk>\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=cp1250\n" +"Content-Type: text/plain; charset=CP1250\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Vim 7.x\n" diff --git a/src/po/sr.po b/src/po/sr.po index 6372f92..3b76e3c 100644 --- a/src/po/sr.po +++ b/src/po/sr.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: Vim(Serbian)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-04-25 12:55+0400\n" -"PO-Revision-Date: 2024-04-25 13:09+0400\n" +"POT-Creation-Date: 2024-07-19 10:23+0400\n" +"PO-Revision-Date: 2024-07-19 10:39+0400\n" "Last-Translator: Ivan PeÅ¡ić <ivan.pesic@gmail.com>\n" "Language-Team: Serbian\n" "Language: sr\n" @@ -447,10 +447,6 @@ msgstr "катакана" msgid "Bopomofo" msgstr "бопомофо" -msgid "Not enough memory to set references, garbage collection aborted!" -msgstr "" -"Ðема довољно меморије за поÑтављање референци, прекинуто је Ñкупљање отпада" - msgid "" "\n" "\tLast set from " @@ -879,6 +875,10 @@ msgstr[0] "+-%s%3ld линија: " msgstr[1] "+-%s%3ld линије: " msgstr[2] "+-%s%3ld линија: " +msgid "Not enough memory to set references, garbage collection aborted!" +msgstr "" +"Ðема довољно меморије за поÑтављање референци, прекинуто је Ñкупљање отпада" + msgid "No match at cursor, finding next" msgstr "Ðема подударања на меÑту курÑора, тражи Ñе даље" @@ -1262,15 +1262,6 @@ msgstr "linenr је ван опÑега" msgid "not allowed in the Vim sandbox" msgstr "није дозвољено унутар Vim sandbox" -#, c-format -msgid "E370: Could not load library %s" -msgstr "E370: Библиотека %s није могла да Ñе учита" - -msgid "Sorry, this command is disabled: the Perl library could not be loaded." -msgstr "" -"Жао нам је, ова команда је онемогућена: Perl библиотека није могла да Ñе " -"учита." - msgid "invalid buffer number" msgstr "неиÑправан број бафера" @@ -1372,8 +1363,8 @@ msgstr " КориÑнички дефиниÑано довршавање (^U^N^P) msgid " Omni completion (^O^N^P)" msgstr " Omni довршавање (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " ПравопиÑни предлог (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " ПравопиÑни предлог (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Довршавање локалне кључне речи (^N^P)" @@ -3886,6 +3877,15 @@ msgstr "УпиÑивање viminfo фајла „%sâ€" msgid "Already only one window" msgstr "Већ поÑтоји Ñамо један прозор" +#, c-format +msgid "E370: Could not load library %s" +msgstr "E370: Библиотека %s није могла да Ñе учита" + +msgid "Sorry, this command is disabled: the Perl library could not be loaded." +msgstr "" +"Жао нам је, ова команда је онемогућена: Perl библиотека није могла да Ñе " +"учита." + msgid "Edit with Vim using &tabpages" msgstr "Уређуј програмом Vim у новој &картици" @@ -5939,9 +5939,6 @@ msgstr "E612: ДефиниÑано је превише знакова" msgid "E613: Unknown printer font: %s" msgstr "E613: Ðепознат фонт штампача: %s" -msgid "E614: Class required" -msgstr "E614: Потребна је клаÑа" - #, c-format msgid "E616: Object required for argument %d" msgstr "E616: За аргумент %d је потребан објекат" @@ -8421,21 +8418,12 @@ msgstr "E1317: ÐеиÑправна декларација променљиве msgid "E1318: Not a valid command in a class: %s" msgstr "E1318: Команда не важи у клаÑи: %s" -msgid "E1319: Using a Class as a Number" -msgstr "E1319: КлаÑа Ñе кориÑти као Број" - msgid "E1320: Using an Object as a Number" msgstr "E1320: Објекат Ñе кориÑти као Број" -msgid "E1321: Using a Class as a Float" -msgstr "E1321: КлаÑа Ñе кориÑти као Покретни" - msgid "E1322: Using an Object as a Float" msgstr "E1322: Објекат Ñе кориÑти као Покретни" -msgid "E1323: Using a Class as a String" -msgstr "E1323: КлаÑа Ñе кориÑти као Стринг" - msgid "E1324: Using an Object as a String" msgstr "E1324: Објекат Ñе кориÑти као Стринг" @@ -8703,10 +8691,6 @@ msgid "E1394: Type name must start with an uppercase letter: %s" msgstr "E1394: Име типа мора да почне великим Ñловом: %s" #, c-format -msgid "E1395: Type alias \"%s\" cannot be modified" -msgstr "E1395: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†не може да Ñе измени" - -#, c-format msgid "E1396: Type alias \"%s\" already exists" msgstr "E1396: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†већ поÑтоји" @@ -8720,18 +8704,6 @@ msgid "E1399: Type can only be used in a script" msgstr "E1399: Тип може да Ñе употреби Ñамо у Ñкрипти" #, c-format -msgid "E1400: Using type alias \"%s\" as a Number" -msgstr "E1400: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†Ñе кориÑти као Број" - -#, c-format -msgid "E1401: Using type alias \"%s\" as a Float" -msgstr "E1401: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†Ñе кориÑти као Покретни" - -#, c-format -msgid "E1402: Using type alias \"%s\" as a String" -msgstr "E1402: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†Ñе кориÑти као Стринг" - -#, c-format msgid "E1403: Type alias \"%s\" cannot be used as a value" msgstr "E1403: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° „%s†не може да Ñе кориÑти као вредноÑÑ‚" @@ -8742,9 +8714,6 @@ msgstr "E1404: Abstract не може да Ñе кориÑти у интерфе msgid "E1405: Class \"%s\" cannot be used as a value" msgstr "E1405: КлаÑа „%s†не може да Ñе кориÑти као вредноÑÑ‚" -msgid "E1406: Cannot use a Class as a variable or value" -msgstr "E1406: КлаÑа не може да Ñе кориÑти као променљива или вредноÑÑ‚" - msgid "E1407: Cannot use a Typealias as a variable or value" msgstr "E1407: ÐÐ»Ð¸Ñ˜Ð°Ñ Ñ‚Ð¸Ð¿Ð° не може да Ñе кориÑти као променљива или вредноÑÑ‚" @@ -9701,6 +9670,9 @@ msgstr "вишеÑтруке картице" msgid "0, 1 or 2; when to use a tab pages line" msgstr "0, 1 или 2; када Ñе кориÑти линија Ñа картицама" +msgid "behaviour when closing tab pages: left, uselast or empty" +msgstr "понашање приликом затварања картице: left, uselast или празно" + msgid "maximum number of tab pages to open for -p and \"tab all\"" msgstr "макÑимални број картица које Ñе отварају за -p и „tab allâ€" diff --git a/src/po/sv.po b/src/po/sv.po index 629a22c..d5296db 100644 --- a/src/po/sv.po +++ b/src/po/sv.po @@ -261,8 +261,8 @@ msgstr " Användardefinierad komplettering (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omnikomplettering (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Stavningsförslag (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Stavningsförslag (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokal nyckelordskomplettering (^N^P)" diff --git a/src/po/tojavascript.vim b/src/po/tojavascript.vim index 8b0dd73..4671a47 100644 --- a/src/po/tojavascript.vim +++ b/src/po/tojavascript.vim @@ -5,15 +5,20 @@ set shortmess+=A -for name in argv()[1:] - exe 'edit ' .. fnameescape(name) +let s:namenum = 0 +let s:fls = [] +for s:name in argv()[1:] + exe 'edit ' .. fnameescape(s:name) " Strip comments, also after :set commands. g/^\s*"/s/.*// g/^\s*set .*"/s/.*// " Write as .js file, xgettext recognizes them - exe 'w! ' .. fnamemodify(name, ":t:r") .. ".js" + let s:fl = fnamemodify(s:name, ":t:r") .. s:namenum .. ".js" + exe 'w! ' .. s:fl + call add(s:fls, s:fl) + let s:namenum += 1 endfor - +call writefile(s:fls, "vim_to_js") quit diff --git a/src/po/tr.po b/src/po/tr.po index 4cff7b3..1150d60 100644 --- a/src/po/tr.po +++ b/src/po/tr.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: Vim Turkish Localization Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-17 12:57+0300\n" -"PO-Revision-Date: 2023-12-17 17:00+0300\n" +"POT-Creation-Date: 2024-06-18 13:41+0300\n" +"PO-Revision-Date: 2024-06-18 17:00+0300\n" "Last-Translator: Emir SARI <emir_sari@icloud.com>\n" "Language-Team: Turkish <https://github.com/bitigchi/vim>\n" "Language: tr\n" @@ -173,6 +173,9 @@ msgstr " (dosya %d/%d)" msgid " (file (%d) of %d)" msgstr " (dosya (%d)/%d)" +msgid "[Command Line]" +msgstr "[Komut Satırı]" + msgid "[Prompt]" msgstr "[Ä°stem]" @@ -444,9 +447,6 @@ msgstr "Katakana" msgid "Bopomofo" msgstr "Bopomofo" -msgid "Not enough memory to set references, garbage collection aborted!" -msgstr "Referansları ayarlamak için yetersiz bellek, atık toplama durduruldu" - msgid "" "\n" "\tLast set from " @@ -697,9 +697,6 @@ msgstr "Hata" msgid "Interrupt" msgstr "Yarıda Kesilme" -msgid "[Command Line]" -msgstr "[Komut Satırı]" - msgid "is a directory" msgstr "bir dizin" @@ -868,6 +865,9 @@ msgid_plural "+-%s%3ld lines: " msgstr[0] "+-%s%3ld satır: " msgstr[1] "+-%s%3ld satır: " +msgid "Not enough memory to set references, garbage collection aborted!" +msgstr "Referansları ayarlamak için yetersiz bellek, atık toplama durduruldu" + msgid "No match at cursor, finding next" msgstr "Ä°mleç konumunda eÅŸleÅŸme bulunamadı, sonraki bulunuyor" @@ -1348,8 +1348,8 @@ msgstr " Kullanıcı tanımlı tamamlamalar (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni tamamlaması (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Yazım önerisi (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Yazım önerisi (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Dahili anahtar sözcük tamamlaması (^N^P)" @@ -1427,6 +1427,9 @@ msgstr "mapnew() argümanı" msgid "filter() argument" msgstr "filter() argümanı" +msgid "foreach() argument" +msgstr "foreach() argümanı" + msgid "extendnew() argument" msgstr "extendnew() argümanı" @@ -2473,6 +2476,9 @@ msgstr "%s, %s üzerinde" msgid "Printing '%s'" msgstr "'%s' yazdırılıyor" +#~ msgid "DefaultFontNameForWindows" +#~ msgstr "" + #, c-format msgid "Opening the X display took %ld msec" msgstr "X ekranını açma %ld milisaniye sürdü" @@ -3414,8 +3420,8 @@ msgid "%s returning %s" msgstr "%s, %s döndürüyor" #, c-format -msgid "Function %s does not need compiling" -msgstr "%s iÅŸlevini derlemeye gerek yok " +msgid "Function %s%s%s does not need compiling" +msgstr "%s%s%s iÅŸlevini derlemeye gerek yok " #, c-format msgid "%s (%s, compiled %s)" @@ -3574,6 +3580,10 @@ msgstr " kullanıcı 2. vimrc dosyası: \"" msgid " 3rd user vimrc file: \"" msgstr " kullanıcı 3. vimrc dosyası: \"" +msgid " 4th user vimrc file: \"" +msgstr " kullanıcı 4. vimrc dosyası: \"" + + msgid " user exrc file: \"" msgstr " kullanıcı exrc dosyası: \"" @@ -4181,6 +4191,10 @@ msgid "E105: Using :loadkeymap not in a sourced file" msgstr "E105: :loadkeymap kaynak alınmayan bir dosyada kullanılıyor" #, c-format +msgid "E106: Unsupported diff output format: %s" +msgstr "E106: Desteklenmeyen diff çıktısı biçimi: %s" + +#, c-format msgid "E107: Missing parentheses: %s" msgstr "E107: Ayraç eksik: %s" @@ -4509,8 +4523,8 @@ msgstr "E196: Bu sürümde ikili harfler bulunmamaktadır" msgid "E197: Cannot set language to \"%s\"" msgstr "E197: \"%s\" diline ayarlanamıyor" -msgid "E199: Active window or buffer deleted" -msgstr "E199: Etkin pencere veya arabellek silinmiÅŸ" +msgid "E199: Active window or buffer changed or deleted" +msgstr "E199: Etkin pencere veya arabellek deÄŸiÅŸtirilmiÅŸ veya silinmiÅŸ" msgid "E200: *ReadPre autocommands made the file unreadable" msgstr "E200: *ReadPre otokomutları dosyayı okunamaz hale getirdi" @@ -6771,6 +6785,10 @@ msgstr "" msgid "E876: (NFA regexp) Not enough space to store the whole NFA" msgstr "E876: (BSO düzenli ifadesi) Tüm BSO'yu depolamak için yeterli alan yok" +#, c-format +msgid "E877: (NFA regexp) Invalid character class: %d" +msgstr "E877: (BSO düzenli ifadesi) Geçersiz karakter sınıfı: %d" + msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!" msgstr "E878: (BSO düzenli ifadesi) Dal gezinmesi için bellek ayrılamadı!" @@ -8383,13 +8401,14 @@ msgid "E1330: Invalid type for object variable: %s" msgstr "E1330: Nesne deÄŸiÅŸkeni için geçersiz tür: %s" msgid "" -"E1331: Public must be followed by \"var\" or \"static\" or \"final\" or " +"E1331: public must be followed by \"var\" or \"static\" or \"final\" or " "\"const\"" -msgstr "E1331: Public sonrası \"var\", \"static\", \"final\" veya \"const\" " +msgstr "" +"E1331: public sonrası \"var\", \"static\", \"final\" veya \"const\" " "gelmelidir" #, c-format -msgid "E1332: Public variable name cannot start with underscore: %s" +msgid "E1332: public variable name cannot start with underscore: %s" msgstr "E1332: Genel deÄŸiÅŸken adı bir alt çizgiyle baÅŸlayamaz: %s" #, c-format @@ -8512,8 +8531,8 @@ msgstr "E1367: \"%2$s\" arayüzünün \"%1$s\" deÄŸiÅŸkeninin eriÅŸim düzeyi fa msgid "" "E1368: Static must be followed by \"var\" or \"def\" or \"final\" or " "\"const\"" -msgstr "E1368: Static sonrası \"var\", \"def\", \"final\" veya \"const\" " -"gelmelidir" +msgstr "" +"E1368: Static sonrası \"var\", \"def\", \"final\" veya \"const\" gelmelidir" #, c-format msgid "E1369: Duplicate variable: %s" @@ -8535,18 +8554,21 @@ msgstr "E1373: Soyut yöntem \"%s\" gerçeklenmemiÅŸ" #, c-format msgid "E1374: Class variable \"%s\" accessible only inside class \"%s\"" -msgstr "E1374: Sınıf deÄŸiÅŸkeni \"%s\", yalnızca \"%s\" sınıfının içinde " +msgstr "" +"E1374: Sınıf deÄŸiÅŸkeni \"%s\", yalnızca \"%s\" sınıfının içinde " "eriÅŸilebilirdir" #, c-format msgid "E1375: Class variable \"%s\" accessible only using class \"%s\"" -msgstr "E1375: Sınıf deÄŸiÅŸkeni \"%s\", yalnızca \"%s\" sınıfı kullanılarak " +msgstr "" +"E1375: Sınıf deÄŸiÅŸkeni \"%s\", yalnızca \"%s\" sınıfı kullanılarak " "eriÅŸilebilirdir" #, c-format msgid "E1376: Object variable \"%s\" accessible only using class \"%s\" object" -msgstr "E1376: Nesne deÄŸiÅŸkeni \"%s\", yalnızca sınıf \"%s\" nesnesi " -"kullanılarak eriÅŸilebilirdir" +msgstr "" +"E1376: Nesne deÄŸiÅŸkeni \"%s\", yalnızca sınıf \"%s\" nesnesi kullanılarak " +"eriÅŸilebilirdir" #, c-format msgid "E1377: Access level of method \"%s\" is different in class \"%s\"" @@ -8576,23 +8598,25 @@ msgstr "" #, c-format msgid "E1384: Class method \"%s\" accessible only inside class \"%s\"" -msgstr "E1384: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfının içinde " -"eriÅŸilebilirdir" +msgstr "" +"E1384: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfının içinde eriÅŸilebilirdir" #, c-format msgid "E1385: Class method \"%s\" accessible only using class \"%s\"" -msgstr "E1385: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfı kullanılarak " +msgstr "" +"E1385: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfı kullanılarak " "eriÅŸilebilirdir" #, c-format msgid "E1386: Object method \"%s\" accessible only using class \"%s\" object" -msgstr "E1386: Nesne yöntemi \"%s\", yalnızca sınıf \"%s\" nesnesi " -"kullanılarak eriÅŸilebilirdir" +msgstr "" +"E1386: Nesne yöntemi \"%s\", yalnızca sınıf \"%s\" nesnesi kullanılarak " +"eriÅŸilebilirdir" -msgid "E1387: Public variable not supported in an interface" +msgid "E1387: public variable not supported in an interface" msgstr "E1387: Bir arayüzde genel deÄŸiÅŸken desteklenmiyor" -msgid "E1388: Public keyword not supported for a method" +msgid "E1388: public keyword not supported for a method" msgstr "E1388: Bir yöntem için genel anahtar sözcük desteklenmiyor" msgid "E1389: Missing name after implements" @@ -8607,12 +8631,14 @@ msgstr "" #, c-format msgid "E1391: Cannot (un)lock variable \"%s\" in class \"%s\"" -msgstr "E1391: \"%2$s\" sınıfındaki \"%1$s\" deÄŸiÅŸkeni kilitlenemiyor/açılamıyor" +msgstr "" +"E1391: \"%2$s\" sınıfındaki \"%1$s\" deÄŸiÅŸkeni kilitlenemiyor/açılamıyor" #, c-format msgid "E1392: Cannot (un)lock class variable \"%s\" in class \"%s\"" -msgstr "E1392: \"%2$s\" sınıfındaki \"%1$s\" sınıf deÄŸiÅŸkeni " -"kilitlenemiyor/açılamıyor" +msgstr "" +"E1392: \"%2$s\" sınıfındaki \"%1$s\" sınıf deÄŸiÅŸkeni kilitlenemiyor/" +"açılamıyor" msgid "E1393: Type can only be defined in Vim9 script" msgstr "E1393: Tür, yalnızca Vim9 betiÄŸinde tanımlanabilir" @@ -8672,13 +8698,83 @@ msgstr "E1408: Final deÄŸiÅŸkeni bir arayüzde desteklenmiyor" #, c-format msgid "E1409: Cannot change read-only variable \"%s\" in class \"%s\"" -msgstr "E1409: \"%2$s\" sınıfındaki \"%1$s\" saltokunur deÄŸiÅŸken " -"deÄŸiÅŸtirilemiyor" +msgstr "" +"E1409: \"%2$s\" sınıfındaki \"%1$s\" saltokunur deÄŸiÅŸken deÄŸiÅŸtirilemiyor" msgid "E1410: Const variable not supported in an interface" msgstr "E1410: Bir arayüzde bir bir Const deÄŸiÅŸken desteklenmiyor" #, c-format +msgid "E1411: Missing dot after object \"%s\"" +msgstr "E1411: \"%s\" nesnesi sonrası nokta eksik" + +#, c-format +msgid "E1412: Builtin object method \"%s\" not supported" +msgstr "E1412: YerleÅŸik nesne yöntemi \"%s\" desteklenmiyor" + +msgid "E1413: Builtin class method not supported" +msgstr "E1413: YerleÅŸik sınıf yöntemi desteklenmiyor" + +msgid "E1414: Enum can only be defined in Vim9 script" +msgstr "E1414: Enümerasyon, yalnızca Vim9 betiÄŸinde kullanılabilir" + +#, c-format +msgid "E1415: Enum name must start with an uppercase letter: %s" +msgstr "E1415: Enümerasyon adı bir BÃœYÃœK harfle baÅŸlamalıdır: %s" + +msgid "E1416: Enum cannot extend a class or enum" +msgstr "E1416: Enümerasyon, bir sınıfı veya enümerasyonu geniÅŸletemez" + +msgid "E1417: Abstract cannot be used in an Enum" +msgstr "E1417: Abstract yalnızca bir enümerasyonda kullanılabilir" + +#, c-format +msgid "E1418: Invalid enum value declaration: %s" +msgstr "E1418: Geçersiz enümerasyon deÄŸeri beyanı: %s" + +#, c-format +msgid "E1419: Not a valid command in an Enum: %s" +msgstr "E1419: Bir enümerasyonda geçerli olmayan bir komut: %s" + +msgid "E1420: Missing :endenum" +msgstr "E1420: :endenum eksik" + +#, c-format +msgid "E1421: Enum \"%s\" cannot be used as a value" +msgstr "E1421: \"%s\" enümerasyonu yalnızca bir deÄŸer olarak kullanılabilir" + +#, c-format +msgid "E1422: Enum value \"%s\" not found in enum \"%s\"" +msgstr "E1422: \"%2$s\" enümerasyonunda \"%1$s\" deÄŸeri bulunamadı" + +#, c-format +msgid "E1423: Enum value \"%s.%s\" cannot be modified" +msgstr "E1423: Enümerasyon deÄŸeri \"%s.%s\" deÄŸiÅŸtirilemiyor" + +#, c-format +msgid "E1424: Using an Enum \"%s\" as a Number" +msgstr "E1424: Enümerasyon \"%s\", sayı olarak kullanılıyor" + +#, c-format +msgid "E1425: Using an Enum \"%s\" as a String" +msgstr "E1425: Enümerasyon \"%s\", dizi olarak kullanılıyor" + +#, c-format +msgid "E1426: Enum \"%s\" ordinal value cannot be modified" +msgstr "E1426: Enümerasyon sıralı deÄŸeri \"%s\" deÄŸiÅŸtirilemiyor" + +#, c-format +msgid "E1427: Enum \"%s\" name cannot be modified" +msgstr "E1427: Enümerasyon adı \"%s\" deÄŸiÅŸtirilemiyor" + +#, c-format +msgid "E1428: Duplicate enum value: %s" +msgstr "E1428: Yinelenen enümerasyon deÄŸeri: %s" + +msgid "E1429: Class can only be used in a script" +msgstr "E1429: Sınıf yalnızca bir betikte kullanılabilir" + +#, c-format msgid "E1500: Cannot mix positional and non-positional arguments: %s" msgstr "E1500: Konumsal ve konumsal olmayan argümanlar karıştırılamıyor: %s" @@ -8724,6 +8820,17 @@ msgstr "E1509: GeniÅŸletilmiÅŸ öznitelik okunurken veya yazılırken hata oluÅŸ msgid "E1510: Value too large: %s" msgstr "E1510: DeÄŸer pek büyük: %s" +#, c-format +msgid "E1511: Wrong number of characters for field \"%s\"" +msgstr "E1511: \"%s\" alanı için yanlış karakter sayısı" + +#, c-format +msgid "E1512: Wrong character width for field \"%s\"" +msgstr "E1512: \"%s\" alanı için yanlış karakter geniÅŸliÄŸi" + +msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled" +msgstr "E1513: Arabellek deÄŸiÅŸtirilemiyor. 'winfixbuf' etkinleÅŸtirilmiÅŸ" + msgid "--No lines in buffer--" msgstr "--Arabellek içinde satır yok--" @@ -9442,6 +9549,9 @@ msgstr "geçerli pencere için kullanılan en az satır sayısı" msgid "minimal number of lines used for any window" msgstr "herhangi bir pencere için kullanılan en az satır sayısı" +msgid "keep window focused on a single buffer" +msgstr "pencereyi tek bir arabelleÄŸe odaklı tut" + msgid "keep the height of the window" msgstr "pencerenin yüksekliÄŸini tut" diff --git a/src/po/uk.cp1251.po b/src/po/uk.cp1251.po index 40d87f5..1a14b2a 100644 --- a/src/po/uk.cp1251.po +++ b/src/po/uk.cp1251.po @@ -1386,8 +1386,8 @@ msgstr " Êîðèñòóâàöüêå äîïîâíåííÿ (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Êì³òëèâå äîïîâíåííÿ (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Îðôîãðàô³÷íà ï³äêàçêà (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Îðôîãðàô³÷íà ï³äêàçêà (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Äîïîâíåííÿ ì³ñöåâèõ êëþ÷îâèõ ñë³â (^N^P)" diff --git a/src/po/uk.po b/src/po/uk.po index 273f833..d756d45 100644 --- a/src/po/uk.po +++ b/src/po/uk.po @@ -1386,8 +1386,8 @@ msgstr " КориÑтувацьке Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Кмітливе Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Орфографічна підказка (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Орфографічна підказка (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¼Ñ–Ñцевих ключових Ñлів (^N^P)" diff --git a/src/po/zh_CN.UTF-8.po b/src/po/zh_CN.UTF-8.po index e604188..f368f6f 100644 --- a/src/po/zh_CN.UTF-8.po +++ b/src/po/zh_CN.UTF-8.po @@ -1291,8 +1291,8 @@ msgstr " 用户自定义补全 (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " 全能补全 (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " 拼写建议 (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " 拼写建议 (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " 关键å—局部补全 (^N^P)" diff --git a/src/po/zh_CN.cp936.po b/src/po/zh_CN.cp936.po index ef3dfa8..89b4bfc 100644 --- a/src/po/zh_CN.cp936.po +++ b/src/po/zh_CN.cp936.po @@ -23,7 +23,7 @@ msgstr "" "Language-Team: Simplified Chinese\n" "Language: \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=gbk\n" +"Content-Type: text/plain; charset=GBK\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" @@ -1291,8 +1291,8 @@ msgstr " Óû§×Ô¶¨Ò岹ȫ (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " È«Äܲ¹È« (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " ƴд½¨Òé (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " ƴд½¨Òé (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ¹Ø¼ü×Ö¾Ö²¿²¹È« (^N^P)" diff --git a/src/po/zh_CN.po b/src/po/zh_CN.po index 4e34616..8e4571d 100644 --- a/src/po/zh_CN.po +++ b/src/po/zh_CN.po @@ -23,7 +23,7 @@ msgstr "" "Language-Team: Simplified Chinese\n" "Language: \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=gb2312\n" +"Content-Type: text/plain; charset=GB2312\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" @@ -1291,8 +1291,8 @@ msgstr " Óû§×Ô¶¨Ò岹ȫ (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " È«Äܲ¹È« (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " ƴд½¨Òé (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " ƴд½¨Òé (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ¹Ø¼ü×Ö¾Ö²¿²¹È« (^N^P)" diff --git a/src/po/zh_TW.po b/src/po/zh_TW.po index 2cedfd4..e37f90d 100644 --- a/src/po/zh_TW.po +++ b/src/po/zh_TW.po @@ -51,7 +51,7 @@ msgstr "" "Language-Team: Hung-Te Lin <piaip@csie.ntu.edu.tw>, Cecil Sheng " "<b7506022@csie.ntu.edu.tw>\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=big5\n" +"Content-Type: text/plain; charset=BIG5\n" "Content-Transfer-Encoding: 8-bit\n" msgid "E82: Cannot allocate any buffer, exiting..." diff --git a/src/popupmenu.c b/src/popupmenu.c index 6e9d826..da8241b 100644 --- a/src/popupmenu.c +++ b/src/popupmenu.c @@ -425,7 +425,7 @@ pum_under_menu(int row, int col, int only_redrawing) * Returns attributes for every cell, or NULL if all attributes are the same. */ static int * -pum_compute_text_attrs(char_u *text, hlf_T hlf) +pum_compute_text_attrs(char_u *text, hlf_T hlf, int user_hlattr) { int i; size_t leader_len; @@ -483,6 +483,9 @@ pum_compute_text_attrs(char_u *text, hlf_T hlf) else if (matched_start && ptr < text + leader_len) new_attr = highlight_attr[hlf == HLF_PSI ? HLF_PMSI : HLF_PMNI]; + if (user_hlattr > 0) + new_attr = hl_combine_attr(new_attr, user_hlattr); + char_cells = mb_ptr2cells(ptr); for (i = 0; i < char_cells; i++) attrs[cell_idx + i] = new_attr; @@ -527,7 +530,7 @@ pum_screen_puts_with_attrs( else #endif attr = attrs[col - col_start]; - screen_puts_len(ptr, char_len, row, col, attr); + screen_puts_len(ptr, char_len, row, col, attr); col += mb_ptr2cells(ptr); ptr += char_len; } @@ -628,6 +631,10 @@ pum_redraw(void) { hlf = hlfs[round]; attr = highlight_attr[hlf]; + if (pum_array[idx].pum_user_hlattr > 0) + attr = hl_combine_attr(attr, pum_array[idx].pum_user_hlattr); + if (round == 1 && pum_array[idx].pum_user_kind_hlattr > 0) + attr = hl_combine_attr(attr, pum_array[idx].pum_user_kind_hlattr); width = 0; s = NULL; switch (round) @@ -656,7 +663,8 @@ pum_redraw(void) if (saved != NUL) *p = saved; - attrs = pum_compute_text_attrs(st, hlf); + int user_hlattr = pum_array[idx].pum_user_hlattr; + attrs = pum_compute_text_attrs(st, hlf, user_hlattr); #ifdef FEAT_RIGHTLEFT if (pum_rl) @@ -1332,9 +1340,10 @@ pum_set_event_info(dict_T *dict) static void pum_position_at_mouse(int min_width) { - if (Rows - mouse_row > pum_size) + if (Rows - mouse_row > pum_size || Rows - mouse_row > mouse_row) { - // Enough space below the mouse row. + // Enough space below the mouse row, + // or there is more space below the mouse row than above. pum_row = mouse_row + 1; if (pum_height > Rows - pum_row) pum_height = Rows - pum_row; @@ -1633,7 +1642,7 @@ pum_select_mouse_pos(void) { int idx = mouse_row - pum_row; - if (idx < 0 || idx >= pum_size) + if (idx < 0 || idx >= pum_height) pum_selected = -1; else if (*pum_array[idx].pum_text != NUL) pum_selected = idx; diff --git a/src/popupwin.c b/src/popupwin.c index 38c1c9e..0ff57fb 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -699,8 +699,8 @@ popup_highlight_curline(win_T *wp) if (syn_name2id((char_u *)linehl) == 0) linehl = "PmenuSel"; - sign_define_by_name(sign_name, NULL, (char_u *)linehl, - NULL, NULL, NULL, NULL); + sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL, + NULL, SIGN_DEF_PRIO); } sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name, @@ -2651,6 +2651,8 @@ f_popup_filter_yesno(typval_T *argvars, typval_T *rettv) return; c = *key; + if (c == CAR && need_wait_return) + return; if (c == K_SPECIAL && key[1] != NUL) c = TO_SPECIAL(key[1], key[2]); @@ -2844,6 +2846,54 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED) popup_adjust_position(wp); } +/* + * popup_setbuf({id}, {bufnr}) + */ + void +f_popup_setbuf(typval_T *argvars, typval_T *rettv UNUSED) +{ + int id; + win_T *wp; + buf_T *buf; + + rettv->v_type = VAR_BOOL; + rettv->vval.v_number = VVAL_FALSE; + + if (check_for_number_arg(argvars, 0) == FAIL + || check_for_buffer_arg(argvars, 1) == FAIL) + return; + + id = (int)tv_get_number(&argvars[0]); + wp = find_popup_win(id); + if (wp == NULL) + return; + + buf = tv_get_buf_from_arg(&argvars[1]); + + if (buf == NULL) + return; +#ifdef FEAT_TERMINAL + if (buf->b_term != NULL && popup_terminal_exists()) + { + emsg(_(e_cannot_open_second_popup_with_terminal)); + return; + } +#endif + + if (wp->w_buffer != buf) + { + wp->w_buffer->b_nwindows--; + win_init_popup_win(wp, buf); + set_local_options_default(wp, FALSE); + swap_exists_action = SEA_READONLY; + buffer_ensure_loaded(buf); + swap_exists_action = SEA_NONE; + redraw_win_later(wp, UPD_NOT_VALID); + popup_adjust_position(wp); + } + rettv->vval.v_number = VVAL_TRUE; +} + static void popup_free(win_T *wp) { diff --git a/src/proto/autocmd.pro b/src/proto/autocmd.pro index 4a502da..920987a 100644 --- a/src/proto/autocmd.pro +++ b/src/proto/autocmd.pro @@ -26,6 +26,7 @@ int has_textchanged(void); int has_textchangedI(void); int has_textchangedP(void); int has_insertcharpre(void); +int has_keyinputpre(void); int has_cmdundefined(void); int has_textyankpost(void); int has_completechanged(void); diff --git a/src/proto/dict.pro b/src/proto/dict.pro index 346e1d5..b1ceecc 100644 --- a/src/proto/dict.pro +++ b/src/proto/dict.pro @@ -40,7 +40,7 @@ int eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal); int eval_lit_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg); void dict_extend(dict_T *d1, dict_T *d2, char_u *action, char *func_name); dictitem_T *dict_lookup(hashitem_T *hi); -int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive); +int dict_equal(dict_T *d1, dict_T *d2, int ic); long dict_count(dict_T *d, typval_T *needle, int ic); void dict_extend_func(typval_T *argvars, type_T *type, char *func_name, char_u *arg_errmsg, int is_new, typval_T *rettv); void dict_filter_map(dict_T *d, filtermap_T filtermap, type_T *argtype, char *func_name, char_u *arg_errmsg, typval_T *expr, typval_T *rettv); diff --git a/src/proto/findfile.pro b/src/proto/findfile.pro index 9560101..1c28221 100644 --- a/src/proto/findfile.pro +++ b/src/proto/findfile.pro @@ -12,7 +12,7 @@ char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum); char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u *rel_fname, linenr_T *file_lnum); char_u *find_file_name_in_path(char_u *ptr, int len, int options, long count, char_u *rel_fname); int vim_ispathlistsep(int c); -void uniquefy_paths(garray_T *gap, char_u *pattern); +void uniquefy_paths(garray_T *gap, char_u *pattern, char_u *path_option); int expand_in_path(garray_T *gap, char_u *pattern, int flags); void simplify_filename(char_u *filename); void f_simplify(typval_T *argvars, typval_T *rettv); diff --git a/src/proto/list.pro b/src/proto/list.pro index 1659b8f..27bea5e 100644 --- a/src/proto/list.pro +++ b/src/proto/list.pro @@ -16,7 +16,7 @@ listitem_T *listitem_alloc(void); void listitem_free(list_T *l, listitem_T *item); void listitem_remove(list_T *l, listitem_T *item); long list_len(list_T *l); -int list_equal(list_T *l1, list_T *l2, int ic, int recursive); +int list_equal(list_T *l1, list_T *l2, int ic); listitem_T *list_find(list_T *l, long n); long list_find_nr(list_T *l, long idx, int *errorp); char_u *list_find_str(list_T *l, long idx); diff --git a/src/proto/mark.pro b/src/proto/mark.pro index cc45f0d..d398c36 100644 --- a/src/proto/mark.pro +++ b/src/proto/mark.pro @@ -28,4 +28,5 @@ void set_last_cursor(win_T *win); void free_all_marks(void); xfmark_T *get_namedfm(void); void f_getmarklist(typval_T *argvars, typval_T *rettv); +void mark_forget_file(win_T *wp, int fnum); /* vim: set ft=c : */ diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro index c57c94c..bb976e3 100644 --- a/src/proto/mbyte.pro +++ b/src/proto/mbyte.pro @@ -48,6 +48,7 @@ int utf_islower(int a); int utf_tolower(int a); int utf_isupper(int a); int mb_strnicmp(char_u *s1, char_u *s2, size_t nn); +int mb_strnicmp2(char_u *s1, char_u *s2, size_t n1, size_t n2); void show_utf8(void); int latin_head_off(char_u *base, char_u *p); int dbcs_screen_head_off(char_u *base, char_u *p); diff --git a/src/proto/memline.pro b/src/proto/memline.pro index c5d9b5d..238bcea 100644 --- a/src/proto/memline.pro +++ b/src/proto/memline.pro @@ -11,7 +11,7 @@ void ml_close_notmod(void); void ml_timestamp(buf_T *buf); void ml_recover(int checkext); int recover_names(char_u *fname, int do_list, list_T *ret_list, int nr, char_u **fname_out); -char_u *make_percent_swname(char_u *dir, char_u *name); +char_u *make_percent_swname(char_u *dir, char_u *dir_end, char_u *name); void get_b0_dict(char_u *fname, dict_T *d); void ml_sync_all(int check_file, int check_char); void ml_preserve(buf_T *buf, int message); diff --git a/src/proto/option.pro b/src/proto/option.pro index 69463d4..1659131 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -69,6 +69,7 @@ char *did_set_showtabline(optset_T *args); char *did_set_smoothscroll(optset_T *args); char *did_set_spell(optset_T *args); char *did_set_swapfile(optset_T *args); +char *did_set_tabclose(optset_T *args); char *did_set_termguicolors(optset_T *args); char *did_set_terse(optset_T *args); char *did_set_textauto(optset_T *args); diff --git a/src/proto/optionstr.pro b/src/proto/optionstr.pro index 340ffc4..39c40f3 100644 --- a/src/proto/optionstr.pro +++ b/src/proto/optionstr.pro @@ -156,6 +156,7 @@ char *did_set_swapsync(optset_T *args); int expand_set_swapsync(optexpand_T *args, int *numMatches, char_u ***matches); char *did_set_switchbuf(optset_T *args); int expand_set_switchbuf(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_tabclose(optexpand_T *args, int *numMatches, char_u ***matches); char *did_set_tabline(optset_T *args); char *did_set_tagcase(optset_T *args); int expand_set_tagcase(optexpand_T *args, int *numMatches, char_u ***matches); diff --git a/src/proto/os_mswin.pro b/src/proto/os_mswin.pro index 4731010..cde9cea 100644 --- a/src/proto/os_mswin.pro +++ b/src/proto/os_mswin.pro @@ -11,6 +11,7 @@ int mch_isFullName(char_u *fname); void slash_adjust(char_u *p); char_u *resolve_appexeclink(char_u *fname); int vim_stat(const char *name, stat_T *stp); +int vim_lstat(const char *name, stat_T *stp); void mch_settmode(tmode_T tmode); int mch_get_shellsize(void); void mch_set_shellsize(void); @@ -22,6 +23,7 @@ int mch_has_wildcard(char_u *p); int mch_chdir(char *path); int mch_icon_load(HANDLE *iconp); int mch_libcall(char_u *libname, char_u *funcname, char_u *argstring, int argint, char_u **string_result, int *number_result); +int mch_get_random(char_u *buf, int len); void DumpPutS(const char *psz); int mch_get_winpos(int *x, int *y); void mch_set_winpos(int x, int y); diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro index 6e13de6..d9dc8d9 100644 --- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -76,6 +76,7 @@ int mch_rename(const char *src, const char *dest); int gpm_available(void); int gpm_enabled(void); int mch_libcall(char_u *libname, char_u *funcname, char_u *argstring, int argint, char_u **string_result, int *number_result); +int mch_get_random(char_u *buf, int len); void setup_term_clip(void); void start_xterm_trace(int button); void stop_xterm_trace(void); diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro index 1ff9950..11679c6 100644 --- a/src/proto/popupwin.pro +++ b/src/proto/popupwin.pro @@ -34,6 +34,7 @@ void f_popup_hide(typval_T *argvars, typval_T *rettv); void popup_show(win_T *wp); void f_popup_show(typval_T *argvars, typval_T *rettv); void f_popup_settext(typval_T *argvars, typval_T *rettv); +void f_popup_setbuf(typval_T *argvars, typval_T *rettv); int error_if_popup_window(int also_with_term); int popup_close(int id, int force); int popup_close_tabpage(tabpage_T *tp, int id, int force); diff --git a/src/proto/search.pro b/src/proto/search.pro index 08526c8..8665994 100644 --- a/src/proto/search.pro +++ b/src/proto/search.pro @@ -41,6 +41,7 @@ void f_matchfuzzy(typval_T *argvars, typval_T *rettv); void f_matchfuzzypos(typval_T *argvars, typval_T *rettv); int fuzzy_match_str(char_u *str, char_u *pat); garray_T *fuzzy_match_str_with_pos(char_u *str, char_u *pat); +int search_for_fuzzy_match(buf_T *buf, pos_T *pos, char_u *pattern, int dir, pos_T *start_pos, int *len, char_u **ptr, int whole_line); void fuzmatch_str_free(fuzmatch_str_T *fuzmatch, int count); int fuzzymatches_to_strmatches(fuzmatch_str_T *fuzmatch, char_u ***matches, int count, int funcsort); /* vim: set ft=c : */ diff --git a/src/proto/sign.pro b/src/proto/sign.pro index a042bad..1cca0a6 100644 --- a/src/proto/sign.pro +++ b/src/proto/sign.pro @@ -8,7 +8,7 @@ int buf_findsigntype_id(buf_T *buf, linenr_T lnum, int typenr); int buf_signcount(buf_T *buf, linenr_T lnum); void buf_delete_signs(buf_T *buf, char_u *group); void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after); -int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl, char_u *numhl); +int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl, char_u *numhl, int prio); int sign_exists_by_name(char_u *name); int sign_undefine_by_name(char_u *name, int give_error); int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio); diff --git a/src/proto/tag.pro b/src/proto/tag.pro index 6de463e..eec7c24 100644 --- a/src/proto/tag.pro +++ b/src/proto/tag.pro @@ -14,4 +14,5 @@ int expand_tags(int tagnames, char_u *pat, int *num_file, char_u ***file); int get_tags(list_T *list, char_u *pat, char_u *buf_fname); void get_tagstack(win_T *wp, dict_T *retdict); int set_tagstack(win_T *wp, dict_T *d, int action); +void tagstack_clear_entry(taggy_T *item); /* vim: set ft=c : */ diff --git a/src/proto/typval.pro b/src/proto/typval.pro index b6ea131..1edfeb4 100644 --- a/src/proto/typval.pro +++ b/src/proto/typval.pro @@ -68,14 +68,13 @@ int typval_compare(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic); int typval_compare_list(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); int typval_compare_null(typval_T *tv1, typval_T *tv2); int typval_compare_blob(typval_T *tv1, typval_T *tv2, exprtype_T type, int *res); -int typval_compare_class(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); int typval_compare_object(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); int typval_compare_dict(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); int typval_compare_func(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); int typval_compare_string(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); char_u *typval_tostring(typval_T *arg, int quotes); int tv_islocked(typval_T *tv); -int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive); +int tv_equal(typval_T *tv1, typval_T *tv2, int ic); int eval_option(char_u **arg, typval_T *rettv, int evaluate); int eval_number(char_u **arg, typval_T *rettv, int evaluate, int want_string); int eval_string(char_u **arg, typval_T *rettv, int evaluate, int interpolate); diff --git a/src/proto/userfunc.pro b/src/proto/userfunc.pro index 9bb4616..32dac66 100644 --- a/src/proto/userfunc.pro +++ b/src/proto/userfunc.pro @@ -39,7 +39,7 @@ int call_callback(callback_T *callback, int len, typval_T *rettv, int argcount, varnumber_T call_callback_retnr(callback_T *callback, int argcount, typval_T *argvars); void user_func_error(funcerror_T error, char_u *name, int found_var); int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in, funcexe_T *funcexe); -int call_simple_func(char_u *funcname, int len, typval_T *rettv); +int call_simple_func(char_u *funcname, size_t len, typval_T *rettv); char_u *printable_func_name(ufunc_T *fp); char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags); char_u *trans_function_name_ext(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial, type_T **type, ufunc_T **ufunc); @@ -95,4 +95,5 @@ int set_ref_in_call_stack(int copyID); int set_ref_in_functions(int copyID); int set_ref_in_func_args(int copyID); int set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID); +int get_func_arity(char_u *name, int *required, int *optional, int *varargs); /* vim: set ft=c : */ diff --git a/src/proto/vim9class.pro b/src/proto/vim9class.pro index 1b5800c..c87fffb 100644 --- a/src/proto/vim9class.pro +++ b/src/proto/vim9class.pro @@ -40,6 +40,7 @@ int is_class_name(char_u *name, typval_T *rettv); void protected_method_access_errmsg(char_u *method_name); int object_empty(object_T *obj); int object_len(object_T *obj); +int object_equal(object_T *o1, object_T *o2, int ic); char_u *object2string(object_T *obj, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int composite_val); int class_instance_of(class_T *cl, class_T *other_cl); void f_instanceof(typval_T *argvars, typval_T *rettv); diff --git a/src/proto/vim9instr.pro b/src/proto/vim9instr.pro index 1b2f79c..8ee33b8 100644 --- a/src/proto/vim9instr.pro +++ b/src/proto/vim9instr.pro @@ -58,7 +58,7 @@ int check_internal_func_args(cctx_T *cctx, int func_idx, int argcount, int metho int generate_BCALL(cctx_T *cctx, int func_idx, int argcount, int method_call); int generate_LISTAPPEND(cctx_T *cctx); int generate_BLOBAPPEND(cctx_T *cctx); -int generate_CALL(cctx_T *cctx, ufunc_T *ufunc, class_T *cl, int mi, int pushed_argcount); +int generate_CALL(cctx_T *cctx, ufunc_T *ufunc, class_T *cl, int mi, int pushed_argcount, int is_super); int generate_UCALL(cctx_T *cctx, char_u *name, int argcount); int check_func_args_from_type(cctx_T *cctx, type_T *type, int argcount, int at_top, char_u *name); int generate_PCALL(cctx_T *cctx, int argcount, char_u *name, type_T *type, int at_top); diff --git a/src/proto/window.pro b/src/proto/window.pro index 26c7040..441070e 100644 --- a/src/proto/window.pro +++ b/src/proto/window.pro @@ -100,4 +100,5 @@ int get_win_number(win_T *wp, win_T *first_win); int get_tab_number(tabpage_T *tp); char *check_colorcolumn(win_T *wp); int get_last_winid(void); +int win_locked(win_T *wp); /* vim: set ft=c : */ diff --git a/src/regexp.c b/src/regexp.c index ff201d9..b020a43 100644 --- a/src/regexp.c +++ b/src/regexp.c @@ -1729,7 +1729,9 @@ mb_decompose(int c, int *c1, int *c2, int *c3) /* * Compare two strings, ignore case if rex.reg_ic set. * Return 0 if strings match, non-zero otherwise. - * Correct the length "*n" when composing characters are ignored. + * Correct the length "*n" when composing characters are ignored + * or for utf8 when both utf codepoints are considered equal because of + * case-folding but have different length (e.g. 's' and 'Å¿') */ static int cstrncmp(char_u *s1, char_u *s2, int *n) @@ -1738,6 +1740,29 @@ cstrncmp(char_u *s1, char_u *s2, int *n) if (!rex.reg_ic) result = STRNCMP(s1, s2, *n); + else if (enc_utf8) + { + char_u *p = s1; + int n2 = 0; + int n1 = *n; + // count the number of characters for byte-length of s1 + while (n1 > 0 && *p != NUL) + { + n1 -= mb_ptr2len(s1); + MB_PTR_ADV(p); + n2++; + } + // count the number of bytes to advance the same number of chars for s2 + p = s2; + while (n2-- > 0 && *p != NUL) + MB_PTR_ADV(p); + + n2 = p - s2; + + result = MB_STRNICMP2(s1, s2, *n, n2); + if (result == 0 && n2 < *n) + *n = n2; + } else result = MB_STRNICMP(s1, s2, *n); @@ -1787,7 +1812,7 @@ cstrncmp(char_u *s1, char_u *s2, int *n) cstrchr(char_u *s, int c) { char_u *p; - int cc; + int cc, lc; if (!rex.reg_ic || (!enc_utf8 && mb_char2len(c) > 1)) return vim_strchr(s, c); @@ -1796,26 +1821,35 @@ cstrchr(char_u *s, int c) // faster (esp. when using MS Visual C++!). // For UTF-8 need to use folded case. if (enc_utf8 && c > 0x80) + { cc = utf_fold(c); + lc = cc; + } else - if (MB_ISUPPER(c)) - cc = MB_TOLOWER(c); - else if (MB_ISLOWER(c)) - cc = MB_TOUPPER(c); - else - return vim_strchr(s, c); + if (MB_ISUPPER(c)) + { + cc = MB_TOLOWER(c); + lc = cc; + } + else if (MB_ISLOWER(c)) + { + cc = MB_TOUPPER(c); + lc = c; + } + else + return vim_strchr(s, c); if (has_mbyte) { for (p = s; *p != NUL; p += (*mb_ptr2len)(p)) { - if (enc_utf8 && c > 0x80) + int uc = utf_ptr2char(p); + if (enc_utf8 && (c > 0x80 || uc > 0x80)) { - int uc = utf_ptr2char(p); - // Do not match an illegal byte. E.g. 0xff matches 0xc3 0xbf, // not 0xff. - if ((uc < 0x80 || uc != *p) && utf_fold(uc) == cc) + // compare with lower case of the character + if ((uc < 0x80 || uc != *p) && utf_fold(uc) == lc) return p; } else if (*p == c || *p == cc) diff --git a/src/regexp_bt.c b/src/regexp_bt.c index 5452dda..16dac73 100644 --- a/src/regexp_bt.c +++ b/src/regexp_bt.c @@ -3823,6 +3823,14 @@ regmatch( } } } + else if (enc_utf8) + { + if (cstrncmp(opnd, rex.input, &len) != 0) + { + status = RA_NOMATCH; + break; + } + } else for (i = 0; i < len; ++i) if (opnd[i] != rex.input[i]) diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index 4f07a21..6db4134 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -5666,7 +5666,12 @@ find_match_text(colnr_T *startcol, int regstart, char_u *match_text) for (;;) { match = TRUE; - len2 = MB_CHAR2LEN(regstart); // skip regstart + // skip regstart + len2 = MB_CHAR2LEN(regstart); + if (enc_utf8 && len2 > 1 && MB_CHAR2LEN(PTR2CHAR(rex.line + col)) != len2) + // because of case-folding of the previously matched text, we may need + // to skip fewer bytes than mb_char2len(regstart) + len2 = mb_char2len(utf_fold(regstart)); for (len1 = 0; match_text[len1] != NUL; len1 += MB_CHAR2LEN(c1)) { c1 = PTR2CHAR(match_text + len1); @@ -7502,7 +7507,7 @@ nfa_regexec_both( // If match_text is set it contains the full text that must match. // Nothing else to try. Doesn't handle combining chars well. - if (prog->match_text != NULL && !rex.reg_icombine) + if (prog->match_text != NULL && *prog->match_text != NUL && !rex.reg_icombine) { retval = find_match_text(&col, prog->regstart, prog->match_text); if (REG_MULTI) diff --git a/src/search.c b/src/search.c index 0b39d90..e5936d8 100644 --- a/src/search.c +++ b/src/search.c @@ -53,6 +53,7 @@ static int fuzzy_match_str_compare(const void *s1, const void *s2); static void fuzzy_match_str_sort(fuzmatch_str_T *fm, int sz); static int fuzzy_match_func_compare(const void *s1, const void *s2); static void fuzzy_match_func_sort(fuzmatch_str_T *fm, int sz); +static int fuzzy_match_str_in_line(char_u **ptr, char_u *pat, int *len, pos_T *current_pos); #define SEARCH_STAT_DEF_TIMEOUT 40L #define SEARCH_STAT_DEF_MAX_COUNT 99 @@ -1547,6 +1548,7 @@ do_search( { vim_free(msgbuf); msgbuf = r; + msgbuflen = STRLEN(msgbuf); // move reversed text to beginning of buffer while (*r != NUL && *r == ' ') r++; @@ -5106,11 +5108,11 @@ fuzzy_match_str_with_pos(char_u *str UNUSED, char_u *pat UNUSED) int j = 0; if (str == NULL || pat == NULL) - return NULL; + return NULL; match_positions = ALLOC_ONE(garray_T); if (match_positions == NULL) - return NULL; + return NULL; ga_init2(match_positions, sizeof(int_u), 10); if (!fuzzy_match(str, pat, FALSE, &score, matches, MAX_FUZZY_MATCHES) @@ -5140,6 +5142,172 @@ fuzzy_match_str_with_pos(char_u *str UNUSED, char_u *pat UNUSED) } /* + * This function searches for a fuzzy match of the pattern `pat` within the + * line pointed to by `*ptr`. It splits the line into words, performs fuzzy + * matching on each word, and returns the length and position of the first + * matched word. + */ + static int +fuzzy_match_str_in_line(char_u **ptr, char_u *pat, int *len, pos_T *current_pos) +{ + char_u *str = *ptr; + char_u *strBegin = str; + char_u *end = NULL; + char_u *start = NULL; + int found = FALSE; + int result; + char save_end; + + if (str == NULL || pat == NULL) + return found; + + while (*str != NUL) + { + // Skip non-word characters + start = find_word_start(str); + if (*start == NUL) + break; + end = find_word_end(start); + + // Extract the word from start to end + save_end = *end; + *end = NUL; + + // Perform fuzzy match + result = fuzzy_match_str(start, pat); + *end = save_end; + + if (result > 0) + { + *len = (int)(end - start); + current_pos->col += (int)(end - strBegin); + found = TRUE; + *ptr = start; + break; + } + + // Move to the end of the current word for the next iteration + str = end; + // Ensure we continue searching after the current word + while (*str != NUL && !vim_iswordp(str)) + MB_PTR_ADV(str); + } + + return found; +} + +/* + * Search for the next fuzzy match in the specified buffer. + * This function attempts to find the next occurrence of the given pattern + * in the buffer, starting from the current position. It handles line wrapping + * and direction of search. + * + * Return TRUE if a match is found, otherwise FALSE. + */ + int +search_for_fuzzy_match( + buf_T *buf, + pos_T *pos, + char_u *pattern, + int dir, + pos_T *start_pos, + int *len, + char_u **ptr, + int whole_line) +{ + pos_T current_pos = *pos; + pos_T circly_end; + int found_new_match = FAIL; + int looped_around = FALSE; + + if (whole_line) + current_pos.lnum += dir; + + if (buf == curbuf) + circly_end = *start_pos; + else + { + circly_end.lnum = buf->b_ml.ml_line_count; + circly_end.col = 0; + circly_end.coladd = 0; + } + + do { + + // Check if looped around and back to start position + if (looped_around && EQUAL_POS(current_pos, circly_end)) + break; + + // Ensure current_pos is valid + if (current_pos.lnum >= 1 && current_pos.lnum <= buf->b_ml.ml_line_count) + { + // Get the current line buffer + *ptr = ml_get_buf(buf, current_pos.lnum, FALSE); + // If ptr is end of line is reached, move to next line + // or previous line based on direction + if (**ptr != NUL) + { + if (!whole_line) + { + *ptr += current_pos.col; + // Try to find a fuzzy match in the current line starting from current position + found_new_match = fuzzy_match_str_in_line(ptr, pattern, len, ¤t_pos); + if (found_new_match) + { + *pos = current_pos; + break; + } + else if (looped_around && current_pos.lnum == circly_end.lnum) + break; + } + else + { + if (fuzzy_match_str(*ptr, pattern) > 0) + { + found_new_match = TRUE; + *pos = current_pos; + *len = (int)STRLEN(*ptr); + break; + } + } + } + } + + // Move to the next line or previous line based on direction + if (dir == FORWARD) + { + if (++current_pos.lnum > buf->b_ml.ml_line_count) + { + if (p_ws) + { + current_pos.lnum = 1; + looped_around = TRUE; + } + else + break; + } + } + else + { + if (--current_pos.lnum < 1) + { + if (p_ws) + { + current_pos.lnum = buf->b_ml.ml_line_count; + looped_around = TRUE; + } + else + break; + + } + } + current_pos.col = 0; + } while (TRUE); + + return found_new_match; +} + +/* * Free an array of fuzzy string matches "fuzmatch[count]". */ void @@ -34,6 +34,7 @@ struct sign int sn_text_hl; // highlight ID for text int sn_cul_hl; // highlight ID for text on current line when 'cursorline' is set int sn_num_hl; // highlight ID for line number + int sn_priority; // default priority of this sign, -1 means SIGN_DEF_PRIO }; static sign_T *first_sign = NULL; @@ -1047,7 +1048,8 @@ sign_define_by_name( char_u *text, char_u *texthl, char_u *culhl, - char_u *numhl) + char_u *numhl, + int prio) { sign_T *sp_prev; sign_T *sp; @@ -1083,6 +1085,8 @@ sign_define_by_name( if (text != NULL && (sign_define_init_text(sp, text) == FAIL)) return FAIL; + sp->sn_priority = prio; + if (linehl != NULL) { if (*linehl == NUL) @@ -1206,6 +1210,10 @@ sign_place( if (*sign_id == 0) *sign_id = sign_group_get_next_signid(buf, sign_group); + // Use the default priority value for this sign. + if (prio == -1) + prio = (sp->sn_priority != -1) ? sp->sn_priority : SIGN_DEF_PRIO; + if (lnum > 0) // ":sign place {id} line={lnum} name={name} file={fname}": // place a sign @@ -1338,6 +1346,7 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline) char_u *texthl = NULL; char_u *culhl = NULL; char_u *numhl = NULL; + int prio = -1; int failed = FALSE; // set values for a defined sign. @@ -1377,6 +1386,11 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline) arg += 6; numhl = vim_strnsave(arg, p - arg); } + else if (STRNCMP(arg, "priority=", 9) == 0) + { + arg += 9; + prio = atoi((char *)arg); + } else { semsg(_(e_invalid_argument_str), arg); @@ -1386,7 +1400,7 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline) } if (!failed) - sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, numhl); + sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, numhl, prio); vim_free(icon); vim_free(text); @@ -1721,7 +1735,7 @@ ex_sign(exarg_T *eap) linenr_T lnum = -1; char_u *sign_name = NULL; char_u *group = NULL; - int prio = SIGN_DEF_PRIO; + int prio = -1; // Parse command line arguments if (parse_sign_cmd_args(idx, arg, &sign_name, &id, &group, &prio, @@ -1750,6 +1764,8 @@ sign_getinfo(sign_T *sp, dict_T *retdict) dict_add_string(retdict, "icon", sp->sn_icon); if (sp->sn_text != NULL) dict_add_string(retdict, "text", sp->sn_text); + if (sp->sn_priority > 0) + dict_add_number(retdict, "priority", sp->sn_priority); if (sp->sn_line_hl > 0) { p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); @@ -1913,6 +1929,7 @@ sign_gui_started(void) sign_list_defined(sign_T *sp) { char_u *p; + char lbuf[MSG_BUF_LEN]; smsg("sign %s", sp->sn_name); if (sp->sn_icon != NULL) @@ -1931,6 +1948,11 @@ sign_list_defined(sign_T *sp) msg_puts(" text="); msg_outtrans(sp->sn_text); } + if (sp->sn_priority > 0) + { + vim_snprintf(lbuf, MSG_BUF_LEN, " priority=%d", sp->sn_priority); + msg_puts(lbuf); + } if (sp->sn_line_hl > 0) { msg_puts(" linehl="); @@ -2088,7 +2110,8 @@ get_sign_name(expand_T *xp UNUSED, int idx) { char *define_arg[] = { - "culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=", NULL + "culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=", "priority=", + NULL }; return (char_u *)define_arg[idx]; } @@ -2261,6 +2284,7 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict) char_u *texthl = NULL; char_u *culhl = NULL; char_u *numhl = NULL; + int prio = -1; int retval = -1; if (name_arg == NULL) @@ -2281,9 +2305,10 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict) texthl = dict_get_string(dict, "texthl", TRUE); culhl = dict_get_string(dict, "culhl", TRUE); numhl = dict_get_string(dict, "numhl", TRUE); + prio = dict_get_number_def(dict, "priority", -1); } - if (sign_define_by_name(name, icon, linehl, text, texthl, culhl, numhl) == OK) + if (sign_define_by_name(name, icon, linehl, text, texthl, culhl, numhl, prio) == OK) retval = 0; cleanup: @@ -2511,7 +2536,7 @@ sign_place_from_dict( buf_T *buf = NULL; dictitem_T *di; linenr_T lnum = 0; - int prio = SIGN_DEF_PRIO; + int prio = -1; int notanum = FALSE; int ret_sign_id = -1; diff --git a/src/spellfile.c b/src/spellfile.c index 51261ab..0b9536d 100644 --- a/src/spellfile.c +++ b/src/spellfile.c @@ -6434,7 +6434,13 @@ init_spellfile(void) l = (int)STRLEN(buf); vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell"); if (filewritable(buf) != 2) - vim_mkdir(buf, 0755); + { + if (vim_mkdir(buf, 0755) != 0) + { + vim_free(buf); + return; + } + } l = (int)STRLEN(buf); vim_snprintf((char *)buf + l, MAXPATHL - l, diff --git a/src/strings.c b/src/strings.c index 6b2ff0a..b8ea00b 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1037,7 +1037,7 @@ string_reduce( * Implementation of "byteidx()" and "byteidxcomp()" functions */ static void -byteidx_common(typval_T *argvars, typval_T *rettv, int comp UNUSED) +byteidx_common(typval_T *argvars, typval_T *rettv, int comp) { rettv->vval.v_number = -1; @@ -2497,7 +2497,8 @@ format_overflow_error(const char *pstart) get_unsigned_int( const char *pstart, const char **p, - unsigned int *uj) + unsigned int *uj, + int overflow_err) { *uj = **p - '0'; ++*p; @@ -2510,8 +2511,13 @@ get_unsigned_int( if (*uj > MAX_ALLOWED_STRING_WIDTH) { - format_overflow_error(pstart); - return FAIL; + if (overflow_err) + { + format_overflow_error(pstart); + return FAIL; + } + else + *uj = MAX_ALLOWED_STRING_WIDTH; } return OK; @@ -2584,7 +2590,7 @@ parse_fmt_types( // Positional argument unsigned int uj; - if (get_unsigned_int(pstart, &p, &uj) == FAIL) + if (get_unsigned_int(pstart, &p, &uj, tvs != NULL) == FAIL) goto error; pos_arg = uj; @@ -2625,7 +2631,7 @@ parse_fmt_types( // Positional argument field width unsigned int uj; - if (get_unsigned_int(arg + 1, &p, &uj) == FAIL) + if (get_unsigned_int(arg + 1, &p, &uj, tvs != NULL) == FAIL) goto error; if (*p != '$') @@ -2656,7 +2662,7 @@ parse_fmt_types( const char *digstart = p; unsigned int uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) goto error; if (*p == '$') @@ -2680,7 +2686,7 @@ parse_fmt_types( // Parse precision unsigned int uj; - if (get_unsigned_int(arg + 1, &p, &uj) == FAIL) + if (get_unsigned_int(arg + 1, &p, &uj, tvs != NULL) == FAIL) goto error; if (*p == '$') @@ -2712,7 +2718,7 @@ parse_fmt_types( const char *digstart = p; unsigned int uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) goto error; if (*p == '$') @@ -3025,7 +3031,7 @@ vim_vsnprintf_typval( const char *digstart = p; unsigned int uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) goto error; pos_arg = uj; @@ -3067,7 +3073,7 @@ vim_vsnprintf_typval( // Positional argument field width unsigned int uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) goto error; arg_idx = uj; @@ -3085,8 +3091,13 @@ vim_vsnprintf_typval( if (j > MAX_ALLOWED_STRING_WIDTH) { - format_overflow_error(digstart); - goto error; + if (tvs != NULL) + { + format_overflow_error(digstart); + goto error; + } + else + j = MAX_ALLOWED_STRING_WIDTH; } if (j >= 0) @@ -3104,14 +3115,8 @@ vim_vsnprintf_typval( const char *digstart = p; unsigned int uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) - goto error; - - if (uj > MAX_ALLOWED_STRING_WIDTH) - { - format_overflow_error(digstart); + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) goto error; - } min_field_width = uj; } @@ -3129,15 +3134,9 @@ vim_vsnprintf_typval( const char *digstart = p; unsigned int uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) goto error; - if (uj > MAX_ALLOWED_STRING_WIDTH) - { - format_overflow_error(digstart); - goto error; - } - precision = uj; } else if (*p == '*') @@ -3152,7 +3151,7 @@ vim_vsnprintf_typval( // positional argument unsigned int uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) goto error; arg_idx = uj; @@ -3170,8 +3169,13 @@ vim_vsnprintf_typval( if (j > MAX_ALLOWED_STRING_WIDTH) { - format_overflow_error(digstart); - goto error; + if (tvs != NULL) + { + format_overflow_error(digstart); + goto error; + } + else + j = MAX_ALLOWED_STRING_WIDTH; } if (j >= 0) diff --git a/src/structs.h b/src/structs.h index 7e21f0f..79f415d 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1309,6 +1309,9 @@ typedef struct mapblock mapblock_T; struct mapblock { mapblock_T *m_next; // next mapblock in list + mapblock_T *m_alt; // pointer to mapblock of the same mapping + // with an alternative form of m_keys, or NULL + // if there is no such mapblock char_u *m_keys; // mapped from, lhs char_u *m_str; // mapped to, rhs char_u *m_orig_str; // rhs as entered by the user @@ -3782,8 +3785,7 @@ struct window_S synblock_T *w_s; // for :ownsyntax #endif - int w_closing; // window is being closed, don't let - // autocommands close it too. + int w_locked; // don't let autocommands close the window frame_T *w_frame; // frame containing this window @@ -4466,12 +4468,14 @@ typedef struct */ typedef struct { - char_u *pum_text; // main menu text - char_u *pum_kind; // extra kind text (may be truncated) - char_u *pum_extra; // extra menu text (may be truncated) - char_u *pum_info; // extra info - int pum_score; // fuzzy match score - int pum_idx; // index of item before sorting by score + char_u *pum_text; // main menu text + char_u *pum_kind; // extra kind text (may be truncated) + char_u *pum_extra; // extra menu text (may be truncated) + char_u *pum_info; // extra info + int pum_score; // fuzzy match score + int pum_idx; // index of item before sorting by score + int pum_user_hlattr; // highlight attribute to combine with + int pum_user_kind_hlattr; // highlight attribute for kind } pumitem_T; /* @@ -4902,7 +4906,8 @@ typedef enum { WT_MEMBER, WT_METHOD, // object method WT_METHOD_ARG, // object method argument type - WT_METHOD_RETURN // object method return type + WT_METHOD_RETURN, // object method return type + WT_CAST, // type cast } wherekind_T; // Struct used to pass the location of a type check. Used in error messages to diff --git a/src/syntax.c b/src/syntax.c index 48e7152..eec5799 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -15,8 +15,6 @@ #if defined(FEAT_SYN_HL) || defined(PROTO) -#define SYN_NAMELEN 50 // maximum length of a syntax name - // different types of offsets that are possible #define SPO_MS_OFF 0 // match start offset #define SPO_ME_OFF 1 // match end offset @@ -323,6 +321,7 @@ static void limit_pos_zero(lpos_T *pos, lpos_T *limit); static void syn_add_end_off(lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, int extra); static void syn_add_start_off(lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, int extra); static char_u *syn_getcurline(void); +static colnr_T syn_getcurline_len(void); static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T *st); static int check_keyword_id(char_u *line, int startcol, int *endcol, long *flags, short **next_list, stateitem_T *cur_si, int *ccharp); static void syn_remove_pattern(synblock_T *block, int idx); @@ -2692,7 +2691,7 @@ update_si_end( // a "oneline" never continues in the next line sip->si_ends = TRUE; sip->si_m_endpos.lnum = current_lnum; - sip->si_m_endpos.col = (colnr_T)STRLEN(syn_getcurline()); + sip->si_m_endpos.col = syn_getcurline_len(); } else { @@ -3130,6 +3129,15 @@ syn_getcurline(void) } /* + * Get length of current line in syntax buffer. + */ + static colnr_T +syn_getcurline_len(void) +{ + return ml_get_buf_len(syn_buf, current_lnum); +} + +/* * Call vim_regexec() to find a match with "rmp" in "syn_buf". * Returns TRUE when there is a match. */ @@ -3935,13 +3943,7 @@ syn_match_msg(void) static int last_matchgroup; -struct name_list -{ - int flag; - char *name; -}; - -static void syn_list_flags(struct name_list *nl, int flags, int attr); +static void syn_list_flags(keyvalue_T *nlist, int nr_entries, int flags, int attr); /* * List one syntax item, for ":syntax" or "syntax list syntax_name". @@ -3956,28 +3958,27 @@ syn_list_one( int idx; int did_header = FALSE; synpat_T *spp; - static struct name_list namelist1[] = + static keyvalue_T namelist1[] = { - {HL_DISPLAY, "display"}, - {HL_CONTAINED, "contained"}, - {HL_ONELINE, "oneline"}, - {HL_KEEPEND, "keepend"}, - {HL_EXTEND, "extend"}, - {HL_EXCLUDENL, "excludenl"}, - {HL_TRANSP, "transparent"}, - {HL_FOLD, "fold"}, + KEYVALUE_ENTRY(HL_DISPLAY, "display"), + KEYVALUE_ENTRY(HL_CONTAINED, "contained"), + KEYVALUE_ENTRY(HL_ONELINE, "oneline"), + KEYVALUE_ENTRY(HL_KEEPEND, "keepend"), + KEYVALUE_ENTRY(HL_EXTEND, "extend"), + KEYVALUE_ENTRY(HL_EXCLUDENL, "excludenl"), + KEYVALUE_ENTRY(HL_TRANSP, "transparent"), + KEYVALUE_ENTRY(HL_FOLD, "fold") #ifdef FEAT_CONCEAL - {HL_CONCEAL, "conceal"}, - {HL_CONCEALENDS, "concealends"}, + , + KEYVALUE_ENTRY(HL_CONCEAL, "conceal"), + KEYVALUE_ENTRY(HL_CONCEALENDS, "concealends") #endif - {0, NULL} }; - static struct name_list namelist2[] = + static keyvalue_T namelist2[] = { - {HL_SKIPWHITE, "skipwhite"}, - {HL_SKIPNL, "skipnl"}, - {HL_SKIPEMPTY, "skipempty"}, - {0, NULL} + KEYVALUE_ENTRY(HL_SKIPWHITE, "skipwhite"), + KEYVALUE_ENTRY(HL_SKIPNL, "skipnl"), + KEYVALUE_ENTRY(HL_SKIPEMPTY, "skipempty") }; attr = HL_ATTR(HLF_D); // highlight like directories @@ -4017,7 +4018,7 @@ syn_list_one( --idx; msg_putchar(' '); } - syn_list_flags(namelist1, spp->sp_flags, attr); + syn_list_flags(namelist1, (int)ARRAY_LENGTH(namelist1), spp->sp_flags, attr); if (spp->sp_cont_list != NULL) put_id_list((char_u *)"contains", spp->sp_cont_list, attr); @@ -4029,7 +4030,7 @@ syn_list_one( if (spp->sp_next_list != NULL) { put_id_list((char_u *)"nextgroup", spp->sp_next_list, attr); - syn_list_flags(namelist2, spp->sp_flags, attr); + syn_list_flags(namelist2, (int)ARRAY_LENGTH(namelist2), spp->sp_flags, attr); } if (spp->sp_flags & (HL_SYNC_HERE|HL_SYNC_THERE)) { @@ -4058,14 +4059,14 @@ syn_list_one( } static void -syn_list_flags(struct name_list *nlist, int flags, int attr) +syn_list_flags(keyvalue_T *nlist, int nr_entries, int flags, int attr) { int i; - for (i = 0; nlist[i].flag != 0; ++i) - if (flags & nlist[i].flag) + for (i = 0; i < nr_entries; ++i) + if (flags & nlist[i].key) { - msg_puts_attr(nlist[i].name, attr); + msg_puts_attr(nlist[i].value, attr); msg_putchar(' '); } } @@ -4084,8 +4085,8 @@ syn_list_cluster(int id) if (msg_col >= endcol) // output at least one space endcol = msg_col + 1; - if (Columns <= endcol) // avoid hang for tiny window - endcol = Columns - 1; + if (Columns <= (long)endcol) // avoid hang for tiny window + endcol = (int)(Columns - 1); msg_advance(endcol); if (SYN_CLSTR(curwin->w_s)[id].scl_list != NULL) @@ -4393,6 +4394,7 @@ clear_keywtab(hashtab_T *ht) static void add_keyword( char_u *name, // name of keyword + size_t namelen, // length of keyword (excluding the NUL) int id, // group ID for this keyword int flags, // flags for this keyword short *cont_in_list, // containedin for this keyword @@ -4403,15 +4405,22 @@ add_keyword( hashtab_T *ht; hashitem_T *hi; char_u *name_ic; + size_t name_iclen; long_u hash; char_u name_folded[MAXKEYWLEN + 1]; if (curwin->w_s->b_syn_ic) - name_ic = str_foldcase(name, (int)STRLEN(name), + { + name_ic = str_foldcase(name, (int)namelen, name_folded, MAXKEYWLEN + 1); + name_iclen = STRLEN(name_ic); + } else + { name_ic = name; - kp = alloc(offsetof(keyentry_T, keyword) + STRLEN(name_ic) + 1); + name_iclen = namelen; + } + kp = alloc(offsetof(keyentry_T, keyword) + name_iclen + 1); if (kp == NULL) return; STRCPY(kp->keyword, name_ic); @@ -4828,19 +4837,26 @@ syn_cmd_keyword(exarg_T *eap, int syncing UNUSED) if (!eap->skip) { + size_t kwlen = 0; + // Adjust flags for use of ":syn include". syn_incl_toplevel(syn_id, &syn_opt_arg.flags); /* * 2: Add an entry for each keyword. */ - for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1) + for (kw = keyword_copy; --cnt >= 0; kw += kwlen + 1) { for (p = vim_strchr(kw, '['); ; ) { - if (p != NULL) + if (p == NULL) + kwlen = STRLEN(kw); + else + { *p = NUL; - add_keyword(kw, syn_id, syn_opt_arg.flags, + kwlen = (size_t)(p - kw); + } + add_keyword(kw, kwlen, syn_id, syn_opt_arg.flags, syn_opt_arg.cont_in_list, syn_opt_arg.next_list, conceal_char); if (p == NULL) @@ -4859,6 +4875,7 @@ syn_cmd_keyword(exarg_T *eap, int syncing UNUSED) goto error; } kw = p + 1; // skip over the "]" + kwlen = 1; break; } if (has_mbyte) @@ -6229,8 +6246,7 @@ static struct subcommand subcommands[] = {"reset", syn_cmd_reset}, {"spell", syn_cmd_spell}, {"sync", syn_cmd_sync}, - {"", syn_cmd_list}, - {NULL, NULL} + {"", syn_cmd_list} }; /* @@ -6257,13 +6273,8 @@ ex_syntax(exarg_T *eap) if (eap->skip) // skip error messages for all subcommands ++emsg_skip; - for (i = 0; ; ++i) + for (i = 0; i < (int)ARRAY_LENGTH(subcommands); ++i) { - if (subcommands[i].name == NULL) - { - semsg(_(e_invalid_syntax_subcommand_str), subcmd_name); - break; - } if (STRCMP(subcmd_name, (char_u *)subcommands[i].name) == 0) { eap->arg = skipwhite(subcmd_end); @@ -6271,6 +6282,10 @@ ex_syntax(exarg_T *eap) break; } } + + if (i == (int)ARRAY_LENGTH(subcommands)) + semsg(_(e_invalid_syntax_subcommand_str), subcmd_name); + vim_free(subcmd_name); if (eap->skip) --emsg_skip; @@ -6424,6 +6439,8 @@ get_syntax_name(expand_T *xp, int idx) switch (expand_what) { case EXP_SUBCMD: + if (idx < 0 || idx >= (int)ARRAY_LENGTH(subcommands)) + return NULL; return (char_u *)subcommands[idx].name; case EXP_CASE: { @@ -6697,6 +6714,7 @@ syntime_report(void) proftime_T tm; # endif int len; + int patlen; proftime_T total_total; int total_count = 0; garray_T ga; @@ -6768,8 +6786,9 @@ syntime_report(void) len = 20; // will wrap anyway else len = Columns - 70; - if (len > (int)STRLEN(p->pattern)) - len = (int)STRLEN(p->pattern); + patlen = (int)STRLEN(p->pattern); + if (len > patlen) + len = patlen; msg_outtrans_len(p->pattern, len); msg_puts("\n"); } @@ -144,7 +144,6 @@ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_ #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) static int add_llist_tags(char_u *tag, int num_matches, char_u **matches); #endif -static void tagstack_clear_entry(taggy_T *item); static char_u *tagmatchname = NULL; // name of last used tag @@ -311,7 +310,7 @@ do_tag( #endif if (postponed_split == 0 && !check_can_set_curbuf_forceit(forceit)) - return FALSE; + return FALSE; if (type == DT_HELP) { @@ -3413,6 +3412,11 @@ get_tagfname( // move the filename one char forward and truncate the // filepath with a NUL filename = gettail(buf); + if (r_ptr != NULL) + { + STRMOVE(r_ptr + 1, r_ptr); + ++r_ptr; + } STRMOVE(filename + 1, filename); *filename++ = NUL; @@ -3709,7 +3713,7 @@ jumpto_tag( char_u *lbuf; if (postponed_split == 0 && !check_can_set_curbuf_forceit(forceit)) - return FAIL; + return FAIL; // Make a copy of the line, it can become invalid when an autocommand calls // back here recursively. @@ -4233,7 +4237,7 @@ find_extra(char_u **pp) /* * Free a single entry in a tag stack */ - static void + void tagstack_clear_entry(taggy_T *item) { VIM_CLEAR(item->tagname); diff --git a/src/terminal.c b/src/terminal.c index 648fc78..073f8dd 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -3451,6 +3451,10 @@ limit_scrollback(term_T *term, garray_T *gap, int update_buffer) sizeof(sb_line_T) * gap->ga_len); if (update_buffer) term->tl_scrollback_scrolled -= todo; + + // make sure cursor is on a valid line + if (curbuf == term->tl_buffer) + check_cursor(); } /* @@ -3643,7 +3647,7 @@ term_after_channel_closed(term_T *term) if (term->tl_finish == TL_FINISH_CLOSE) { aco_save_T aco; - int do_set_w_closing = term->tl_buffer->b_nwindows == 0; + int do_set_w_locked = term->tl_buffer->b_nwindows == 0; #ifdef FEAT_PROP_POPUP win_T *pwin = NULL; @@ -3674,12 +3678,12 @@ term_after_channel_closed(term_T *term) { // Avoid closing the window if we temporarily use it. if (is_aucmd_win(curwin)) - do_set_w_closing = TRUE; - if (do_set_w_closing) - curwin->w_closing = TRUE; + do_set_w_locked = TRUE; + if (do_set_w_locked) + curwin->w_locked = TRUE; do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE); - if (do_set_w_closing) - curwin->w_closing = FALSE; + if (do_set_w_locked) + curwin->w_locked = FALSE; aucmd_restbuf(&aco); } #ifdef FEAT_PROP_POPUP @@ -6299,7 +6303,7 @@ f_term_getsize(typval_T *argvars, typval_T *rettv) * "term_setsize(buf, rows, cols)" function */ void -f_term_setsize(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +f_term_setsize(typval_T *argvars, typval_T *rettv UNUSED) { buf_T *buf; term_T *term; diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak index e31d2b5..67ef641 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -20,7 +20,8 @@ SCRIPTS_TINY = \ test24 \ test25 \ test26 \ - test27 + test27 \ + test28 SCRIPTS_TINY_OUT = \ test10.out \ @@ -31,7 +32,8 @@ SCRIPTS_TINY_OUT = \ test24.out \ test25.out \ test26.out \ - test27.out + test27.out \ + test28.out # Tests for Vim9 script. TEST_VIM9 = \ @@ -161,6 +163,10 @@ NEW_TESTS = \ test_function_lists \ test_ga \ test_getcwd \ + test_gettext \ + test_gettext_cp1251 \ + test_gettext_utf8 \ + test_gettext_make \ test_getvar \ test_gf \ test_glob2regpat \ @@ -309,6 +315,7 @@ NEW_TESTS = \ test_textobjects \ test_textprop \ test_timers \ + test_tohtml \ test_true_false \ test_trycatch \ test_undo \ @@ -335,6 +342,7 @@ NEW_TESTS = \ test_writefile \ test_xdg \ test_xxd \ + test_zip_plugin \ test_alot_latin \ test_alot_utf8 \ test_alot @@ -420,6 +428,10 @@ NEW_TESTS_RES = \ test_functions.res \ test_function_lists.res \ test_getcwd.res \ + test_gettext.res \ + test_gettext_cp1251.res \ + test_gettext_utf8.res \ + test_gettext_make.res \ test_getvar.res \ test_gf.res \ test_gn.res \ @@ -550,6 +562,7 @@ NEW_TESTS_RES = \ test_textobjects.res \ test_textprop.res \ test_timers.res \ + test_tohtml.res \ test_true_false.res \ test_trycatch.res \ test_undo.res \ @@ -571,6 +584,7 @@ NEW_TESTS_RES = \ test_writefile.res \ test_xdg.res \ test_xxd.res \ + test_zip_plugin.res \ test_alot_latin.res \ test_alot_utf8.res \ test_alot.res diff --git a/src/testdir/Make_mvc.mak b/src/testdir/Make_mvc.mak index 318cd4a..1bf9eae 100644 --- a/src/testdir/Make_mvc.mak +++ b/src/testdir/Make_mvc.mak @@ -5,9 +5,9 @@ # Testing may be done with a debug build !IF EXIST(..\\vimd.exe) && !EXIST(..\\vim.exe) -VIMPROG = ..\\vimd +VIMPROG = ..\\vimd.exe !ELSE -VIMPROG = ..\\vim +VIMPROG = ..\\vim.exe !ENDIF @@ -42,7 +42,7 @@ report: else ( echo No failures reported > test_result.log ) $(VIMPROG) -u NONE $(COMMON_ARGS) -S summarize.vim messages -if exist starttime del starttime - @echo. + @echo: @echo Test results: @cmd /c type test_result.log @if exist test.log ( echo TEST FAILURE & exit /b 1 ) \ @@ -56,7 +56,7 @@ $(NEW_TESTS): -if exist test.log del test.log -if exist messages del messages -if exist starttime del starttime - @$(MAKE) -nologo -f Make_mvc.mak $@.res VIMPROG=$(VIMPROG) + @$(MAKE) -nologo -f Make_mvc.mak VIMPROG=$(VIMPROG) $@.res @type messages @if exist test.log exit 1 diff --git a/src/testdir/Makefile b/src/testdir/Makefile index 4e476f9..7a4c4c4 100644 --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -84,7 +84,7 @@ test_vim9: RM_ON_RUN = test.out X* viminfo RM_ON_START = test.ok benchmark.out -RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in +RUN_VIMPROG = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in # Delete files that may interfere with running tests. This includes some files # that may result from working on the tests, not only from running them. @@ -114,7 +114,7 @@ tinytests: $(SCRIPTS_TINY_OUT) @# 200 msec is sufficient, but only modern sleep supports a fraction of @# a second, fall back to a second if it fails. @-/bin/sh -c "sleep .2 > /dev/null 2>&1 || sleep 1" - $(RUN_VIM) $*.in $(REDIR_TEST_TO_NULL) + $(RUN_VIMPROG) $*.in $(REDIR_TEST_TO_NULL) @# Check if the test.out file matches test.ok. @/bin/sh -c "if test -f test.out; then \ diff --git a/src/testdir/README.txt b/src/testdir/README.txt index f72bdbf..203c324 100644 --- a/src/testdir/README.txt +++ b/src/testdir/README.txt @@ -97,8 +97,7 @@ tests are successful, then this file will be an empty file. - To execute only specific test functions, add a second argument: - $ ../vim -u NONE -S runtest.vim test_channel.vim open_delay - + $ ../vim -u NONE -S runtest.vim test_channel.vim open_delay - To run all the tests: @@ -119,3 +118,83 @@ tests are successful, then this file will be an empty file. - To cleanup the temporary files after running the tests: $ make clean + + +VIEWING GENERATED SCREENDUMPS (local): + +You may also wish to look at the whole batch of failed screendumps after +running "make". Source the "viewdumps.vim" script for this task: + + $ ../vim -u NONE -S viewdumps.vim \ + [dumps/Test_xxd_*.dump ...] + +By default, all screendumps found in the "failed" directory will be added to +the argument list and then the first one will be loaded. Loaded screendumps +that bear filenames of screendumps found in the "dumps" directory will be +rendering the contents of any such pair of files and the difference between +them (:help term_dumpdiff()); otherwise, they will be rendering own contents +(:help term_dumpload()). Remember to execute :edit when occasionally you see +raw file contents instead of rendered. + +At any time, you can add, list, and abandon other screendumps: + + :$argedit dumps/Test_spell_*.dump + :args + :qall + +The listing of argument commands can be found under :help buffer-list. + + +VIEWING GENERATED SCREENDUMPS (from a CI-uploaded artifact): + +After you have downloaded an artifact archive containing failed screendumps +and extracted its files in a temporary directory, you need to set up a "dumps" +directory by creating a symlink: + + $ cd /path/to/fork + $ ln -s $(pwd)/src/testdir/dumps /tmp/src/testdir/dumps + +You can now examine the extracted screendumps: + + $ ./src/vim -u NONE -S src/testdir/viewdumps.vim \ + /tmp/src/testdir/failed/*.dump + + +VIEWING GENERATED SCREENDUMPS (submitted for a pull request): + +First, you need to check out the topic branch with the proposed changes and +write down a difference list between the HEAD commit (index) and its parent +commit with respect to the changed "dumps" filenames: + + $ cd /path/to/fork + $ git switch prs/1234 + $ git diff-index --relative=src/testdir/dumps/ \ + --name-only prs/1234~1 > /tmp/filelist + +Then, you need to check out the master branch, change the current working +directory to reconcile relative filepaths written in the filenames list, +possibly create an empty "failed" directory, copy in this directory the old +"dumps" files, whose names are on the same list, and follow it by checking out +the topic branch: + + $ git switch master + $ cd src/testdir/dumps + $ test -d ../failed || mkdir ../failed + $ cp -t ../failed $(cat /tmp/filelist) + $ git switch prs/1234 + +Make note of any missing new screendumps. Please remember about the +introduced INVERTED relation between "dumps" and "failed", i.e. the files to +be committed are in "dumps" already and their old versions are in "failed". +Therefore, you need to copy the missing new screendumps from "dumps" to +"failed": + + $ cp -t ../failed foo_10.dump foo_11.dump foo_12.dump + +After you have changed the current working directory to its parent directory, +you can now examine the screendumps from the "failed" directory (note that new +screendumps will be shown with no difference between their versions): + + $ cd .. + $ ../vim -u NONE -S viewdumps.vim + diff --git a/src/testdir/commondumps.vim b/src/testdir/commondumps.vim new file mode 100644 index 0000000..ed70280 --- /dev/null +++ b/src/testdir/commondumps.vim @@ -0,0 +1,76 @@ +vim9script + +# (Script-local.) +# +# Render a loaded screendump file or the difference of a loaded screendump +# file and its namesake file from the "dumps" directory. +def Render() + const failed_fname: string = bufname() + try + setlocal suffixesadd=.dump + const dumps_fname: string = findfile( + fnamemodify(failed_fname, ':p:t'), + fnamemodify(failed_fname, ':p:h:h') .. '/dumps') + if filereadable(dumps_fname) + term_dumpdiff(failed_fname, dumps_fname) + else + term_dumpload(failed_fname) + endif + finally + exec 'bwipeout ' .. failed_fname + endtry +enddef + +# Search for the "failed" directory in the passed _subtreedirname_ directories +# (usually "\<src\>" or "\<syntax\>") and, if found, select its passed _count_ +# occurence, add all its "*.dump" files to the argument list and list them; +# also define a BufRead autocommand that would invoke "Render()" for every +# "*.dump" file. +def g:Init(subtreedirname: string, count: number) + # Support sourcing this script from any directory in the direct path that + # leads to the project's root directory. + const failed_path: string = finddir('failed', getcwd() .. '/**', -1) + ->filter(((cwdpath: string, parentdirname: string) => + (_: number, dirpath: string) => + cwdpath =~ parentdirname || dirpath =~ parentdirname)( + getcwd(), + subtreedirname)) + ->get(count, '') .. '/' + var error: string = null_string + + if failed_path == '/' + error = 'No such directory: "failed"' + else + const failed_fnames: string = failed_path .. readdir(failed_path, + (fname: string) => fname =~ '^.\+\.dump$') + ->join(' ' .. failed_path) + + if failed_fnames =~ 'failed/$' + error = 'No such file: "*.dump"' + else + exec ':0argedit ' .. failed_fnames + buffers + endif + endif + + autocmd_add([{ + replace: true, + group: 'viewdumps', + event: 'BufRead', + pattern: '*.dump', + cmd: 'Render()', + }]) + + # Unconditionally help, in case a list of filenames is passed to the + # command, the first terminal window with its BufRead event. + silent doautocmd viewdumps BufRead + + if error != null_string + # Instead of sleeping, fill half a window with blanks and prompt + # hit-enter. + echom error .. repeat("\x20", + (winwidth(0) * (winheight(0) / 2) - strlen(error))) + endif +enddef + +# vim:fdm=syntax:sw=2:ts=8:noet:nolist:nosta: diff --git a/src/testdir/crash/dialog_changed_uaf b/src/testdir/crash/dialog_changed_uaf Binary files differnew file mode 100644 index 0000000..e37d18d --- /dev/null +++ b/src/testdir/crash/dialog_changed_uaf diff --git a/src/testdir/crash/double_free b/src/testdir/crash/double_free Binary files differnew file mode 100644 index 0000000..895c4a0 --- /dev/null +++ b/src/testdir/crash/double_free diff --git a/src/testdir/crash/heap_overflow3 b/src/testdir/crash/heap_overflow3 Binary files differnew file mode 100644 index 0000000..c40adbe --- /dev/null +++ b/src/testdir/crash/heap_overflow3 diff --git a/src/testdir/crash/nullpointer b/src/testdir/crash/nullpointer Binary files differnew file mode 100644 index 0000000..c8ff3a4 --- /dev/null +++ b/src/testdir/crash/nullpointer diff --git a/src/testdir/crash/reverse_text_overflow b/src/testdir/crash/reverse_text_overflow Binary files differnew file mode 100644 index 0000000..dfbfe2c --- /dev/null +++ b/src/testdir/crash/reverse_text_overflow diff --git a/src/testdir/dumps/Test_breakindent_with_double_width_wrap_1.dump b/src/testdir/dumps/Test_breakindent_with_double_width_wrap_1.dump new file mode 100644 index 0000000..7b761bc --- /dev/null +++ b/src/testdir/dumps/Test_breakindent_with_double_width_wrap_1.dump @@ -0,0 +1,6 @@ +| +0&#ffffff0@7|a@40|>+0#4040ff13& +| +0#0000000&@7>å£*&@2| +&@35 +|~+0#4040ff13&| @48 +|~| @48 +|~| @48 +| +0#0000000&@31|1|,|4|3|-|5|9| @6|A|l@1| diff --git a/src/testdir/dumps/Test_cmdwin_no_terminal.dump b/src/testdir/dumps/Test_cmdwin_no_terminal.dump index 97d8147..6de9879 100644 --- a/src/testdir/dumps/Test_cmdwin_no_terminal.dump +++ b/src/testdir/dumps/Test_cmdwin_no_terminal.dump @@ -1,6 +1,6 @@ | +0&#ffffff0@74 |[+1&&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1 -|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|c+0#e000e06&|m|d|h|e|i|g|h|t|=+0#0000000&|2| @58 +|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|c+0#e000e06&|m|d|h|e|i|g|h|t|=+0#af5f00255&|2+0#0000000&| @58 |:+0#4040ff13&> +0#0000000&@73 |~+0#4040ff13&| @73 |~| @73 diff --git a/src/testdir/dumps/Test_matchparen_mbyte_1.dump b/src/testdir/dumps/Test_matchparen_mbyte_1.dump new file mode 100644 index 0000000..f5df150 --- /dev/null +++ b/src/testdir/dumps/Test_matchparen_mbyte_1.dump @@ -0,0 +1,10 @@ +>a+0&#ffffff0@7|(*&| +&@64 +|b@3|)*&|c+&@1| @66 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_matchparen_mbyte_2.dump b/src/testdir/dumps/Test_matchparen_mbyte_2.dump new file mode 100644 index 0000000..0e4e6e8 --- /dev/null +++ b/src/testdir/dumps/Test_matchparen_mbyte_2.dump @@ -0,0 +1,10 @@ +|a+0&#ffffff0@7>(*0(ffff15| +0&#ffffff0@64 +|b@3|)*0(ffff15|c+0&#ffffff0@1| @66 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|1|,|9| @10|A|l@1| diff --git a/src/testdir/dumps/Test_matchparen_mbyte_3.dump b/src/testdir/dumps/Test_matchparen_mbyte_3.dump new file mode 100644 index 0000000..85c462a --- /dev/null +++ b/src/testdir/dumps/Test_matchparen_mbyte_3.dump @@ -0,0 +1,10 @@ +|a+0&#ffffff0@7|(*&| +&@64 +|b@3|)*&|c+&>c| @66 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|2|,|9|-|8| @8|A|l@1| diff --git a/src/testdir/dumps/Test_matchparen_mbyte_4.dump b/src/testdir/dumps/Test_matchparen_mbyte_4.dump new file mode 100644 index 0000000..45f5d08 --- /dev/null +++ b/src/testdir/dumps/Test_matchparen_mbyte_4.dump @@ -0,0 +1,10 @@ +|a+0&#ffffff0@7|(*0(ffff15| +0&#ffffff0@64 +|b@3>)*0(ffff15|c+0&#ffffff0@1| @66 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|2|,|5| @10|A|l@1| diff --git a/src/testdir/dumps/Test_matchparen_mbyte_5.dump b/src/testdir/dumps/Test_matchparen_mbyte_5.dump new file mode 100644 index 0000000..45c3bfa --- /dev/null +++ b/src/testdir/dumps/Test_matchparen_mbyte_5.dump @@ -0,0 +1,10 @@ +|a+0&#ffffff0@7|(*&| +&@64 +>b@3|)*&|c+&@1| @66 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|2|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_matchparen_mbyte_6.dump b/src/testdir/dumps/Test_matchparen_mbyte_6.dump new file mode 100644 index 0000000..8064a98 --- /dev/null +++ b/src/testdir/dumps/Test_matchparen_mbyte_6.dump @@ -0,0 +1,10 @@ +|a+0&#ffffff0@7|(*0(ffff15> +0&#ffffff0@64 +|b@3|)*0(ffff15|c+0&#ffffff0@1| @66 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|1|2|-|1@1| @6|A|l@1| diff --git a/src/testdir/dumps/Test_matchparen_mbyte_7.dump b/src/testdir/dumps/Test_matchparen_mbyte_7.dump new file mode 100644 index 0000000..4d8c647 --- /dev/null +++ b/src/testdir/dumps/Test_matchparen_mbyte_7.dump @@ -0,0 +1,10 @@ +|a+0&#ffffff0@7|(*&| +&@64 +|b@3|)*&|c+&@1> @66 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|2|,|1|0|-|9| @7|A|l@1| diff --git a/src/testdir/dumps/Test_matchparen_mbyte_8.dump b/src/testdir/dumps/Test_matchparen_mbyte_8.dump new file mode 100644 index 0000000..c3699fd --- /dev/null +++ b/src/testdir/dumps/Test_matchparen_mbyte_8.dump @@ -0,0 +1,10 @@ +|a+0&#ffffff0@7|(*0(ffff15| +0&#ffffff0@64 +|b@3|)*0(ffff15> +0&#ffffff0@68 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|2|,|8|-|7| @8|A|l@1| diff --git a/src/testdir/dumps/Test_popup_setbuf_01.dump b/src/testdir/dumps/Test_popup_setbuf_01.dump new file mode 100644 index 0000000..14359ba --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_01.dump @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff --git a/src/testdir/dumps/Test_popup_setbuf_02.dump b/src/testdir/dumps/Test_popup_setbuf_02.dump new file mode 100644 index 0000000..5feb982 --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_02.dump @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|s|e|t|b|u|f|(|p|,| |'|f|o@1|b|a|r|.|t|x|t|'|)| @21|0|,|0|-|1| @8|A|l@1| diff --git a/src/testdir/dumps/Test_popup_setbuf_03.dump b/src/testdir/dumps/Test_popup_setbuf_03.dump new file mode 100644 index 0000000..2c49576 --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_03.dump @@ -0,0 +1,10 @@ +|~+0#4040ff13#ffffff0| @73 +|~| @73 +|~| @73 +|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|E+0#ffffff16#e000002|1|2@1|0|:| |S|t|r|i|n|g| |o|r| |N|u|m|b|e|r| |r|e|q|u|i|r|e|d| |f|o|r| |a|r|g|u|m|e|n|t| |2| +0#0000000#ffffff0@27 +|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35 diff --git a/src/testdir/dumps/Test_popup_setbuf_04.dump b/src/testdir/dumps/Test_popup_setbuf_04.dump new file mode 100644 index 0000000..937fa7c --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_04.dump @@ -0,0 +1,10 @@ +>*+0#ffffff16#ffd7ff255|h+0#e000002&|e|l|p|.|t|x|t|*+0#ffffff16&| +0#0000001&@5|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000001&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @11| +0#0000000#0000001 +| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@23|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @29| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@72|k| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@5|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e|y|s|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @1| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255|l| @71| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@19|"|j|"| |t|o| |g|o| |d|o|w|n|,| |"|k|"| |t|o| |g|o| |u|p|,| |"|l|"| |t|o| |g|o| |r|i|g|h|t|.| @6|j| +0#0000000#a8a8a8255 +|C+0#0000001#ffd7ff255|l|o|s|e| |t|h|i|s| |w|i|n|d|o|w|:| @1|U|s|e| |"|:|q|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&|.| @37| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@2|G|e|t| |o|u|t| |o|f| |V|i|m|:| @1|U|s|e| |"|:|q|a|!|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&| |(|c|a|r|e|f|u|l|,| |a|l@1| |c|h|a|n|g|e|s| |a|r|e| |l|o|s|t|!|)|.| @2| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255 diff --git a/src/testdir/dumps/Test_popup_setbuf_05.dump b/src/testdir/dumps/Test_popup_setbuf_05.dump new file mode 100644 index 0000000..a13dfe3 --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_05.dump @@ -0,0 +1,10 @@ +>h+0#e000002#ffffff0|e|l|p|.|t|x|t| +0#0000000&@7|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000000&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @12 +@75 +@24|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @30 +@73|k| +@6|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e| +0#0000001#ffd7ff255|s+0#0000000#ffffff0|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @2 +|l| @73 +|h+3&&|e|l|p|.|t|x|t| |[|H|e|l|p|]|[|R|O|]| @37|1|,|1| @11|T|o|p +| +0&&@74 +|[+1&&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1 +| +0&&@74 diff --git a/src/testdir/dumps/Test_popup_setbuf_06.dump b/src/testdir/dumps/Test_popup_setbuf_06.dump new file mode 100644 index 0000000..937fa7c --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_06.dump @@ -0,0 +1,10 @@ +>*+0#ffffff16#ffd7ff255|h+0#e000002&|e|l|p|.|t|x|t|*+0#ffffff16&| +0#0000001&@5|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000001&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @11| +0#0000000#0000001 +| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@23|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @29| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@72|k| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@5|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e|y|s|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @1| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255|l| @71| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@19|"|j|"| |t|o| |g|o| |d|o|w|n|,| |"|k|"| |t|o| |g|o| |u|p|,| |"|l|"| |t|o| |g|o| |r|i|g|h|t|.| @6|j| +0#0000000#a8a8a8255 +|C+0#0000001#ffd7ff255|l|o|s|e| |t|h|i|s| |w|i|n|d|o|w|:| @1|U|s|e| |"|:|q|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&|.| @37| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@2|G|e|t| |o|u|t| |o|f| |V|i|m|:| @1|U|s|e| |"|:|q|a|!|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&| |(|c|a|r|e|f|u|l|,| |a|l@1| |c|h|a|n|g|e|s| |a|r|e| |l|o|s|t|!|)|.| @2| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255 diff --git a/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_2.dump b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_2.dump new file mode 100644 index 0000000..6022a16 --- /dev/null +++ b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_2.dump @@ -0,0 +1,3 @@ +|a+0&#ffffff0@39|b+0#e000e06&@8|>+0#4040ff13& +>å£*0#0000000&|1+&|2|3|4|5| @42 +@32|1|,|4|1|-|5|1| @6|A|l@1| diff --git a/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_3.dump b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_3.dump new file mode 100644 index 0000000..c033399 --- /dev/null +++ b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_3.dump @@ -0,0 +1,3 @@ +|a+0&#ffffff0@39|b+0#e000e06&@8|>+0#4040ff13& +|+@2>å£*0#0000000&|1+&|2|3|4|5| @39 +|:|s|e|t| |s|h|o|w|b|r|e|a|k|=|+@2| @13|1|,|4|1|-|5|4| @6|A|l@1| diff --git a/src/testdir/dumps/Test_pum_highlights_10.dump b/src/testdir/dumps/Test_pum_highlights_10.dump new file mode 100644 index 0000000..790b028 --- /dev/null +++ b/src/testdir/dumps/Test_pum_highlights_10.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0|h|e|l@1|o| |h|e|l|i|o| |h|e|r|o| |h|e|l@1|o> @51 +|~+0#4040ff13&| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|r|o| @10| +0#4040ff13#ffffff0@41 +|~| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|l|i|o| @9| +0#4040ff13#ffffff0@41 +|~| @15| +0#0000001#e0e0e08|h+0#00e0e07&|e+0#0000001&|l@1|o| @9| +0#4040ff13#ffffff0@41 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@27 diff --git a/src/testdir/dumps/Test_pum_highlights_11.dump b/src/testdir/dumps/Test_pum_highlights_11.dump new file mode 100644 index 0000000..ef75a89 --- /dev/null +++ b/src/testdir/dumps/Test_pum_highlights_11.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0|h|e|l@1|o| |h|e|l|i|o| |h|e|r|o| |h|e|l|i|o> @51 +|~+0#4040ff13&| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|r|o| @10| +0#4040ff13#ffffff0@41 +|~| @15| +0#0000001#e0e0e08|h+0#00e0e07&|e+0#0000001&|l|i|o| @9| +0#4040ff13#ffffff0@41 +|~| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|l@1|o| @9| +0#4040ff13#ffffff0@41 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |2| |o|f| |3| +0#0000000&@27 diff --git a/src/testdir/dumps/Test_pum_highlights_12.dump b/src/testdir/dumps/Test_pum_highlights_12.dump new file mode 100644 index 0000000..a0d2b49 --- /dev/null +++ b/src/testdir/dumps/Test_pum_highlights_12.dump @@ -0,0 +1,20 @@ +|a+0&#ffffff0|w|o|r|d|1> @68 +|a+0#ff404010#e0e0e08|w|o|r|d|1| |W| |e|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@52 +|a+0#0000001#ffd7ff255|w|o|r|d|2| |W| |e|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@52 +|ä½ *0#ff404010#ffd7ff255|好| +&@2|W| |e|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@52 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@26 diff --git a/src/testdir/dumps/Test_pum_highlights_13.dump b/src/testdir/dumps/Test_pum_highlights_13.dump new file mode 100644 index 0000000..34fde12 --- /dev/null +++ b/src/testdir/dumps/Test_pum_highlights_13.dump @@ -0,0 +1,20 @@ +|a+0&#ffffff0|w|o|r|d|1> @68 +|a+8#ff404010#e0e0e08|w|o+0&&|r|d|1| |W| |e|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@52 +|a+8#0000e05#ffd7ff255|w|o+0#0000001&|r|d|2| |W| |e|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@52 +|ä½ *0#ff404010#ffd7ff255|好| +&@2|W| |e|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@52 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@26 diff --git a/src/testdir/dumps/Test_pum_highlights_14.dump b/src/testdir/dumps/Test_pum_highlights_14.dump new file mode 100644 index 0000000..f35b4cb --- /dev/null +++ b/src/testdir/dumps/Test_pum_highlights_14.dump @@ -0,0 +1,20 @@ +|a+0&#ffffff0|w|o|r|d|2> @68 +|a+8#ff404010#ffd7ff255|w|o+0&&|r|d|1| |W| |e|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@52 +|a+8#00e0e07#e0e0e08|w|o+0#0000001&|r|d|2| |W| |e|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@52 +|ä½ *0#ff404010#ffd7ff255|好| +&@2|W| |e|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@52 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |2| |o|f| |3| +0#0000000&@26 diff --git a/src/testdir/dumps/Test_pum_highlights_15.dump b/src/testdir/dumps/Test_pum_highlights_15.dump new file mode 100644 index 0000000..e923b43 --- /dev/null +++ b/src/testdir/dumps/Test_pum_highlights_15.dump @@ -0,0 +1,20 @@ +|/+0&#ffffff0|n|o|n|_|e|x|i|t|_|f|o|l|d|e|r> @58 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |F|i|l|e| |n|a|m|e| |c|o|m|p|l|e|t|i|o|n| |(|^|F|^|N|^|P|)| |P+0#ffffff16#e000002|a|t@1|e|r|n| |n|o|t| |f|o|u|n|d| +0#0000000#ffffff0@24 diff --git a/src/testdir/dumps/Test_pum_highlights_16.dump b/src/testdir/dumps/Test_pum_highlights_16.dump new file mode 100644 index 0000000..fe2b68d --- /dev/null +++ b/src/testdir/dumps/Test_pum_highlights_16.dump @@ -0,0 +1,20 @@ +|a+0&#ffffff0|w|o|r|d|1> @68 +|a+0#ff404010#e0e0e08|w|o|r|d|1| |v+0#ffff4012&|a|r|i|a|b|l|e| |e+0#ff404010&|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@45 +|a+0#0000001#ffd7ff255|w|o|r|d|2| |f+0#4040ff13&|u|n|c|t|i|o|n| |e+0#0000001&|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@45 +|ä½ *0#0000001#ffd7ff255|好| +&@2|c+0#40ff4011&|l|a|s@1| @3|e+0#0000001&|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@45 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@26 diff --git a/src/testdir/dumps/Test_wildmenu_pum_11.dump b/src/testdir/dumps/Test_wildmenu_pum_11.dump index 4697c8a..a0ffc74 100644 --- a/src/testdir/dumps/Test_wildmenu_pum_11.dump +++ b/src/testdir/dumps/Test_wildmenu_pum_11.dump @@ -1,10 +1,10 @@ | +0&#ffffff0@74 |~+0#4040ff13&| @73 -|~| @73 |~| @10| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@46 |~| @10| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@46 |~| @10| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@46 |~| @10| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@46 +|~| @10| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@46 |~| @10| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@46 |~| @10| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@46 |:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=> @55 diff --git a/src/testdir/dumps/Test_wildmenu_pum_12.dump b/src/testdir/dumps/Test_wildmenu_pum_12.dump index d93631d..12842c4 100644 --- a/src/testdir/dumps/Test_wildmenu_pum_12.dump +++ b/src/testdir/dumps/Test_wildmenu_pum_12.dump @@ -1,10 +1,10 @@ | +0&#ffffff0@74 |~+0#4040ff13&| @73 -|~| @73 |~| @17| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@39 |~| @17| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@39 |~| @17| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@39 |~| @17| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@39 +|~| @17| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@39 |~| @17| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@39 |~| @17| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@39 |:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=| |c|u|l|h|l|=> @48 diff --git a/src/testdir/dumps/Test_wildmenu_pum_13.dump b/src/testdir/dumps/Test_wildmenu_pum_13.dump index b2b1424..94a8ccc 100644 --- a/src/testdir/dumps/Test_wildmenu_pum_13.dump +++ b/src/testdir/dumps/Test_wildmenu_pum_13.dump @@ -1,10 +1,10 @@ | +0&#ffffff0@74 |~+0#4040ff13&| @73 -|~| @73 |~| @24| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@32 |~| @24| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@32 |~| @24| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@32 |~| @24| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@32 +|~| @24| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@32 |~| @24| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@32 |~| @24| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@32 |:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=| |c|u|l|h|l|=| |c|u|l|h|l|=> @41 diff --git a/src/testdir/dumps/Test_wildmenu_pum_22.dump b/src/testdir/dumps/Test_wildmenu_pum_22.dump index 3fd00ad..e774d5d 100644 --- a/src/testdir/dumps/Test_wildmenu_pum_22.dump +++ b/src/testdir/dumps/Test_wildmenu_pum_22.dump @@ -1,7 +1,7 @@ | +0&#ffffff0@74 |[+1&&|N|o| |N|a|m|e|]| @65 -|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#0000000&|l|o|n|g|e|s|t|,+0#af5f00255&|f+0#0000000&|u|l@1| @48 -|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#0000000&|f|u|l@1| @56 +|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#af5f00255&|l+0#0000000&|o|n|g|e|s|t|,+0#e000e06&|f+0#0000000&|u|l@1| @48 +|:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#af5f00255&|f+0#0000000&|u|l@1| @56 |:+0#4040ff13&|s+0#af5f00255&|i|g|n| +0#0000000&|d|e|f|i|n|e| @62 |:+0#4040ff13&|s+0#af5f00255&|i|g|n| +0#0000000&|d|e|f|i|n|e> @62 |~+0#4040ff13&| @73 diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim index 8cca2b9..7674714 100644 --- a/src/testdir/gen_opt_test.vim +++ b/src/testdir/gen_opt_test.vim @@ -144,6 +144,7 @@ let test_values = { \ 'splitkeep': [['cursor', 'screen', 'topline'], ['xxx']], \ 'swapsync': [['', 'sync', 'fsync'], ['xxx']], \ 'switchbuf': [['', 'useopen', 'split,newtab'], ['xxx']], + \ 'tabclose': [['', 'left', 'left,uselast'], ['xxx']], \ 'tagcase': [['smart', 'match'], ['', 'xxx', 'smart,match']], \ 'term': [[], []], \ 'termguicolors': [[], []], diff --git a/src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo b/src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo Binary files differnew file mode 100644 index 0000000..300eba2 --- /dev/null +++ b/src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo diff --git a/src/testdir/samples/Test_tohtml_basic.c.html b/src/testdir/samples/Test_tohtml_basic.c.html new file mode 100644 index 0000000..d9467b5 --- /dev/null +++ b/src/testdir/samples/Test_tohtml_basic.c.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<title>/home/jiangyinzuo/vim/src/testdir/Test_tohtml_basic.c.html</title> +<meta name="Generator" content="Vim/9.1"> +<meta name="plugin-version" content="vim9.0_v2"> +<meta name="syntax" content="none"> +<meta name="settings" content="use_css,no_foldcolumn,pre_wrap,prevent_copy=,use_input_for_pc=none"> +<meta name="colorscheme" content="none"> +<style> +<!-- +pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-color: #ffffff; } +body { font-family: monospace; color: #000000; background-color: #ffffff; } +* { font-size: 1em; } +--> +</style> +</head> +<body> +<pre id='vimCodeElement'> +#include <stdio.h> +#include <stdlib.h> + +int isprime(int n) +{ + if (n <= 1) + return 0; + + for (int i = 2; i <= n / 2; i++) + if (n % i == 0) + return 0; + + return 1; +} + +int main(int argc, char *argv[]) +{ + int n = 7; + + printf("%d is %s prime\n", n, isprime(n) ? "a" : "not a"); + + return 0; +} +</pre> +</body> +</html> +<!-- vim: set foldmethod=manual : --> diff --git a/src/testdir/samples/Test_tohtml_basic_no_css.c.html b/src/testdir/samples/Test_tohtml_basic_no_css.c.html new file mode 100644 index 0000000..fcbcf5c --- /dev/null +++ b/src/testdir/samples/Test_tohtml_basic_no_css.c.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<title>/home/jiangyinzuo/vim/src/testdir/Test_tohtml_basic_no_css.c.html</title> +<meta name="Generator" content="Vim/9.1"> +<meta name="plugin-version" content="vim9.0_v2"> +<meta name="syntax" content="none"> +<meta name="settings" content="no_pre,no_foldcolumn,expand_tabs,prevent_copy=,use_input_for_pc=none"> +<meta name="colorscheme" content="none"> +</head> +<body bgcolor="#ffffff" text="#000000"> +<font face="monospace"> +#include <stdio.h><br> +#include <stdlib.h><br> +<br> +int isprime(int n)<br> +{<br> + if (n <= 1)<br> + return 0;<br> +<br> + for (int i = 2; i <= n / 2; i++)<br> + if (n % i == 0)<br> + return 0;<br> +<br> + return 1;<br> +}<br> +<br> +int main(int argc, char *argv[])<br> +{<br> + int n = 7;<br> +<br> + printf("%d is %s prime\n", n, isprime(n) ? "a" : "not a");<br> +<br> + return 0;<br> +}<br> +</font> +</body> +</html> +<!-- vim: set foldmethod=manual : --> diff --git a/src/testdir/samples/test.zip b/src/testdir/samples/test.zip Binary files differnew file mode 100644 index 0000000..6d34ac6 --- /dev/null +++ b/src/testdir/samples/test.zip diff --git a/src/testdir/samples/testa.zip b/src/testdir/samples/testa.zip Binary files differnew file mode 100644 index 0000000..10b0346 --- /dev/null +++ b/src/testdir/samples/testa.zip diff --git a/src/testdir/test28.in b/src/testdir/test28.in new file mode 100644 index 0000000..3d5289d --- /dev/null +++ b/src/testdir/test28.in @@ -0,0 +1,13 @@ +Test for using CTRL-A/CTRL-X in tiny mode + +STARTTEST +/12352 +/12354 +:/^STARTHERE/+,$w! test.out +:qa! +ENDTEST + +STARTHERE +12352 + +12354 diff --git a/src/testdir/test28.ok b/src/testdir/test28.ok new file mode 100644 index 0000000..085c133 --- /dev/null +++ b/src/testdir/test28.ok @@ -0,0 +1,3 @@ +12353 + +12353 diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim index edc8b77..8d81a82 100644 --- a/src/testdir/test_arglist.vim +++ b/src/testdir/test_arglist.vim @@ -359,6 +359,7 @@ func Test_argv() call assert_equal('', argv(1, 100)) call assert_equal([], argv(-1, 100)) call assert_equal('', argv(10, -1)) + %argdelete endfunc " Test for the :argedit command @@ -744,4 +745,26 @@ func Test_all_command() %bw! endfunc +" Test for deleting buffer when creating an arglist. This was accessing freed +" memory +func Test_crash_arglist_uaf() + "%argdelete + new one + au BufAdd XUAFlocal :bw + "call assert_fails(':arglocal XUAFlocal', 'E163:') + arglocal XUAFlocal + au! BufAdd + bw! XUAFlocal + + au BufAdd XUAFlocal2 :bw + new two + new three + arglocal + argadd XUAFlocal2 Xfoobar + bw! XUAFlocal2 + bw! two + + au! BufAdd +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_assert.vim b/src/testdir/test_assert.vim index d143f19..15b18a4 100644 --- a/src/testdir/test_assert.vim +++ b/src/testdir/test_assert.vim @@ -48,10 +48,19 @@ func Test_assert_equal() call assert_match("Expected 'bar' but got 'foo'", v:errors[0]) call remove(v:errors, 0) + let s = 'αβγ' + call assert_equal(1, assert_equal('δεζ', s)) + call assert_match("Expected 'δεζ' but got 'αβγ'", v:errors[0]) + call remove(v:errors, 0) + call assert_equal('XxxxxxxxxxxxxxxxxxxxxxX', 'XyyyyyyyyyyyyyyyyyyyyyyyyyX') call assert_match("Expected 'X\\\\\\[x occurs 21 times]X' but got 'X\\\\\\[y occurs 25 times]X'", v:errors[0]) call remove(v:errors, 0) + call assert_equal('ΩωωωωωωωωωωωωωωωωωωωωωΩ', 'ΩψψψψψψψψψψψψψψψψψψψψψψψψψΩ') + call assert_match("Expected 'Ω\\\\\\[ω occurs 21 times]Ω' but got 'Ω\\\\\\[ψ occurs 25 times]Ω'", v:errors[0]) + call remove(v:errors, 0) + " special characters are escaped call assert_equal("\b\e\f\n\t\r\\\x01\x7f", 'x') call assert_match('Expected ''\\b\\e\\f\\n\\t\\r\\\\\\x01\\x7f'' but got ''x''', v:errors[0]) diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index c9f257a..5a91351 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -14,6 +14,13 @@ func s:cleanup_buffers() abort endfor endfunc +func CleanUpTestAuGroup() + augroup testing + au! + augroup END + augroup! testing +endfunc + func Test_vim_did_enter() call assert_false(v:vim_did_enter) @@ -269,6 +276,7 @@ endfunc func Test_win_tab_autocmd() let g:record = [] + defer CleanUpTestAuGroup() augroup testing au WinNewPre * call add(g:record, 'WinNewPre') au WinNew * call add(g:record, 'WinNew') @@ -288,7 +296,7 @@ func Test_win_tab_autocmd() call assert_equal([ \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter', - \ 'WinLeave', 'TabLeave', 'WinNewPre', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter', + \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter', \ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter', \ 'WinLeave', 'WinClosed', 'WinEnter' \ ], g:record) @@ -299,7 +307,7 @@ func Test_win_tab_autocmd() bwipe somefile call assert_equal([ - \ 'WinLeave', 'TabLeave', 'WinNewPre', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter', + \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter', \ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', \ 'WinClosed', 'TabClosed' \ ], g:record) @@ -316,9 +324,6 @@ func Test_win_tab_autocmd() \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter' \ ], g:record) - augroup testing - au! - augroup END unlet g:record endfunc @@ -330,17 +335,15 @@ func Test_WinNewPre() au WinNewPre * call add(g:layouts_pre, winlayout()) au WinNew * call add(g:layouts_post, winlayout()) augroup END + defer CleanUpTestAuGroup() split call assert_notequal(g:layouts_pre[0], g:layouts_post[0]) split call assert_equal(g:layouts_pre[1], g:layouts_post[0]) call assert_notequal(g:layouts_pre[1], g:layouts_post[1]) + " not triggered for tabnew tabnew - call assert_notequal(g:layouts_pre[2], g:layouts_post[1]) - call assert_notequal(g:layouts_pre[2], g:layouts_post[2]) - augroup testing - au! - augroup END + call assert_equal(2, len(g:layouts_pre)) unlet g:layouts_pre unlet g:layouts_post @@ -383,9 +386,6 @@ func Test_WinNewPre() let g:caught += 1 endtry call assert_equal(4, g:caught) - augroup testing - au! - augroup END unlet g:caught endfunc @@ -2096,6 +2096,38 @@ func Test_Cmdline() au! CmdlineEnter au! CmdlineLeave let &shellslash = save_shellslash + + au! CursorMovedC : let g:pos += [getcmdpos()] + let g:pos = [] + call feedkeys(":foo bar baz\<C-W>\<C-W>\<C-W>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9, 5, 1], g:pos) + let g:pos = [] + call feedkeys(":hello\<C-B>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 1], g:pos) + let g:pos = [] + call feedkeys(":hello\<C-U>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 1], g:pos) + let g:pos = [] + call feedkeys(":hello\<Left>\<C-R>=''\<CR>\<Left>\<Right>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 5, 4, 5], g:pos) + let g:pos = [] + call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3], g:pos) + let g:pos = [] + call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Left>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3, 2], g:pos) + au! CursorMovedC + + " setcmdpos() is no-op inside an autocommand + au! CursorMovedC : let g:pos += [getcmdpos()] | call setcmdpos(1) + let g:pos = [] + call feedkeys(":hello\<Left>\<Left>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 5, 4], g:pos) + au! CursorMovedC + + unlet g:entered + unlet g:left + unlet g:pos endfunc " Test for BufWritePre autocommand that deletes or unloads the buffer. @@ -2775,7 +2807,8 @@ endfunc func Test_autocmd_nested() let g:did_nested = 0 - augroup Testing + defer CleanUpTestAuGroup() + augroup testing au WinNew * edit somefile au BufNew * let g:did_nested = 1 augroup END @@ -2785,7 +2818,7 @@ func Test_autocmd_nested() bwipe! somefile " old nested argument still works - augroup Testing + augroup testing au! au WinNew * nested edit somefile au BufNew * let g:did_nested = 1 @@ -4720,4 +4753,115 @@ func Test_BufEnter_botline() set hidden&vim endfunc +func Test_KeyInputPre() + " Consume previous keys + call feedkeys('', 'ntx') + + " KeyInputPre can record input keys. + let s:keys = [] + au KeyInputPre n call add(s:keys, v:char) + + call feedkeys('jkjkjjj', 'ntx') + call assert_equal( + \ ['j', 'k', 'j', 'k', 'j', 'j', 'j'], + \ s:keys) + + unlet s:keys + au! KeyInputPre + + " KeyInputPre can handle multibyte. + let s:keys = [] + au KeyInputPre * call add(s:keys, v:char) + edit Xxx1 + + call feedkeys("iã‚\<ESC>", 'ntx') + call assert_equal(['i', "ã‚", "\<ESC>"], s:keys) + + bwipe! Xxx1 + unlet s:keys + au! KeyInputPre + + " KeyInputPre can change input keys. + au KeyInputPre i if v:char ==# 'a' | let v:char = 'b' | endif + edit Xxx1 + + call feedkeys("iaabb\<ESC>", 'ntx') + call assert_equal(getline('.'), 'bbbb') + + bwipe! Xxx1 + au! KeyInputPre + + " KeyInputPre returns multiple characters. + au KeyInputPre i if v:char ==# 'a' | let v:char = 'cccc' | endif + edit Xxx1 + + call feedkeys("iaabb\<ESC>", 'ntx') + call assert_equal(getline('.'), 'ccbb') + + bwipe! Xxx1 + au! KeyInputPre + + " KeyInputPre can use special keys. + au KeyInputPre i if v:char ==# 'a' | let v:char = "\<Ignore>" | endif + edit Xxx1 + + call feedkeys("iaabb\<ESC>", 'ntx') + call assert_equal(getline('.'), 'bb') + + bwipe! Xxx1 + au! KeyInputPre + + " Test for v:event.typed + au KeyInputPre n call assert_true(v:event.typed) + call feedkeys('j', 'ntx') + + au! KeyInputPre + + au KeyInputPre n call assert_false(v:event.typed) + call feedkeys('j', 'nx') + + au! KeyInputPre + + " Test for v:event.typedchar + nnoremap j k + au KeyInputPre n + \ call assert_equal(v:event.typedchar, 'j') + \ | call assert_equal(v:char, 'k') + call feedkeys('j', 'tx') + + au! KeyInputPre +endfunc + +" those commands caused null pointer access, see #15464 +func Test_WinNewPre_crash() + defer CleanUpTestAuGroup() + let _cmdheight=&cmdheight + augroup testing + au! + autocmd WinNewPre * redraw + augroup END + tabnew + tabclose + augroup testing + au! + autocmd WinNewPre * wincmd t + augroup END + tabnew + tabclose + augroup testing + au! + autocmd WinNewPre * wincmd b + augroup END + tabnew + tabclose + augroup testing + au! + autocmd WinNewPre * set cmdheight+=1 + augroup END + tabnew + tabclose + let &cmdheight=_cmdheight +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_breakindent.vim b/src/testdir/test_breakindent.vim index 96d91c9..b306c02 100644 --- a/src/testdir/test_breakindent.vim +++ b/src/testdir/test_breakindent.vim @@ -1165,4 +1165,15 @@ func Test_breakindent_min_with_signcol() call s:close_windows() endfunc +func Test_breakindent_with_double_width_wrap() + 50vnew + setlocal tabstop=8 breakindent nolist + call setline(1, "\t" .. repeat('a', winwidth(0) - 9) .. 'å£å£å£') + normal! $g0 + call assert_equal(2, winline()) + call assert_equal(9, wincol()) + + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_buffer.vim b/src/testdir/test_buffer.vim index de088bd..757ba05 100644 --- a/src/testdir/test_buffer.vim +++ b/src/testdir/test_buffer.vim @@ -126,6 +126,52 @@ func Test_buflist_browse() %bwipe! endfunc +" Test for :bnext and :bprev when called from help and non-help buffers. +func Test_bnext_bprev_help() + %bwipe! + + e XHelp1 | set bt=help + let b1 = bufnr() + e Xbuf1 + let b2 = bufnr() + + " There's only one buffer of each type. + b XHelp1 + bnext | call assert_equal(b1, bufnr()) + bprev | call assert_equal(b1, bufnr()) + b Xbuf1 + bnext | call assert_equal(b2, bufnr()) + bprev | call assert_equal(b2, bufnr()) + + " Add one more buffer of each type. + e XHelp2 | set bt=help + let b3 = bufnr() + e Xbuf2 + let b4 = bufnr() + + " Help buffer jumps to help buffer. + b XHelp1 + bnext | call assert_equal(b3, bufnr()) + bnext | call assert_equal(b1, bufnr()) + bprev | call assert_equal(b3, bufnr()) + bprev | call assert_equal(b1, bufnr()) + + " Regular buffer jumps to regular buffer. + b Xbuf1 + bnext | call assert_equal(b4, bufnr()) + bnext | call assert_equal(b2, bufnr()) + bprev | call assert_equal(b4, bufnr()) + bprev | call assert_equal(b2, bufnr()) + + " :brewind and :blast are not affected by the buffer type. + b Xbuf2 + brewind | call assert_equal(b1, bufnr()) + b XHelp1 + blast | call assert_equal(b4, bufnr()) + + %bwipe! +endfunc + " Test for :bdelete func Test_bdelete_cmd() %bwipe! diff --git a/src/testdir/test_cd.vim b/src/testdir/test_cd.vim index 9fb5958..13a3eba 100644 --- a/src/testdir/test_cd.vim +++ b/src/testdir/test_cd.vim @@ -200,12 +200,20 @@ endfunc func Test_cd_completion() call mkdir('XComplDir1', 'D') call mkdir('XComplDir2', 'D') + call mkdir('sub/XComplDir3', 'pD') call writefile([], 'XComplFile', 'D') for cmd in ['cd', 'chdir', 'lcd', 'lchdir', 'tcd', 'tchdir'] call feedkeys(':' .. cmd .. " XCompl\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"' .. cmd .. ' XComplDir1/ XComplDir2/', @:) endfor + + set cdpath+=sub + for cmd in ['cd', 'chdir', 'lcd', 'lchdir', 'tcd', 'tchdir'] + call feedkeys(':' .. cmd .. " XCompl\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"' .. cmd .. ' XComplDir1/ XComplDir2/ XComplDir3/', @:) + endfor + set cdpath& endfunc func Test_cd_unknown_dir() diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index 8b7489e..3f6918a 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -658,7 +658,8 @@ func Test_getcompletion() unlet g:cmdline_compl_params " For others test if the name is recognized. - let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user'] + let names = ['buffer', 'environment', 'file_in_path', 'dir_in_path', 'mapping', 'tag', + \ 'tag_listfiles', 'user'] if has('cmdline_hist') call add(names, 'history') endif @@ -3612,7 +3613,7 @@ func Test_cmdline_complete_bang_cmd_argument() endfunc func Call_cmd_funcs() - return string([getcmdpos(), getcmdscreenpos(), getcmdcompltype()]) + return [getcmdpos(), getcmdscreenpos(), getcmdcompltype()] endfunc func Test_screenpos_and_completion() @@ -3620,13 +3621,24 @@ func Test_screenpos_and_completion() call assert_equal(0, getcmdscreenpos()) call assert_equal('', getcmdcompltype()) - cnoremap <expr> <F2> string([getcmdpos(), getcmdscreenpos(), getcmdcompltype()]) + cnoremap <expr> <F2> string(Call_cmd_funcs()) call feedkeys(":let a\<F2>\<C-B>\"\<CR>", "xt") call assert_equal("\"let a[6, 7, 'var']", @:) call feedkeys(":quit \<F2>\<C-B>\"\<CR>", "xt") call assert_equal("\"quit [6, 7, '']", @:) call feedkeys(":nosuchcommand \<F2>\<C-B>\"\<CR>", "xt") call assert_equal("\"nosuchcommand [15, 16, '']", @:) + + " Check that getcmdcompltype() doesn't interfere with cmdline completion. + let g:results = [] + cnoremap <F2> <Cmd>let g:results += [[getcmdline()] + Call_cmd_funcs()]<CR> + call feedkeys(":sign un\<Tab>\<F2>\<Tab>\<F2>\<Tab>\<F2>\<C-C>", "xt") + call assert_equal([ + \ ['sign undefine', 14, 15, 'sign'], + \ ['sign unplace', 13, 14, 'sign'], + \ ['sign un', 8, 9, 'sign']], g:results) + + unlet g:results cunmap <F2> endfunc @@ -3858,4 +3870,25 @@ func Test_term_option() let &cpo = _cpo endfunc +func Test_ex_command_completion() + " required for :* + set cpo+=* + let list = filter(getcompletion('', 'command'), 'exists(":" . v:val) == 0') + " :++ and :-- are only valid in Vim9 Script context, so they can be ignored + call assert_equal(['++', '--'], sort(list)) + call assert_equal(1, exists(':k')) + call assert_equal(0, exists(':ke')) + call assert_equal(1, exists(':kee')) + call assert_equal(1, exists(':keep')) + call assert_equal(1, exists(':keepm')) + call assert_equal(1, exists(':keepma')) + call assert_equal(1, exists(':keepmar')) + call assert_equal(1, exists(':keepmark')) + call assert_equal(2, exists(':keepmarks')) + call assert_equal(2, exists(':keepalt')) + call assert_equal(2, exists(':keepjumps')) + call assert_equal(2, exists(':keeppatterns')) + set cpo-=* +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_codestyle.vim b/src/testdir/test_codestyle.vim index a455264..83f52ef 100644 --- a/src/testdir/test_codestyle.vim +++ b/src/testdir/test_codestyle.vim @@ -28,6 +28,13 @@ def Test_source_files() g:ignoreSwapExists = 'e' exe 'edit ' .. fname + # Some files are generated files and may contain space errors. + if fname =~ 'dlldata.c' + || fname =~ 'if_ole.h' + || fname =~ 'iid_ole.c' + continue + endif + PerformCheck(fname, ' \t', 'space before Tab', '') PerformCheck(fname, '\s$', 'trailing white space', '') @@ -68,7 +75,8 @@ def Test_test_files() && fname !~ 'test_listchars.vim' && fname !~ 'test_visual.vim' cursor(1, 1) - var lnum = search(fname =~ "test_regexp_latin" ? '[^á] \t' : ' \t') + var skip = 'getline(".") =~ "codestyle: ignore"' + var lnum = search(fname =~ "test_regexp_latin" ? '[^á] \t' : ' \t', 'W', 0, 0, skip) ReportError('testdir/' .. fname, lnum, 'space before Tab') endif @@ -155,4 +163,4 @@ def Test_help_files() enddef -" vim: shiftwidth=2 sts=2 expandtab +" vim: shiftwidth=2 sts=2 expandtab nofoldenable diff --git a/src/testdir/test_cpoptions.vim b/src/testdir/test_cpoptions.vim index 6ff8301..7bfbcd1 100644 --- a/src/testdir/test_cpoptions.vim +++ b/src/testdir/test_cpoptions.vim @@ -19,7 +19,7 @@ func Test_cpo_a() set cpo+=a read XfileCpoA call assert_equal('XfileCpoA', @#) - close! + bw! let &cpo = save_cpo endfunc @@ -39,7 +39,7 @@ func Test_cpo_A() set cpo+=A write XcpoAfile2 call assert_equal('XcpoAfile2', @#) - close! + bw! call delete('XcpoAfile2') let &cpo = save_cpo endfunc @@ -81,7 +81,7 @@ func Test_cpo_B() call assert_equal('abd ', getline(1)) call feedkeys(":imap <buffer> x\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"imap <buffer> x\k', @:) - close! + bw! let &cpo = save_cpo endfunc @@ -96,7 +96,7 @@ func Test_cpo_c() set cpo-=c exe "normal gg/abab\<CR>" call assert_equal(5, searchcount().total) - close! + bw! let &cpo = save_cpo endfunc @@ -143,7 +143,7 @@ func Test_cpo_D() exe "norm! 1gg0f\<c-k>!!" call assert_equal(1, col('.')) set cpo-=D - close! + bw! let &cpo = save_cpo endfunc @@ -183,7 +183,7 @@ func Test_cpo_E() call assert_beeps('exe "normal v\<C-A>"') call assert_beeps('exe "normal v\<C-X>"') set cpo-=E - close! + bw! endfunc " Test for the 'f' flag in 'cpo' (read in an empty buffer sets the file name) @@ -213,7 +213,7 @@ func Test_cpo_F() set cpo+=F write XfileCpoF call assert_equal('XfileCpoF', @%) - close! + bw! call delete('XfileCpoF') let &cpo = save_cpo endfunc @@ -229,7 +229,7 @@ func Test_cpo_g() set cpo+=g edit call assert_equal(1, line('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -245,7 +245,7 @@ func Test_cpo_H() call setline(1, ' ') normal! Ia call assert_equal(' a ', getline(1)) - close! + bw! let &cpo = save_cpo endfunc @@ -264,7 +264,7 @@ func Test_cpo_I() %d exe "normal i one\<CR>\<Up>" call assert_equal('', getline(2)) - close! + bw! let &cpo = save_cpo endfunc @@ -295,7 +295,7 @@ func Test_cpo_J() normal ( call assert_equal(colnr, col('.')) endfor - close! + bw! let &cpo = save_cpo endfunc @@ -317,7 +317,7 @@ func Test_cpo_l() set cpo+=l exe 'normal gg/[\t]' .. "\<CR>" call assert_equal([4, 10], [col('.'), virtcol('.')]) - close! + bw! let &cpo = save_cpo endfunc @@ -338,7 +338,7 @@ func Test_cpo_L() call setline(1, 'abcdefghijklmnopqr') exe "normal 0gR\<Tab>" call assert_equal("\<Tab>ijklmnopqr", getline(1)) - close! + bw! let &cpo = save_cpo endfunc @@ -376,7 +376,7 @@ func Test_cpo_M() call cursor(2, 1) call assert_beeps('normal %') - close! + bw! let &cpo = save_cpo endfunc @@ -392,7 +392,7 @@ func Test_cpo_n() set cpo+=n redraw! call assert_equal('aaaa', Screenline(2)) - close! + bw! let &cpo = save_cpo endfunc @@ -409,7 +409,7 @@ func Test_cpo_o() exe "normal /one/+2\<CR>" normal n call assert_equal(5, line('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -424,7 +424,7 @@ func Test_cpo_O() set cpo+=O write call assert_equal(['one'], readfile('XfileCpoO')) - close! + bw! let &cpo = save_cpo endfunc @@ -462,7 +462,7 @@ func Test_cpo_q() set cpo+=q normal gg4J call assert_equal(4, col('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -483,7 +483,7 @@ func Test_cpo_r() let @/ = 'three' normal 2G. call assert_equal('abc three four', getline(2)) - close! + bw! let &cpo = save_cpo endfunc @@ -503,7 +503,7 @@ func Test_cpo_R() 3mark r %!sort call assert_equal(0, line("'r")) - close! + bw! let &cpo = save_cpo endfunc @@ -530,8 +530,8 @@ func Test_cpo_S() wincmd p call assert_equal(0, &autoindent) wincmd t - close! - close! + bw! + bw! let &cpo = save_cpo endfunc @@ -550,7 +550,7 @@ func Test_cpo_u() exe "normal iabc\<C-G>udef\<C-G>ughi" normal uu call assert_equal('abcdefghi', getline(1)) - close! + bw! let &cpo = save_cpo endfunc @@ -574,7 +574,7 @@ func Test_cpo_w() call assert_equal('hereZZZare some words', getline('.')) norm! 1gg2elcWYYY call assert_equal('hereZZZare someYYYwords', getline('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -611,7 +611,7 @@ func Test_cpo_X() normal ggRy normal 4. call assert_equal('yyyyxxxaaaaa', getline(1)) - close! + bw! let &cpo = save_cpo endfunc @@ -630,7 +630,7 @@ func Test_cpo_y() normal ggyy normal 2G. call assert_equal("two\n", @") - close! + bw! let &cpo = save_cpo endfunc @@ -647,7 +647,7 @@ func Test_cpo_Z() setlocal readonly write! call assert_equal(1, &readonly) - close! + bw! let &cpo = save_cpo endfunc @@ -700,7 +700,7 @@ func Test_cpo_percent() call assert_equal(15, col('.')) normal 22|% call assert_equal(27, col('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -716,7 +716,7 @@ func Test_cpo_minus() call assert_beeps('normal 10k') call assert_equal(3, line('.')) call assert_fails(10, 'E16:') - close! + bw! let &cpo = save_cpo endfunc @@ -732,7 +732,7 @@ func Test_cpo_plus() set cpo+=+ write X2 call assert_equal(0, &modified) - close! + bw! call delete('X1') call delete('X2') let &cpo = save_cpo @@ -749,7 +749,7 @@ func Test_cpo_star() set cpo+=* *a call assert_equal(1, x) - close! + bw! let &cpo = save_cpo endfunc @@ -770,7 +770,7 @@ func Test_cpo_gt() normal gg"Rye normal "Rye call assert_equal("\none\none", @r) - close! + bw! let &cpo = save_cpo endfunc @@ -803,7 +803,7 @@ func Test_cpo_semicolon() call assert_equal('bbb y', getline(4)) call assert_equal('ccc', getline(5)) call assert_equal('ddd yee y', getline(6)) - close! + bw! let &cpo = save_cpo endfunc @@ -828,7 +828,7 @@ func Test_cpo_hash() call assert_equal(['', 'one', 'two', 'three'], getline(1, '$')) normal gg2Ozero call assert_equal(['zero', '', 'one', 'two', 'three'], getline(1, '$')) - close! + bw! let &cpo = save_cpo endfunc @@ -858,7 +858,7 @@ func Test_cpo_backslash() set cpo+=\ exe 'normal gg/[ \-]' .. "\<CR>n" call assert_equal(2, col('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -880,7 +880,7 @@ func Test_cpo_brace() call assert_equal(2, line('.')) normal G{ call assert_equal(2, line('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -908,8 +908,53 @@ func Test_cpo_dot() call delete('Xfoo') set cpo& - close! + bw! let &cpo = save_cpo endfunc +" Test for the 'z' flag in 'cpo' (make cw and dw work similar and avoid +" inconsistencies, see :h cpo-z) +func Test_cpo_z() + let save_cpo = &cpo + new + " Test 1: dw behaves differently from cw + call setline(1, ['foo bar baz', 'one two three']) + call cursor(1, 1) + " dw does not delete the whitespace after the word + norm! wcwanother + set cpo-=z + " dw deletes the whitespace after the word + call cursor(2, 1) + norm! wcwfour + call assert_equal(['foo another baz', 'one fourthree'], getline(1, '$')) + " Test 2: d{motion} becomes linewise :h d-special + %d + call setline(1, ['one ', ' bar', ' e ', 'zwei']) + call cursor(2, 1) + set cpo+=z + " delete operation becomes linewise + call feedkeys("fbd/e\\zs\<cr>", 'tnx') + call assert_equal(['one ', 'zwei'], getline(1, '$')) + %d + call setline(1, ['one ', ' bar', ' e ', 'zwei']) + call cursor(2, 1) + call feedkeys("fbd2w", 'tnx') + call assert_equal(['one ', 'zwei'], getline(1, '$')) + + " delete operation does not become line wise + set cpo-=z + call setline(1, ['one ', ' bar', ' e ', 'zwei']) + call cursor(2, 1) + call feedkeys("fbd/e\\zs\<cr>", 'tnx') + call assert_equal(['one ', ' ', 'zwei'], getline(1, '$')) " codestyle: ignore + %d + call setline(1, ['one ', ' bar', ' e ', 'zwei']) + call cursor(2, 1) + call feedkeys("fbd2w", 'tnx') + call assert_equal(['one ', ' ', 'zwei'], getline(1, '$')) + + " clean up + bw! + let &cpo = save_cpo +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_crash.vim b/src/testdir/test_crash.vim index fd786e5..b334876 100644 --- a/src/testdir/test_crash.vim +++ b/src/testdir/test_crash.vim @@ -150,6 +150,13 @@ func Test_crash1_2() \ ' ; echo "crash 4: [OK]" >> '.. result .. "\<cr>") call TermWait(buf, 150) + let file = 'crash/reverse_text_overflow' + let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'" + let args = printf(cmn_args, vim, file) + call term_sendkeys(buf, args .. + \ ' ; echo "crash 5: [OK]" >> '.. result .. "\<cr>") + call TermWait(buf, 150) + " clean up exe buf .. "bw!" exe "sp " .. result @@ -158,6 +165,7 @@ func Test_crash1_2() \ 'crash 2: [OK]', \ 'crash 3: [OK]', \ 'crash 4: [OK]', + \ 'crash 5: [OK]', \ ] call assert_equal(expected, getline(1, '$')) @@ -190,6 +198,31 @@ func Test_crash1_3() call term_sendkeys(buf, args) call TermWait(buf, 150) + let file = 'crash/double_free' + let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>" + let args = printf(cmn_args, vim, file) + call term_sendkeys(buf, args) + call TermWait(buf, 50) + + let file = 'crash/dialog_changed_uaf' + let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>" + let args = printf(cmn_args, vim, file) + call term_sendkeys(buf, args) + call TermWait(buf, 150) + + let file = 'crash/nullpointer' + let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>" + let args = printf(cmn_args, vim, file) + call term_sendkeys(buf, args) + call TermWait(buf, 50) + + let file = 'crash/heap_overflow3' + let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'" + let args = printf(cmn_args, vim, file) + call term_sendkeys(buf, args) + call TermWait(buf, 150) + + " clean up exe buf .. "bw!" bw! @@ -204,4 +237,11 @@ func Test_crash2() exe buf .. "bw!" endfunc +func TearDown() + " That file is created at Test_crash1_3() by dialog_changed_uaf + " but cleaning up in that test doesn't remove it. Let's try again at + " the end of this test script + call delete('Untitled') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_eval_stuff.vim b/src/testdir/test_eval_stuff.vim index a346399..1b17108 100644 --- a/src/testdir/test_eval_stuff.vim +++ b/src/testdir/test_eval_stuff.vim @@ -2,6 +2,7 @@ source view_util.vim source shared.vim +import './vim9.vim' as v9 function s:foo() abort try @@ -126,7 +127,31 @@ func Test_for_invalid() call assert_fails("for x in 99", 'E1098:') call assert_fails("for x in function('winnr')", 'E1098:') call assert_fails("for x in {'a': 9}", 'E1098:') - call assert_fails("for v:maxcol in range(1)", 'E46:') + + let lines =<< trim END + for v:maxcol in range(5) + endfor + END + + let save_v_maxcol = v:maxcol + call v9.CheckLegacyAndVim9Failure(lines, 'E46:') + call assert_equal(save_v_maxcol, v:maxcol) + + let lines =<< trim END + for g:constvar in range(5) + endfor + END + + const g:constvar = 10 + call v9.CheckLegacyAndVim9Failure(lines, 'E741:') + call assert_equal(10, g:constvar) + unlet g:constvar + + let g:constvar = 10 + lockvar 0 g:constvar + call v9.CheckLegacyAndVim9Failure(lines, 'E1122:') + call assert_equal(10, g:constvar) + unlet g:constvar if 0 /1/5/2/s/\n diff --git a/src/testdir/test_ex_mode.vim b/src/testdir/test_ex_mode.vim index 59c28f3..aa94935 100644 --- a/src/testdir/test_ex_mode.vim +++ b/src/testdir/test_ex_mode.vim @@ -68,7 +68,7 @@ func Test_Ex_substitute() CheckRunVimInTerminal let buf = RunVimInTerminal('', {'rows': 6}) - call term_sendkeys(buf, ":call setline(1, ['foo foo', 'foo foo', 'foo foo'])\<CR>") + call term_sendkeys(buf, ":call setline(1, repeat(['foo foo'], 4))\<CR>") call term_sendkeys(buf, ":set number\<CR>") call term_sendkeys(buf, "gQ") call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000) @@ -90,8 +90,14 @@ func Test_Ex_substitute() " Pressing enter in ex mode should print the current line call term_sendkeys(buf, "\<CR>") - call WaitForAssert({-> assert_match(' 3 foo foo', - \ term_getline(buf, 5))}, 1000) + call WaitForAssert({-> assert_match(' 3 foo foo', term_getline(buf, 5))}, 1000) + call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000) + + " The printed line should overwrite the colon + call term_sendkeys(buf, "\<CR>") + call WaitForAssert({-> assert_match(' 3 foo foo', term_getline(buf, 4))}, 1000) + call WaitForAssert({-> assert_match(' 4 foo foo', term_getline(buf, 5))}, 1000) + call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000) call term_sendkeys(buf, ":vi\<CR>") call WaitForAssert({-> assert_match('foo bar', term_getline(buf, 1))}, 1000) @@ -165,6 +171,37 @@ func Test_Ex_global() call assert_equal('bax', getline(3)) call assert_equal('bay', getline(5)) bwipe! + + new + call setline(1, ['foo', 'bar']) + call feedkeys("Qg/./i\\\na\\\n.\\\na\\\nb\\\n.", "xt") + call assert_equal(['a', 'b', 'foo', 'a', 'b', 'bar'], getline(1, '$')) + bwipe! +endfunc + +func Test_Ex_shell() + CheckUnix + + new + call feedkeys("Qr !echo foo\\\necho bar\n", 'xt') + call assert_equal(['', 'foo', 'bar'], getline(1, '$')) + bwipe! + + new + call feedkeys("Qr !echo foo\\\\\nbar\n", 'xt') + call assert_equal(['', 'foobar'], getline(1, '$')) + bwipe! + + new + call feedkeys("Qr !echo foo\\ \\\necho bar\n", 'xt') + call assert_equal(['', 'foo ', 'bar'], getline(1, '$')) + bwipe! + + new + call setline(1, ['bar', 'baz']) + call feedkeys("Qg/./!echo \\\ns/b/c/", "xt") + call assert_equal(['car', 'caz'], getline(1, '$')) + bwipe! endfunc " Test for pressing Ctrl-C in :append inside a loop in Ex mode @@ -204,18 +241,11 @@ func Test_Ex_append() call feedkeys("Qappend!\npqr\nxyz\n.\nvisual\n", 'xt') call assert_equal(["\t abc", "\t pqr", "\t xyz"], getline(1, '$')) close! -endfunc -" In Ex-mode, backslashes at the end of a command should be halved. -func Test_Ex_echo_backslash() - " This test works only when the language is English - CheckEnglish - let bsl = '\\\\' - let bsl2 = '\\\' - call assert_fails('call feedkeys("Qecho " .. bsl .. "\nvisual\n", "xt")', - \ 'E15: Invalid expression: "\\"') - call assert_fails('call feedkeys("Qecho " .. bsl2 .. "\nm\nvisual\n", "xt")', - \ "E15: Invalid expression: \"\\\nm\"") + new + call feedkeys("Qappend\na\\\n.", 'xt') + call assert_equal(['a\'], getline(1, '$')) + close! endfunc func Test_ex_mode_errors() @@ -314,5 +344,47 @@ func Test_empty_command_visual_mode() call delete('guidialogfile') endfunc +" Test using backslash in ex-mode +func Test_backslash_multiline() + new + call setline(1, 'enum') + call feedkeys('Qg/enum/i\
\
.', "xt") + call assert_equal(["", "enum"], getline(1, 2)) +endfunc + +" Test using backslash in ex-mode after patch 9.1.0535 +func Test_backslash_multiline2() + new + call feedkeys('Qa
X \\
Y
.', "xt") + call assert_equal(['X \\', "Y"], getline(1, 2)) +endfunc + +" Testing implicit print command +func Test_implicit_print() + new + call setline(1, ['one', 'two', 'three']) + call feedkeys('Q:let a=execute(":1,2")', 'xt') + call feedkeys('Q:let b=execute(":3")', 'xt') + call assert_equal('one two', a->split('\n')->join(' ')) + call assert_equal('three', b->split('\n')->join(' ')) + bw! +endfunc + +" Test inserting text after the trailing bar +func Test_insert_after_trailing_bar() + new + call feedkeys("Qi|\nfoo\n.\na|bar\nbar\n.\nc|baz\n.", "xt") + call assert_equal(['', 'foo', 'bar', 'baz'], getline(1, '$')) + bwipe! +endfunc + +" Test global insert of a newline without terminating period +func Test_global_insert_newline() + new + call setline(1, ['foo']) + call feedkeys("Qg/foo/i\\\n", "xt") + call assert_equal(['', 'foo'], getline(1, '$')) + bwipe! +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_excmd.vim b/src/testdir/test_excmd.vim index 221ceb0..3b7e489 100644 --- a/src/testdir/test_excmd.vim +++ b/src/testdir/test_excmd.vim @@ -703,6 +703,8 @@ func Test_address_line_overflow() call setline(1, range(100)) call assert_fails('|.44444444444444444444444', 'E1247:') call assert_fails('|.9223372036854775806', 'E1247:') + call assert_fails('.44444444444444444444444d', 'E1247:') + call assert_equal(range(100)->map('string(v:val)'), getline(1, '$')) $ yank 77777777777777777777 diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index d0a078f..1e6c39e 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -95,6 +95,7 @@ def s:GetFilenameChecks(): dict<list<string>> aml: ['file.aml'], ampl: ['file.run'], ant: ['build.xml'], + antlr4: ['parser.g4'], apache: ['.htaccess', '/etc/httpd/file.conf', '/etc/apache2/sites-2/file.com', '/etc/apache2/some.config', '/etc/apache2/conf.file/conf', '/etc/apache2/mods-some/file', '/etc/apache2/sites-some/file', '/etc/httpd/conf.d/file.config', '/etc/apache2/conf.file/file', '/etc/apache2/file.conf', '/etc/apache2/file.conf-file', '/etc/apache2/mods-file/file', '/etc/apache2/sites-file/file', '/etc/apache2/sites-file/file.com', '/etc/httpd/conf.d/file.conf', '/etc/httpd/conf.d/file.conf-file', 'access.conf', 'access.conf-file', 'any/etc/apache2/conf.file/file', 'any/etc/apache2/file.conf', 'any/etc/apache2/file.conf-file', 'any/etc/apache2/mods-file/file', 'any/etc/apache2/sites-file/file', 'any/etc/apache2/sites-file/file.com', 'any/etc/httpd/conf.d/file.conf', 'any/etc/httpd/conf.d/file.conf-file', 'any/etc/httpd/file.conf', 'apache.conf', 'apache.conf-file', 'apache2.conf', 'apache2.conf-file', 'httpd.conf', 'httpd.conf-file', 'srm.conf', 'srm.conf-file', '/etc/httpd/mods-some/file', '/etc/httpd/sites-some/file', '/etc/httpd/conf.file/conf'], apachestyle: ['/etc/proftpd/file.config,/etc/proftpd/conf.file/file', '/etc/proftpd/conf.file/file', '/etc/proftpd/file.conf', '/etc/proftpd/file.conf-file', 'any/etc/proftpd/conf.file/file', 'any/etc/proftpd/file.conf', 'any/etc/proftpd/file.conf-file', 'proftpd.conf', 'proftpd.conf-file'], applescript: ['file.scpt'], @@ -106,6 +107,7 @@ def s:GetFilenameChecks(): dict<list<string>> asn: ['file.asn', 'file.asn1'], asterisk: ['asterisk/file.conf', 'asterisk/file.conf-file', 'some-asterisk/file.conf', 'some-asterisk/file.conf-file'], astro: ['file.astro'], + asy: ['file.asy'], atlas: ['file.atl', 'file.as'], authzed: ['schema.zed'], autohotkey: ['file.ahk'], @@ -121,7 +123,7 @@ def s:GetFilenameChecks(): dict<list<string>> beancount: ['file.beancount'], bib: ['file.bib'], bicep: ['file.bicep', 'file.bicepparam'], - bindzone: ['named.root', '/bind/db.file', '/named/db.file', 'any/bind/db.file', 'any/named/db.file'], + bindzone: ['named.root', '/bind/db.file', '/named/db.file', 'any/bind/db.file', 'any/named/db.file', 'foobar.zone'], bitbake: ['file.bb', 'file.bbappend', 'file.bbclass', 'build/conf/local.conf', 'meta/conf/layer.conf', 'build/conf/bbappend.conf', 'meta-layer/conf/distro/foo.conf'], blade: ['file.blade.php'], blank: ['file.bl'], @@ -142,6 +144,7 @@ def s:GetFilenameChecks(): dict<list<string>> cdl: ['file.cdl'], cdrdaoconf: ['/etc/cdrdao.conf', '/etc/defaults/cdrdao', '/etc/default/cdrdao', '.cdrdao', 'any/etc/cdrdao.conf', 'any/etc/default/cdrdao', 'any/etc/defaults/cdrdao'], cdrtoc: ['file.toc'], + cedar: ['file.cedar'], cf: ['file.cfm', 'file.cfi', 'file.cfc'], cfengine: ['cfengine.conf'], cfg: ['file.hgrc', 'filehgrc', 'hgrc', 'some-hgrc'], @@ -160,7 +163,7 @@ def s:GetFilenameChecks(): dict<list<string>> cmakecache: ['CMakeCache.txt'], cmod: ['file.cmod'], cmusrc: ['any/.cmus/autosave', 'any/.cmus/rc', 'any/.cmus/command-history', 'any/.cmus/file.theme', 'any/cmus/rc', 'any/cmus/file.theme', '/.cmus/autosave', '/.cmus/command-history', '/.cmus/file.theme', '/.cmus/rc', '/cmus/file.theme', '/cmus/rc'], - cobol: ['file.cbl', 'file.cob', 'file.lib'], + cobol: ['file.cbl', 'file.cob'], coco: ['file.atg'], conaryrecipe: ['file.recipe'], conf: ['auto.master', 'file.conf', 'texdoc.cnf', '.x11vncrc', '.chktexrc', '.ripgreprc', 'ripgreprc', 'file.ctags', '.mbsyncrc'], @@ -222,11 +225,11 @@ def s:GetFilenameChecks(): dict<list<string>> 'psprint.conf', 'sofficerc', 'any/.config/lxqt/globalkeyshortcuts.conf', 'any/.config/screengrab/screengrab.conf', 'any/.local/share/flatpak/repo/config', '.notmuch-config'], dot: ['file.dot', 'file.gv'], - dracula: ['file.drac', 'file.drc', 'filelvs', 'filelpe', 'drac.file', 'lpe', 'lvs', 'some-lpe', 'some-lvs'], + dracula: ['file.drac', 'file.drc', 'file.lvs', 'file.lpe', 'drac.file'], dtd: ['file.dtd'], dtrace: ['/usr/lib/dtrace/io.d'], dts: ['file.dts', 'file.dtsi', 'file.dtso', 'file.its', 'file.keymap'], - dune: ['jbuild', 'dune', 'dune-project', 'dune-workspace'], + dune: ['jbuild', 'dune', 'dune-project', 'dune-workspace', 'dune-file'], dylan: ['file.dylan'], dylanintr: ['file.intr'], dylanlid: ['file.lid'], @@ -256,6 +259,7 @@ def s:GetFilenameChecks(): dict<list<string>> factor: ['file.factor'], falcon: ['file.fal'], fan: ['file.fan', 'file.fwt'], + faust: ['file.dsp', 'file.lib'], fennel: ['file.fnl'], fetchmail: ['.fetchmailrc'], fgl: ['file.4gl', 'file.4gh', 'file.m4gl'], @@ -285,17 +289,18 @@ def s:GetFilenameChecks(): dict<list<string>> gitattributes: ['file.git/info/attributes', '.gitattributes', '/.config/git/attributes', '/etc/gitattributes', '/usr/local/etc/gitattributes', 'some.git/info/attributes'] + WhenConfigHome('$XDG_CONFIG_HOME/git/attributes'), gitcommit: ['COMMIT_EDITMSG', 'MERGE_MSG', 'TAG_EDITMSG', 'NOTES_EDITMSG', 'EDIT_DESCRIPTION'], gitconfig: ['file.git/config', 'file.git/config.worktree', 'file.git/worktrees/x/config.worktree', '.gitconfig', '.gitmodules', 'file.git/modules//config', '/.config/git/config', '/etc/gitconfig', '/usr/local/etc/gitconfig', '/etc/gitconfig.d/file', 'any/etc/gitconfig.d/file', '/.gitconfig.d/file', 'any/.config/git/config', 'any/.gitconfig.d/file', 'some.git/config', 'some.git/modules/any/config'] + WhenConfigHome('$XDG_CONFIG_HOME/git/config'), - gitignore: ['file.git/info/exclude', '.gitignore', '/.config/git/ignore', 'some.git/info/exclude'] + WhenConfigHome('$XDG_CONFIG_HOME/git/ignore'), + gitignore: ['file.git/info/exclude', '.gitignore', '/.config/git/ignore', 'some.git/info/exclude'] + WhenConfigHome('$XDG_CONFIG_HOME/git/ignore') + ['.prettierignore'], gitolite: ['gitolite.conf', '/gitolite-admin/conf/file', 'any/gitolite-admin/conf/file'], gitrebase: ['git-rebase-todo'], gitsendemail: ['.gitsendemail.msg.xxxxxx'], gkrellmrc: ['gkrellmrc', 'gkrellmrc_x'], gleam: ['file.gleam'], - glsl: ['file.glsl'], + glsl: ['file.glsl', 'file.vert', 'file.tesc', 'file.tese', 'file.geom', 'file.frag', 'file.comp', 'file.rgen', 'file.rmiss', 'file.rchit', 'file.rahit', 'file.rint', 'file.rcall'], gn: ['file.gn', 'file.gni'], gnash: ['gnashrc', '.gnashrc', 'gnashpluginrc', '.gnashpluginrc'], gnuplot: ['file.gpi', '.gnuplot', 'file.gnuplot', '.gnuplot_history'], go: ['file.go'], + goaccess: ['goaccess.conf'], gomod: ['go.mod'], gosum: ['go.sum', 'go.work.sum'], gowork: ['go.work'], @@ -332,6 +337,7 @@ def s:GetFilenameChecks(): dict<list<string>> hoon: ['file.hoon'], hostconf: ['/etc/host.conf', 'any/etc/host.conf'], hostsaccess: ['/etc/hosts.allow', '/etc/hosts.deny', 'any/etc/hosts.allow', 'any/etc/hosts.deny'], + # file.component.html should be HTML, not Angular, see #13594 html: ['file.html', 'file.htm', 'file.cshtml', 'file.component.html'], htmlm4: ['file.html.m4'], httest: ['file.htt', 'file.htb'], @@ -364,7 +370,9 @@ def s:GetFilenameChecks(): dict<list<string>> jq: ['file.jq'], jovial: ['file.jov', 'file.j73', 'file.jovial'], jproperties: ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file', 'org.eclipse.xyz.prefs'], - json: ['file.json', 'file.jsonp', 'file.json-patch', 'file.geojson', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', 'file.jupyterlab-settings', '.prettierrc', '.firebaserc', '.stylelintrc', '.lintstagedrc', 'file.slnf', 'file.sublime-project', 'file.sublime-settings', 'file.sublime-workspace', 'file.bd', 'file.bda', 'file.xci', 'flake.lock'], + json: ['file.json', 'file.jsonp', 'file.json-patch', 'file.geojson', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', 'file.jupyterlab-settings', + '.prettierrc', '.firebaserc', '.stylelintrc', '.lintstagedrc', 'file.slnf', 'file.sublime-project', 'file.sublime-settings', 'file.sublime-workspace', + 'file.bd', 'file.bda', 'file.xci', 'flake.lock', 'pack.mcmeta', 'deno.lock'], json5: ['file.json5'], jsonc: ['file.jsonc', '.babelrc', '.eslintrc', '.jsfmtrc', '.jshintrc', '.jscsrc', '.vsconfig', '.hintrc', '.swrc', 'jsconfig.json', 'tsconfig.json', 'tsconfig.test.json', 'tsconfig-test.json', '.luaurc'], jsonl: ['file.jsonl'], @@ -383,6 +391,7 @@ def s:GetFilenameChecks(): dict<list<string>> lace: ['file.ace', 'file.ACE'], latte: ['file.latte', 'file.lte'], ld: ['file.ld', 'any/usr/lib/aarch64-xilinx-linux/ldscripts/aarch64elf32b.x'], + ldapconf: ['ldap.conf', '.ldaprc', 'ldaprc'], ldif: ['file.ldif'], lean: ['file.lean'], ledger: ['file.ldg', 'file.ledger', 'file.journal'], @@ -420,18 +429,19 @@ def s:GetFilenameChecks(): dict<list<string>> mail: ['snd.123', '.letter', '.letter.123', '.followup', '.article', '.article.123', 'pico.123', 'mutt-xx-xxx', 'muttng-xx-xxx', 'ae123.txt', 'file.eml', 'reportbug-file'], mailaliases: ['/etc/mail/aliases', '/etc/aliases', 'any/etc/aliases', 'any/etc/mail/aliases'], mailcap: ['.mailcap', 'mailcap'], - make: ['file.mk', 'file.mak', 'file.dsp', 'makefile', 'Makefile', 'makefile-file', 'Makefile-file', 'some-makefile', 'some-Makefile', 'Kbuild'], + make: ['file.mk', 'file.mak', 'makefile', 'Makefile', 'makefile-file', 'Makefile-file', 'some-makefile', 'some-Makefile', 'Kbuild'], mallard: ['file.page'], man: ['file.man'], manconf: ['/etc/man.conf', 'man.config', 'any/etc/man.conf'], map: ['file.map'], maple: ['file.mv', 'file.mpl', 'file.mws'], markdown: ['file.markdown', 'file.mdown', 'file.mkd', 'file.mkdn', 'file.mdwn', 'file.md'], - mason: ['file.mason', 'file.mhtml', 'file.comp'], + mason: ['file.mason', 'file.mhtml'], master: ['file.mas', 'file.master'], matlab: ['file.m'], maxima: ['file.demo', 'file.dmt', 'file.dm1', 'file.dm2', 'file.dm3', 'file.wxm', 'maxima-init.mac'], + mediawiki: ['file.mw', 'file.wiki'], mel: ['file.mel'], mermaid: ['file.mmd', 'file.mmdc', 'file.mermaid'], meson: ['meson.build', 'meson.options', 'meson_options.txt'], @@ -466,7 +476,7 @@ def s:GetFilenameChecks(): dict<list<string>> mgp: ['file.mgp'], mib: ['file.mib', 'file.my'], mix: ['file.mix', 'file.mixal'], - mma: ['file.nb'], + mma: ['file.nb', 'file.wl'], mmp: ['file.mmp'], modconf: ['/etc/modules.conf', '/etc/modules', '/etc/conf.modules', '/etc/modprobe.file', 'any/etc/conf.modules', 'any/etc/modprobe.file', 'any/etc/modules', 'any/etc/modules.conf'], modula3: ['file.m3', 'file.mg', 'file.i3', 'file.ig', 'file.lm3'], @@ -522,7 +532,7 @@ def s:GetFilenameChecks(): dict<list<string>> odin: ['file.odin'], omnimark: ['file.xom', 'file.xin'], ondir: ['.ondirrc'], - opam: ['opam', 'file.opam', 'file.opam.template'], + opam: ['opam', 'file.opam', 'file.opam.template', 'opam.locked', 'file.opam.locked'], openroad: ['file.or'], openscad: ['file.scad'], openvpn: ['file.ovpn', '/etc/openvpn/client/client.conf', '/usr/share/openvpn/examples/server.conf'], @@ -645,7 +655,8 @@ def s:GetFilenameChecks(): dict<list<string>> sh: ['.bashrc', '.bash_profile', '.bash-profile', '.bash_logout', '.bash-logout', '.bash_aliases', '.bash-aliases', '.bash_history', '.bash-history', '/tmp/bash-fc-3Ozjlw', '/tmp/bash-fc.3Ozjlw', 'PKGBUILD', 'APKBUILD', 'file.bash', '/usr/share/doc/bash-completion/filter.sh', '/etc/udev/cdsymlinks.conf', 'any/etc/udev/cdsymlinks.conf', 'file.bats', '.ash_history', 'any/etc/neofetch/config.conf', '.xprofile', - 'user-dirs.defaults', 'user-dirs.dirs', 'makepkg.conf', '.makepkg.conf', 'file.mdd', 'file.cygport'], + 'user-dirs.defaults', 'user-dirs.dirs', 'makepkg.conf', '.makepkg.conf', 'file.mdd', 'file.cygport', '.env', '.envrc', 'devscripts.conf', + '.devscripts'], sieve: ['file.siv', 'file.sieve'], sil: ['file.sil'], simula: ['file.sim'], @@ -759,7 +770,7 @@ def s:GetFilenameChecks(): dict<list<string>> teraterm: ['file.ttl'], terminfo: ['file.ti'], 'terraform-vars': ['file.tfvars'], - tex: ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl', 'any/.texlive/texmf-config/tex/latex/file/file.cfg', 'file.pgf', 'file.nlo', 'file.nls', 'file.thm', 'file.eps_tex', 'file.pygtex', 'file.pygstyle', 'file.clo', 'file.aux', 'file.brf', 'file.ind', 'file.lof', 'file.loe', 'file.nav', 'file.vrb', 'file.ins', 'file.tikz', 'file.bbx', 'file.cbx', 'file.beamer'], + tex: ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl', 'any/.texlive/texmf-config/tex/latex/file/file.cfg', 'file.pgf', 'file.nlo', 'file.nls', 'file.thm', 'file.eps_tex', 'file.pygtex', 'file.pygstyle', 'file.clo', 'file.aux', 'file.brf', 'file.ind', 'file.lof', 'file.loe', 'file.nav', 'file.vrb', 'file.ins', 'file.tikz', 'file.bbx', 'file.cbx', 'file.beamer', 'file.pdf_tex'], texinfo: ['file.texinfo', 'file.texi', 'file.txi'], texmf: ['texmf.cnf'], text: ['file.text', 'file.txt', 'README', 'LICENSE', 'COPYING', 'AUTHORS', '/usr/share/doc/bash-completion/AUTHORS', '/etc/apt/apt.conf.d/README', '/etc/Muttrc.d/README'], @@ -854,6 +865,8 @@ def s:GetFilenameChecks(): dict<list<string>> z8a: ['file.z8a'], zathurarc: ['zathurarc'], zig: ['file.zig', 'build.zig.zon'], + ziggy: ['file.ziggy'], + ziggy_schema: ['file.ziggy-schema'], zimbu: ['file.zu'], zimbutempl: ['file.zut'], zserio: ['file.zs'], @@ -1043,7 +1056,8 @@ func Test_emptybuf_ftdetect() call assert_equal('', &filetype) filetype detect call assert_equal('sh', &filetype) - close! + " close the swapfile + bw! endfunc " Test for ':filetype indent on' and ':filetype indent off' commands @@ -1567,6 +1581,73 @@ func Test_hook_file() filetype off endfunc +func Test_html_file() + filetype on + + " HTML Angular + let content = ['@for (item of items; track item.name) {', ' <li> {{ item.name }}</li>', '} @empty {', ' <li> There are no items.</li>', '}'] + call writefile(content, 'Xfile.html', 'D') + split Xfile.html + call assert_equal('htmlangular', &filetype) + bwipe! + + " Django Template + let content = ['{% if foobar %}', + \ ' <ul>', + \ ' {% for question in list %}', + \ ' <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>', + \ ' {% endfor %}', + \ ' </ul>', + \ '{% else %}', + \ ' <p>No polls are available.</p>', + \ '{% endif %}'] + call writefile(content, 'Xfile.html', 'D') + split Xfile.html + call assert_equal('htmldjango', &filetype) + bwipe! + + " Super html layout + let content = ['<extend template="base.shtml">', + \ '<title id="title" var="$page.title"></title>', + \ '<head id="head"></head>', + \ '<div id="content">', + \ '</div>'] + call writefile(content, 'Xfile.shtml', 'D') + split Xfile.shtml + call assert_equal('superhtml', &filetype) + bwipe! + + " Super html template + let content = ['<!DOCTYPE html>', + \ '<html>', + \ ' <head id="head">', + \ ' <title id="title">', + \ ' <super>', + \ ' suffix', + \ ' </title>', + \ ' <super>', + \ ' </head>', + \ ' <body>', + \ ' <div id="content">', + \ ' <super>', + \ ' </div>', + \ ' </body>', + \ '</html>'] + call writefile(content, 'Xfile.shtml', 'D') + split Xfile.shtml + call assert_equal('superhtml', &filetype) + bwipe! + + " regular HTML + let content = ['<!DOCTYPE html>', '<html>', ' <head>Foobar</head>', ' <body>Content', ' </body>', '</html>'] + call writefile(content, 'Xfile.html', 'D') + split Xfile.html + call assert_equal('html', &filetype) + bwipe! + + filetype off +endfunc + func Test_m_file() filetype on @@ -2401,6 +2482,32 @@ func Test_typ_file() filetype off endfunc +func Test_dsp_file() + filetype on + + " Microsoft Developer Studio Project file + + call writefile(['# Microsoft Developer Studio Project File'], 'Xfile.dsp', 'D') + split Xfile.dsp + call assert_equal('make', &filetype) + bwipe! + + let g:filetype_dsp = 'make' + split test.dsp + call assert_equal('make', &filetype) + bwipe! + unlet g:filetype_dsp + + " Faust + + call writefile(['this is a fallback'], 'Xfile.dsp') + split Xfile.dsp + call assert_equal('faust', &filetype) + bwipe! + + filetype off +endfunc + func Test_vba_file() filetype on @@ -2509,4 +2616,86 @@ func Test_uci_file() filetype off endfunc +func Test_pro_file() + filetype on + + "Prolog + call writefile([':-module(test/1,'], 'Xfile.pro', 'D') + split Xfile.pro + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['% comment'], 'Xfile.pro', 'D') + split Xfile.pro + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['/* multiline comment'], 'Xfile.pro', 'D') + split Xfile.pro + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['rule(test, 1.7).'], 'Xfile.pro', 'D') + split Xfile.pro + call assert_equal('prolog', &filetype) + bwipe! + + " IDL + call writefile(['x = findgen(100)/10'], 'Xfile.pro', 'D') + split Xfile.pro + call assert_equal('idlang', &filetype) + + filetype off +endfunc + + +func Test_pl_file() + filetype on + + "Prolog + call writefile([':-module(test/1,'], 'Xfile.pl', 'D') + split Xfile.pl + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['% comment'], 'Xfile.pl', 'D') + split Xfile.pl + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['/* multiline comment'], 'Xfile.pl', 'D') + split Xfile.pl + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['rule(test, 1.7).'], 'Xfile.pl', 'D') + split Xfile.pl + call assert_equal('prolog', &filetype) + bwipe! + + " Perl + call writefile(['%data = (1, 2, 3);'], 'Xfile.pl', 'D') + split Xfile.pl + call assert_equal('perl', &filetype) + + filetype off +endfunc + +func Test_make_file() + filetype on + + " Microsoft Makefile + call writefile(['# Makefile for Windows', '!if "$(VIMDLL)" == "yes"'], 'XMakefile.mak', 'D') + split XMakefile.mak + call assert_equal(1, get(b:, 'make_microsoft', 0)) + bwipe! + + call writefile(['# get the list of tests', 'include testdir/Make_all.mak'], 'XMakefile.mak', 'D') + split XMakefile.mak + call assert_equal(0, get(b:, 'make_microsoft', 0)) + bwipe! + + filetype off +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_findfile.vim b/src/testdir/test_findfile.vim index 20d5096..a5e18b9 100644 --- a/src/testdir/test_findfile.vim +++ b/src/testdir/test_findfile.vim @@ -98,14 +98,48 @@ func Test_findfile() " Test upwards search with stop-directory. cd Xdir2 + let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/Xdir3/', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/Xdir3', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';../', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';..', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/', -1) call assert_equal(1, len(l)) call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';../../', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';../..', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) let l = findfile('bar', ';' . save_dir . '/Xfinddir1/', -1) call assert_equal(2, len(l)) call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) call assert_match('.*/Xfinddir1/bar', l[1]) + let l = findfile('bar', ';' . save_dir . '/Xfinddir1', -1) + call assert_equal(2, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + call assert_match('.*/Xfinddir1/bar', l[1]) + let l = findfile('bar', ';../../../', -1) + call assert_equal(2, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + call assert_match('.*/Xfinddir1/bar', l[1]) + let l = findfile('bar', ';../../..', -1) + call assert_equal(2, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + call assert_match('.*/Xfinddir1/bar', l[1]) " Test combined downwards and upwards search from Xdir2/. cd ../.. @@ -133,6 +167,7 @@ func Test_finddir() let save_shellslash = &shellslash let save_dir = getcwd() set path=,, + set shellslash call CreateFiles() cd Xfinddir1 diff --git a/src/testdir/test_fnamemodify.vim b/src/testdir/test_fnamemodify.vim index c19f464..4e61343 100644 --- a/src/testdir/test_fnamemodify.vim +++ b/src/testdir/test_fnamemodify.vim @@ -14,6 +14,8 @@ func Test_fnamemodify() call assert_equal($HOME .. "/foo" , fnamemodify('~/foo', ':p')) call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/../', ':p')) call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/..', ':p')) + call assert_equal(fnamemodify('.', ':p:h:h') .. '/', fnamemodify('../', ':p')) + call assert_equal(fnamemodify('.', ':p:h:h') .. '/', fnamemodify('..', ':p')) call assert_equal('test.out', fnamemodify('test.out', ':.')) call assert_equal('a', fnamemodify('../testdir/a', ':.')) call assert_equal('~/testdir/test.out', fnamemodify('test.out', ':~')) diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim index dedc4a2..17487a5 100644 --- a/src/testdir/test_fold.vim +++ b/src/testdir/test_fold.vim @@ -1914,4 +1914,39 @@ func Test_foldexpr_end_fold() bwipe! endfunc +" Test moving cursor down to or beyond start of folded end of buffer. +func Test_cursor_down_fold_eob() + call setline(1, range(1, 4)) + norm Gzf2kj + call assert_equal(2, line('.')) + norm zojzc + call assert_equal(3, line('.')) + norm j + call assert_equal(3, line('.')) + norm k2j + call assert_equal(4, line('.')) + bwipe! +endfunc + +" issue: #15455 +func Test_cursor_fold_marker_undo() + new + call setline(1, ['{{{', '', 'This is a Line', '', 'This is a Line', '', '}}}']) + let &ul=&ul + setl foldmethod=marker + call cursor(2, 1) + norm! zo1vjdu + call assert_equal(1, foldlevel('.')) + bwipe! + new + call setline(1, ['', '{{{', '', 'This is a Line', '', 'This is a Line', '', '}}}']) + let &ul=&ul + setl foldmethod=marker + call cursor(3, 1) + norm! zo + norm! vjdu + call assert_equal(1, foldlevel('.')) + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index acdb954..1021d05 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -923,6 +923,10 @@ func Test_mode() call feedkeys("gQ\<Insert>\<F2>vi\<CR>", 'xt') call assert_equal("c-cvr", g:current_modes) + " Commandline mode in Visual mode should return "c-c", never "v-v". + call feedkeys("v\<Cmd>call input('')\<CR>\<F2>\<CR>\<Esc>", 'xt') + call assert_equal("c-c", g:current_modes) + " Executing commands in Vim Ex mode should return "cv", never "cvr", " as Cmdline editing has already ended. call feedkeys("gQcall Save_mode()\<CR>vi\<CR>", 'xt') @@ -3822,6 +3826,29 @@ func Test_glob2() endif endfunc +func Test_glob_symlinks() + call writefile([], 'Xglob1') + + if has("win32") + silent !mklink XglobBad DoesNotExist + if v:shell_error + throw 'Skipped: cannot create symlinks' + endif + silent !mklink XglobOk Xglob1 + else + silent !ln -s DoesNotExist XglobBad + silent !ln -s Xglob1 XglobOk + endif + + " The broken symlink is excluded when alllinks is false. + call assert_equal(['Xglob1', 'XglobBad', 'XglobOk'], sort(glob('Xglob*', 0, 1, 1))) + call assert_equal(['Xglob1', 'XglobOk'], sort(glob('Xglob*', 0, 1, 0))) + + call delete('Xglob1') + call delete('XglobBad') + call delete('XglobOk') +endfunc + " Test for browse() func Test_browse() CheckFeature browse @@ -3842,11 +3869,6 @@ func Test_default_arg_value() call assert_equal('msg', HasDefault()) endfunc -" Test for gettext() -func Test_gettext() - call assert_fails('call gettext(1)', 'E1174:') -endfunc - func Test_builtin_check() call assert_fails('let g:["trim"] = {x -> " " .. x}', 'E704:') call assert_fails('let g:.trim = {x -> " " .. x}', 'E704:') diff --git a/src/testdir/test_gettext.vim b/src/testdir/test_gettext.vim new file mode 100644 index 0000000..a990121 --- /dev/null +++ b/src/testdir/test_gettext.vim @@ -0,0 +1,18 @@ +source check.vim + +CheckFeature gettext + +" Test for gettext() +func Test_gettext() + call assert_fails('call bindtextdomain("test")', 'E119:') + call assert_fails('call bindtextdomain("vim", "test")', 'E475:') + + call assert_fails('call gettext(1)', 'E1174:') + call assert_equal('xxxTESTxxx', gettext("xxxTESTxxx")) + + call assert_equal('xxxTESTxxx', gettext("xxxTESTxxx", "vim")) + call assert_equal('xxxTESTxxx', gettext("xxxTESTxxx", "__PACKAGE__")) + call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__")) +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_gettext_cp1251.vim b/src/testdir/test_gettext_cp1251.vim new file mode 100644 index 0000000..69d2bbf --- /dev/null +++ b/src/testdir/test_gettext_cp1251.vim @@ -0,0 +1,35 @@ +source check.vim +" This fail on CI MacOS 14 because bindtextdomain() is not available there +" (missing library?) +CheckNotMac +CheckFeature gettext + +" Test for gettext() +func Test_gettext() + set encoding=cp1251 + call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__")) + + try + call assert_true(bindtextdomain("__PACKAGE__", getcwd())) + + try + language messages ru_RU + call assert_equal('ÎØÈÁÊÀ: ', gettext("ERROR: ", "__PACKAGE__")) + catch /^Vim\%((\a\+)\)\=:E197:/ + throw "Skipped: not possible to set locale to ru (missing?)" + endtry + + try + language messages en_GB.UTF-8 + call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__")) + catch /^Vim\%((\a\+)\)\=:E197:/ + throw "Skipped: not possible to set locale to en (missing?)" + endtry + + catch /^Vim\%((\a\+)\)\=:E342:/ + throw "Skipped: out of memory executing bindtextdomain()" + endtry + set encoding& +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_gettext_make.vim b/src/testdir/test_gettext_make.vim new file mode 100644 index 0000000..1242fa4 --- /dev/null +++ b/src/testdir/test_gettext_make.vim @@ -0,0 +1,72 @@ +source check.vim +CheckNotMac +CheckFeature gettext + +" Test for package translation Makefile +func Test_gettext_makefile() + cd ../po + if has('win32') + if getenv('GETTEXT_PATH') == v:null + throw 'Skipped: %GETTEXT_PATH% is not set.' + endif + call system('nmake.exe -f Make_mvc.mak "VIMPROG=' .. getenv('VIMPROG') .. + \ '" "GETTEXT_PATH=' .. getenv('GETTEXT_PATH') .. + \ '" PLUGPACKAGE=test_gettext + \ "PO_PLUG_INPUTLIST=..\testdir\test_gettext_makefile_in1.vim + \ ..\testdir\test_gettext_makefile_in2.vim + \ ..\testdir\test_gettext_makefile_in3.vim + \ ..\testdir\test_gettext_makefile_in4.vim" test_gettext.pot') + else +" Will it work on macOS? + call system("make -f Makefile PLUGPACKAGE=test_gettext + \ PO_PLUG_INPUTLIST=\"../testdir/test_gettext_makefile_in1.vim + \ ../testdir/test_gettext_makefile_in2.vim + \ ../testdir/test_gettext_makefile_in3.vim + \ ../testdir/test_gettext_makefile_in4.vim\" test_gettext.pot") + endif + if v:shell_error != 0 + throw 'Fail to create test_gettext.pot. Error code: ' .. v:shell_error + endif + let expected =<< trim END + # SOME DESCRIPTIVE TITLE. + # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER + # This file is distributed under the same license as the test_gettext package. + # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. + # + #, fuzzy + msgid "" + msgstr "" + "Project-Id-Version: test_gettext\n" + "Report-Msgid-Bugs-To: \n" + "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" + "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" + "Language-Team: LANGUAGE <LL@li.org>\n" + "Language: \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=CHARSET\n" + "Content-Transfer-Encoding: 8bit\n" + + #: ../testdir/test_gettext_makefile_in1.vim:4 ../testdir/test_gettext_makefile_in1.vim:6 + #: ../testdir/test_gettext_makefile_in2.vim:5 ../testdir/test_gettext_makefile_in4.vim:4 + msgid "This is a test" + msgstr "" + + #: ../testdir/test_gettext_makefile_in1.vim:5 + msgid "This is another test" + msgstr "" + + #: ../testdir/test_gettext_makefile_in2.vim:4 + msgid "This is a test from the second file" + msgstr "" + + #: ../testdir/test_gettext_makefile_in4.vim:5 + msgid "This is a fourth test" + msgstr "" + END + let potfile = filter(readfile("test_gettext.pot"), 'v:val !~ "POT-Creation-Date"') + call assert_equal(expected, potfile) + call delete('test_gettext.pot') + cd - +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_gettext_makefile_in1.vim b/src/testdir/test_gettext_makefile_in1.vim new file mode 100644 index 0000000..cbe1159 --- /dev/null +++ b/src/testdir/test_gettext_makefile_in1.vim @@ -0,0 +1,7 @@ +" Test file for gettext() package makefile +" Last Change: 2024 Jun 01 + +echo gettext("This is a test", "test_gettext") +echo gettext("This is another test", "test_gettext") +echo gettext("This is a test", "test_gettext") +" vim: ts=8 diff --git a/src/testdir/test_gettext_makefile_in2.vim b/src/testdir/test_gettext_makefile_in2.vim new file mode 100644 index 0000000..86d3dd9 --- /dev/null +++ b/src/testdir/test_gettext_makefile_in2.vim @@ -0,0 +1,6 @@ +" Test file for gettext() package makefile +" Last Change: 2024 Jun 01 + +echo gettext("This is a test from the second file", "test_gettext") +echo gettext("This is a test", "test_gettext") +" vim: ts=8 diff --git a/src/testdir/test_gettext_makefile_in3.vim b/src/testdir/test_gettext_makefile_in3.vim new file mode 100644 index 0000000..f4cf93d --- /dev/null +++ b/src/testdir/test_gettext_makefile_in3.vim @@ -0,0 +1,4 @@ +" Test file for gettext() package makefile +" Last Change: 2024 Jun 01 + +" vim: ts=8 diff --git a/src/testdir/test_gettext_makefile_in4.vim b/src/testdir/test_gettext_makefile_in4.vim new file mode 100644 index 0000000..7f9f3f7 --- /dev/null +++ b/src/testdir/test_gettext_makefile_in4.vim @@ -0,0 +1,6 @@ +" Test file for gettext() package makefile +" Last Change: 2024 Jun 01 + +echo gettext("This is a test", "test_gettext") +echo gettext("This is a fourth test", "test_gettext") +" vim: ts=8 diff --git a/src/testdir/test_gettext_utf8.vim b/src/testdir/test_gettext_utf8.vim new file mode 100644 index 0000000..b96f8ea --- /dev/null +++ b/src/testdir/test_gettext_utf8.vim @@ -0,0 +1,35 @@ +source check.vim +" This fail on CI MacOS 14 because bindtextdomain() is not available there +" (missing library?) +CheckNotMac +CheckFeature gettext + +" Test for gettext() +func Test_gettext() + set encoding=utf-8 + call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__")) + + try + call assert_true(bindtextdomain("__PACKAGE__", getcwd())) + + try + language messages ru_RU + call assert_equal('ОШИБКÐ: ', gettext("ERROR: ", "__PACKAGE__")) + catch /^Vim\%((\a\+)\)\=:E197:/ + throw "Skipped: not possible to set locale to ru (missing?)" + endtry + + try + language messages en_GB.UTF-8 + call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__")) + catch /^Vim\%((\a\+)\)\=:E197:/ + throw "Skipped: not possible to set locale to en (missing?)" + endtry + + catch /^Vim\%((\a\+)\)\=:E342:/ + throw "Skipped: out of memory executing bindtextdomain()" + endtry + set encoding& +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_getvar.vim b/src/testdir/test_getvar.vim index 2065186..6efb192 100644 --- a/src/testdir/test_getvar.vim +++ b/src/testdir/test_getvar.vim @@ -142,20 +142,28 @@ func Test_get_func() let l:F = function('tr') call assert_equal('tr', get(l:F, 'name')) call assert_equal(l:F, get(l:F, 'func')) + call assert_equal({'required': 3, 'optional': 0, 'varargs': v:false}, + \ get(l:F, 'arity')) let Fb_func = function('s:FooBar') call assert_match('<SNR>\d\+_FooBar', get(Fb_func, 'name')) + call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false}, + \ get(Fb_func, 'arity')) let Fb_ref = funcref('s:FooBar') call assert_match('<SNR>\d\+_FooBar', get(Fb_ref, 'name')) + call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false}, + \ get(Fb_ref, 'arity')) call assert_equal({'func has': 'no dict'}, get(l:F, 'dict', {'func has': 'no dict'})) call assert_equal(0, get(l:F, 'dict')) call assert_equal([], get(l:F, 'args')) + let NF = test_null_function() call assert_equal('', get(NF, 'name')) call assert_equal(NF, get(NF, 'func')) call assert_equal(0, get(NF, 'dict')) call assert_equal([], get(NF, 'args')) + call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false}, get(NF, 'arity')) endfunc " get({partial}, {what} [, {default}]) - in test_partial.vim diff --git a/src/testdir/test_goto.vim b/src/testdir/test_goto.vim index 357a8d2..b6a6695 100644 --- a/src/testdir/test_goto.vim +++ b/src/testdir/test_goto.vim @@ -296,6 +296,7 @@ func Test_gd_string() return x; } [CODE] + call XTest_goto_decl('gd', lines, 4, 7) endfunc @@ -320,14 +321,16 @@ func Test_set_options_keep_col() let pos = getcurpos() normal j set invhlsearch spell spelllang=en,cjk spelloptions=camel textwidth=80 - set cursorline cursorcolumn cursorlineopt=line colorcolumn=+1 + set cursorline cursorcolumn cursorlineopt=line colorcolumn=+1 winfixbuf + set comments=:# commentstring=#%s define=function set background=dark set background=light normal k call assert_equal(pos, getcurpos()) bwipe! set hlsearch& spell& spelllang& spelloptions& textwidth& - set cursorline& cursorcolumn& cursorlineopt& colorcolumn& + set cursorline& cursorcolumn& cursorlineopt& colorcolumn& winfixbuf& + set comments& commentstring& define& set background& endfunc diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim index d53750f..ae65310 100644 --- a/src/testdir/test_gui.vim +++ b/src/testdir/test_gui.vim @@ -1708,7 +1708,8 @@ func Test_gui_lowlevel_keyevent() new " Test for <Ctrl-A> to <Ctrl-Z> keys - for kc in range(65, 90) + " FIXME: <Ctrl-C> is excluded for now. It makes the test flaky. + for kc in range(65, 66) + range(68, 90) call SendKeys([0x11, kc]) try let ch = getcharstr() diff --git a/src/testdir/test_increment.vim b/src/testdir/test_increment.vim index fdd7c0c..3a5f5ee 100644 --- a/src/testdir/test_increment.vim +++ b/src/testdir/test_increment.vim @@ -840,6 +840,44 @@ func Test_increment_unsigned() set nrformats-=unsigned endfunc +" Try incrementing/decrementing a number when nrformats contains blank +func Test_increment_blank() + set nrformats+=blank + + " Signed + call setline(1, '0') + exec "norm! gg0\<C-X>" + call assert_equal('-1', getline(1)) + + call setline(1, '3') + exec "norm! gg010\<C-X>" + call assert_equal('-7', getline(1)) + + call setline(1, '-0') + exec "norm! gg0\<C-X>" + call assert_equal("-1", getline(1)) + + " Unsigned + " NOTE: 18446744073709551615 == 2^64 - 1 + call setline(1, 'a-18446744073709551615') + exec "norm! gg0\<C-A>" + call assert_equal('a-18446744073709551615', getline(1)) + + call setline(1, 'a-18446744073709551615') + exec "norm! gg0\<C-A>" + call assert_equal('a-18446744073709551615', getline(1)) + + call setline(1, 'a-18446744073709551614') + exec "norm! gg08\<C-A>" + call assert_equal('a-18446744073709551615', getline(1)) + + call setline(1, 'a-1') + exec "norm! gg0\<C-A>" + call assert_equal('a-2', getline(1)) + + set nrformats-=blank +endfunc + func Test_in_decrement_large_number() " NOTE: 18446744073709551616 == 2^64 call setline(1, '18446744073709551616') diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim index 48589ce..aee3393 100644 --- a/src/testdir/test_ins_complete.vim +++ b/src/testdir/test_ins_complete.vim @@ -2586,9 +2586,85 @@ func Test_complete_fuzzy_match() call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') call assert_equal('hello help hero h', getline('.')) + set completeopt-=noinsert + call setline(1, ['xyz yxz x']) + call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('xyz yxz xyz', getline('.')) + " can fuzzy get yxz when use Ctrl-N twice + call setline(1, ['xyz yxz x']) + call feedkeys("A\<C-X>\<C-N>\<C-N>\<Esc>0", 'tx!') + call assert_equal('xyz yxz yxz', getline('.')) + + call setline(1, ['ä½ å¥½ ä½ ']) + call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('ä½ å¥½ ä½ å¥½', getline('.')) + call setline(1, ['ä½ çš„ 我的 çš„']) + call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('ä½ çš„ 我的 ä½ çš„', getline('.')) + " can fuzzy get multiple-byte word when use Ctrl-N twice + call setline(1, ['ä½ çš„ 我的 çš„']) + call feedkeys("A\<C-X>\<C-N>\<C-N>\<Esc>0", 'tx!') + call assert_equal('ä½ çš„ 我的 我的', getline('.')) + + " respect wrapscan + set nowrapscan + call setline(1, ["xyz", "yxz", ""]) + call cursor(3, 1) + call feedkeys("Sy\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('y', getline('.')) + set wrapscan + call feedkeys("Sy\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('xyz', getline('.')) + + " fuzzy on file + call writefile([''], 'fobar', 'D') + call writefile([''], 'foobar', 'D') + call setline(1, ['fob']) + call cursor(1, 1) + call feedkeys("A\<C-X>\<C-f>\<Esc>0", 'tx!') + call assert_equal('fobar', getline('.')) + call feedkeys("Sfob\<C-X>\<C-f>\<C-N>\<Esc>0", 'tx!') + call assert_equal('foobar', getline('.')) + call feedkeys("S../\<C-X>\<C-f>\<Esc>0", 'tx!') + call assert_match('../*', getline('.')) + call feedkeys("S../td\<C-X>\<C-f>\<Esc>0", 'tx!') + call assert_match('../testdir', getline('.')) + + " can get completion from other buffer + set completeopt=fuzzy,menu,menuone + vnew + call setline(1, ["completeness,", "compatibility", "Composite", "Omnipotent"]) + wincmd p + call feedkeys("Somp\<C-N>\<Esc>0", 'tx!') + call assert_equal('completeness', getline('.')) + call feedkeys("Somp\<C-N>\<C-N>\<Esc>0", 'tx!') + call assert_equal('compatibility', getline('.')) + call feedkeys("Somp\<C-P>\<Esc>0", 'tx!') + call assert_equal('Omnipotent', getline('.')) + call feedkeys("Somp\<C-P>\<C-P>\<Esc>0", 'tx!') + call assert_equal('Composite', getline('.')) + call feedkeys("S omp\<C-N>\<Esc>0", 'tx!') + call assert_equal(' completeness', getline('.')) + + " fuzzy on whole line completion + call setline(1, ["world is on fire", "no one can save me but you", 'user can execute', '']) + call cursor(4, 1) + call feedkeys("Swio\<C-X>\<C-L>\<Esc>0", 'tx!') + call assert_equal('world is on fire', getline('.')) + call feedkeys("Su\<C-X>\<C-L>\<C-P>\<Esc>0", 'tx!') + call assert_equal('no one can save me but you', getline('.')) + + " issue #15526 + set completeopt=fuzzy,menuone,menu,noselect + call setline(1, ['Text', 'ToText', '']) + call cursor(2, 1) + call feedkeys("STe\<C-X>\<C-N>x\<CR>\<Esc>0", 'tx!') + call assert_equal('Tex', getline('.')) + " clean up set omnifunc= bw! + bw! set complete& completeopt& autocmd! AAAAA_Group augroup! AAAAA_Group @@ -2599,6 +2675,38 @@ func Test_complete_fuzzy_match() unlet g:word endfunc +func Test_complete_fuzzy_with_completeslash() + CheckMSWindows + + call writefile([''], 'fobar', 'D') + let orig_shellslash = &shellslash + set cpt& + new + set completeopt+=fuzzy + set noshellslash + + " Test with completeslash unset + set completeslash= + call setline(1, ['.\fob']) + call feedkeys("A\<C-X>\<C-F>\<Esc>0", 'tx!') + call assert_equal('.\fobar', getline('.')) + + " Test with completeslash=backslash + set completeslash=backslash + call feedkeys("S.\\fob\<C-X>\<C-F>\<Esc>0", 'tx!') + call assert_equal('.\fobar', getline('.')) + + " Test with completeslash=slash + set completeslash=slash + call feedkeys("S.\\fob\<C-X>\<C-F>\<Esc>0", 'tx!') + call assert_equal('./fobar', getline('.')) + + " Reset and clean up + let &shellslash = orig_shellslash + set completeslash= + %bw! +endfunc + " Check that tie breaking is stable for completeopt+=fuzzy (which should " behave the same on different platforms). func Test_complete_fuzzy_match_tie() @@ -2619,4 +2727,14 @@ func Test_complete_fuzzy_match_tie() set completeopt& endfunc +func Test_complete_backwards_default() + new + call append(1, ['foobar', 'foobaz']) + new + call feedkeys("i\<c-p>", 'tx') + call assert_equal('foobaz', getline('.')) + bw! + bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab nofoldenable diff --git a/src/testdir/test_jumplist.vim b/src/testdir/test_jumplist.vim index 8fbf39f..4b9fcee 100644 --- a/src/testdir/test_jumplist.vim +++ b/src/testdir/test_jumplist.vim @@ -59,29 +59,63 @@ func Test_getjumplist() call assert_equal(4, l[1]) endfunc -func Test_jumplist_invalid() +func Test_jumplist_wipe_buf() new clearjumps - " put some randome text - put ='a' - let prev = bufnr('%') + " Put some random text and fill the jump list. + call setline(1, ['foo', 'bar', 'baz']) + normal G + normal gg setl nomodified bufhidden=wipe e XXJumpListBuffer - let bnr = bufnr('%') - " 1) empty jumplist - let expected = [[ - \ {'lnum': 2, 'bufnr': prev, 'col': 0, 'coladd': 0}], 1] - call assert_equal(expected, getjumplist()) + " The jump list is empty as the buffer was wiped out. + call assert_equal([[], 0], getjumplist()) let jumps = execute(':jumps') call assert_equal('>', jumps[-1:]) - " now jump back - exe ":norm! \<c-o>" - let expected = [[ - \ {'lnum': 2, 'bufnr': prev, 'col': 0, 'coladd': 0}, - \ {'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0}], 0] - call assert_equal(expected, getjumplist()) - let jumps = execute(':jumps') - call assert_match('> 0 2 0 -invalid-', jumps) + + " Put some random text and fill the jump list. + call setline(1, ['foo', 'bar', 'baz']) + setl bufhidden=hide + + " References to wiped buffer are deleted with multiple tabpages. + let [w1, t1] = [win_getid(), tabpagenr()] + clearjumps + normal G + normal gg + enew + + split XXJumpListBuffer + let [w2, t2] = [win_getid(), tabpagenr()] + clearjumps + normal G + normal gg + enew + + tabnew XXJumpListBuffer + let [w3, t3] = [win_getid(), tabpagenr()] + clearjumps + normal G + normal gg + enew + + split XXJumpListBuffer + let [w4, t4] = [win_getid(), tabpagenr()] + clearjumps + normal G + normal gg + enew + + for [w, t] in [[w1, t1], [w2, t2], [w3, t3], [w4, t4]] + call assert_equal(2, len(getjumplist(w, t)[0])) + endfor + + bwipe! XXJumpListBuffer + + for [w, t] in [[w1, t1], [w2, t2], [w3, t3], [w4, t4]] + call assert_equal(0, len(getjumplist(w, t)[0])) + endfor + + %bwipe! endfunc " Test for '' mark in an empty buffer diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim index 12a6dd4..48217cf 100644 --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -1147,6 +1147,19 @@ func Test_listdict_compare() call assert_fails('echo {} =~ {}', 'E736:') endfunc +func Test_recursive_listdict_compare() + let l1 = [0, 1] + let l1[0] = l1 + let l2 = [0, 1] + let l2[0] = l2 + call assert_true(l1 == l2) + let d1 = {0: 0, 1: 1} + let d1[0] = d1 + let d2 = {0: 0, 1: 1} + let d2[0] = d2 + call assert_true(d1 == d2) +endfunc + " compare complex recursively linked list and dict func Test_listdict_compare_complex() let lines =<< trim END @@ -1557,4 +1570,83 @@ func Test_extendnew_leak() for i in range(100) | silent! call extendnew({}, {}, {}) | endfor endfunc +" Test for comparing deeply nested List/Dict values +func Test_deep_nested_listdict_compare() + let lines =<< trim END + def GetNestedList(sz: number): list<any> + var l: list<any> = [] + var x: list<any> = l + for i in range(sz) + var y: list<any> = [1] + add(x, y) + x = y + endfor + return l + enddef + + VAR l1 = GetNestedList(1000) + VAR l2 = GetNestedList(999) + call assert_false(l1 == l2) + + #" after 1000 nested items, the lists are considered to be equal + VAR l3 = GetNestedList(1001) + VAR l4 = GetNestedList(1002) + call assert_true(l3 == l4) + END + call v9.CheckLegacyAndVim9Success(lines) + + let lines =<< trim END + def GetNestedDict(sz: number): dict<any> + var d: dict<any> = {} + var x: dict<any> = d + for i in range(sz) + var y: dict<any> = {} + x['a'] = y + x = y + endfor + return d + enddef + + VAR d1 = GetNestedDict(1000) + VAR d2 = GetNestedDict(999) + call assert_false(d1 == d2) + + #" after 1000 nested items, the Dicts are considered to be equal + VAR d3 = GetNestedDict(1001) + VAR d4 = GetNestedDict(1002) + call assert_true(d3 == d4) + END + call v9.CheckLegacyAndVim9Success(lines) +endfunc + +" Test for using id() +def Test_id_with_dict() + # demonstate a way that "id(item)" differs from "string(item)" + var d1 = {one: 1} + var d2 = {one: 1} + var d3 = {one: 1} + var idDict: dict<any> + idDict[id(d1)] = d1 + idDict[id(d2)] = d2 + idDict[id(d3)] = d3 + assert_equal(3, idDict->len()) + + var stringDict: dict<any> + stringDict[string(d1)] = d1 + stringDict[string(d2)] = d2 + stringDict[string(d3)] = d3 + assert_equal(1, stringDict->len()) + + assert_equal('', id(3)) + + assert_equal('', id(null)) + assert_equal('', id(null_blob)) + assert_equal('', id(null_dict)) + assert_equal('', id(null_function)) + assert_equal('', id(null_list)) + assert_equal('', id(null_partial)) + assert_equal('', id(null_string)) + assert_equal('', id(null_channel)) + assert_equal('', id(null_job)) +enddef " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_listlbr_utf8.vim b/src/testdir/test_listlbr_utf8.vim index 313ff30..693f201 100644 --- a/src/testdir/test_listlbr_utf8.vim +++ b/src/testdir/test_listlbr_utf8.vim @@ -280,6 +280,9 @@ func Test_chinese_char_on_wrap_column() call s:compare_lines(expect, lines) call assert_equal(len(expect), winline()) call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol()) + norm! g0 + call assert_equal(len(expect), winline()) + call assert_equal(1, wincol()) call s:close_windows() endfunc @@ -315,6 +318,9 @@ func Test_chinese_char_on_wrap_column_sbr() call s:compare_lines(expect, lines) call assert_equal(len(expect), winline()) call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol()) + norm! g0 + call assert_equal(len(expect), winline()) + call assert_equal(4, wincol()) call s:close_windows() endfunc diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim index 1175310..064f8ac 100644 --- a/src/testdir/test_mapping.vim +++ b/src/testdir/test_mapping.vim @@ -1767,6 +1767,49 @@ func Test_unmap_simplifiable() unmap <C-I> endfunc +" Test that the first byte of rhs is not remapped if rhs starts with lhs. +func Test_map_rhs_starts_with_lhs() + new + func MapExpr() + return "\<C-R>\<C-P>" + endfunc + + for expr in [v:false, v:true] + if expr + imap <buffer><expr> <C-R> MapExpr() + else + imap <buffer> <C-R> <C-R><C-P> + endif + + for restore in [v:false, v:true] + if restore + let saved = maparg('<C-R>', 'i', v:false, v:true) + iunmap <buffer> <C-R> + call mapset(saved) + endif + + let @a = 'foo' + call assert_nobeep('call feedkeys("S\<C-R>a", "tx")') + call assert_equal('foo', getline('.')) + + let @a = 'bar' + call assert_nobeep('call feedkeys("S\<*C-R>a", "tx")') + call assert_equal('bar', getline('.')) + endfor + endfor + + " When two mappings are used for <C-I> and <Tab>, remapping should work. + imap <buffer> <C-I> <Tab>bar + imap <buffer> <Tab> foo + call feedkeys("S\<Tab>", 'xt') + call assert_equal('foo', getline('.')) + call feedkeys("S\<*C-I>", 'xt') + call assert_equal('foobar', getline('.')) + + delfunc MapExpr + bwipe! +endfunc + func Test_expr_map_escape_special() nnoremap … <Cmd>let g:got_ellipsis += 1<CR> func Func() diff --git a/src/testdir/test_matchparen.vim b/src/testdir/test_matchparen.vim index 70aa38f..49d3510 100644 --- a/src/testdir/test_matchparen.vim +++ b/src/testdir/test_matchparen.vim @@ -108,5 +108,35 @@ func Test_matchparen_pum_clear() call StopVimInTerminal(buf) endfunc +" Test that matchparen works with multibyte chars in 'matchpairs' +func Test_matchparen_mbyte() + CheckScreendump + + let lines =<< trim END + source $VIMRUNTIME/plugin/matchparen.vim + call setline(1, ['aaaaaaaa(', 'bbbb)cc']) + set matchpairs+=(:) + END + + call writefile(lines, 'XmatchparenMbyte', 'D') + let buf = RunVimInTerminal('-S XmatchparenMbyte', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_1', {}) + call term_sendkeys(buf, "$") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_2', {}) + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_3', {}) + call term_sendkeys(buf, "2h") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_4', {}) + call term_sendkeys(buf, "0") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_5', {}) + call term_sendkeys(buf, "kA") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_6', {}) + call term_sendkeys(buf, "\<Down>") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_7', {}) + call term_sendkeys(buf, "\<C-W>") + call VerifyScreenDump(buf, 'Test_matchparen_mbyte_8', {}) + + call StopVimInTerminal(buf) +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_menu.vim b/src/testdir/test_menu.vim index 2229228..40fec40 100644 --- a/src/testdir/test_menu.vim +++ b/src/testdir/test_menu.vim @@ -481,13 +481,48 @@ func Test_popup_menu() unmenu PopUp endfunc +func Test_popup_menu_truncated() + CheckNotGui + + set mouse=a mousemodel=popup + aunmenu PopUp + for i in range(2 * &lines) + exe $'menu PopUp.{i} <Cmd>let g:res = {i}<CR>' + endfor + + func LeftClickExpr(row, col) + call test_setmouse(a:row, a:col) + return "\<LeftMouse>" + endfunc + + " Clicking at the bottom should place popup menu above click position. + " <RightRelease> should not select an item immediately. + let g:res = -1 + call test_setmouse(&lines, 1) + nnoremap <expr><F2> LeftClickExpr(4, 1) + call feedkeys("\<RightMouse>\<RightRelease>\<F2>", 'tx') + call assert_equal(3, g:res) + + " Clicking at the top should place popup menu below click position. + let g:res = -1 + call test_setmouse(1, 1) + nnoremap <expr><F2> LeftClickExpr(5, 1) + call feedkeys("\<RightMouse>\<RightRelease>\<F2>", 'tx') + call assert_equal(3, g:res) + + nunmap <F2> + delfunc LeftClickExpr + unlet g:res + aunmenu PopUp + set mouse& mousemodel& +endfunc + " Test for MenuPopup autocommand func Test_autocmd_MenuPopup() CheckNotGui - set mouse=a - set mousemodel=popup - aunmenu * + set mouse=a mousemodel=popup + aunmenu PopUp autocmd MenuPopup * exe printf( \ 'anoremenu PopUp.Foo <Cmd>let g:res = ["%s", "%s"]<CR>', \ expand('<afile>'), expand('<amatch>')) diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim index 83594d2..398bf29 100644 --- a/src/testdir/test_normal.vim +++ b/src/testdir/test_normal.vim @@ -4257,6 +4257,9 @@ func Test_page_cursor_topbot() call assert_equal(18, line('.')) exe "norm! \<C-B>\<C-F>" call assert_equal(9, line('.')) + " Not when already at the start of the buffer. + exe "norm! ggj\<C-B>" + call assert_equal(2, line('.')) bwipe! endfunc diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim index fbfbaae..94c98fe 100644 --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -548,6 +548,9 @@ func Test_set_completion_string_values() call assert_equal('sync', getcompletion('set swapsync=', 'cmdline')[1]) call assert_equal('usetab', getcompletion('set switchbuf=', 'cmdline')[1]) call assert_equal('ignore', getcompletion('set tagcase=', 'cmdline')[1]) + if exists('+tabclose') + call assert_equal('left uselast', join(sort(getcompletion('set tabclose=', 'cmdline'))), ' ') + endif if exists('+termwintype') call assert_equal('conpty', getcompletion('set termwintype=', 'cmdline')[1]) endif @@ -1407,7 +1410,8 @@ func Test_write() set nowrite call assert_fails('write Xwrfile', 'E142:') set write - close! + " close swapfile + bw! endfunc " Test for 'buftype' option @@ -1724,7 +1728,7 @@ func Test_VIM_POSIX() qall [CODE] if RunVim([], after, '') - call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\.;', + call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>#{|&/\.;', \ 'AS'], readfile('X_VIM_POSIX')) endif @@ -1734,7 +1738,7 @@ func Test_VIM_POSIX() qall [CODE] if RunVim([], after, '') - call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;', + call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>;', \ 'S'], readfile('X_VIM_POSIX')) endif diff --git a/src/testdir/test_partial.vim b/src/testdir/test_partial.vim index b5a58f6..acc8b73 100644 --- a/src/testdir/test_partial.vim +++ b/src/testdir/test_partial.vim @@ -311,6 +311,11 @@ func Test_auto_partial_rebind() endfunc func Test_get_partial_items() + func s:Qux(x, y, z=3, w=1, ...) + endfunc + func s:Qux1(x, y) + endfunc + let dict = {'name': 'hello'} let args = ["foo", "bar"] let Func = function('MyDictFunc') @@ -331,6 +336,23 @@ func Test_get_partial_items() let dict = {'partial has': 'no dict'} call assert_equal(dict, get(P, 'dict', dict)) call assert_equal(0, get(l:P, 'dict')) + + call assert_equal({'required': 2, 'optional': 2, 'varargs': v:true}, + \ get(funcref('s:Qux', []), 'arity')) + call assert_equal({'required': 1, 'optional': 2, 'varargs': v:true}, + \ get(funcref('s:Qux', [1]), 'arity')) + call assert_equal({'required': 0, 'optional': 2, 'varargs': v:true}, + \ get(funcref('s:Qux', [1, 2]), 'arity')) + call assert_equal({'required': 0, 'optional': 1, 'varargs': v:true}, + \ get(funcref('s:Qux', [1, 2, 3]), 'arity')) + call assert_equal({'required': 0, 'optional': 0, 'varargs': v:true}, + \ get(funcref('s:Qux', [1, 2, 3, 4]), 'arity')) + " More args than expected is not an error + call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false}, + \ get(funcref('s:Qux1', [1, 2, 3, 4]), 'arity')) + + delfunc s:Qux + delfunc s:Qux1 endfunc func Test_compare_partials() diff --git a/src/testdir/test_paste.vim b/src/testdir/test_paste.vim index d079f48..b35fc81 100644 --- a/src/testdir/test_paste.vim +++ b/src/testdir/test_paste.vim @@ -93,7 +93,7 @@ func Test_paste_ex_mode() call assert_equal("foo\rbar", foo) " pasting more than 40 bytes - exe "norm Q\<PasteStart>0000000000000000000000000000000000000000000000000000000000000000000000\<C-C>" + exe "norm Q\<PasteStart>s/.*/0000000000000000000000000000000000000000000000000000000000000000/\<C-C>" endfunc func Test_paste_onechar() diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim index dd01a57..fe958da 100644 --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -1482,8 +1482,101 @@ func Test_pum_highlights_match() call term_sendkeys(buf, "o\<BS>\<C-R>=Comp()\<CR>") call VerifyScreenDump(buf, 'Test_pum_highlights_09', {}) + " issue #15095 wrong select + call term_sendkeys(buf, "\<ESC>:set completeopt=fuzzy,menu\<CR>") + call TermWait(buf) + call term_sendkeys(buf, "S hello helio hero h\<C-X>\<C-P>") + call TermWait(buf, 50) + call VerifyScreenDump(buf, 'Test_pum_highlights_10', {}) + + call term_sendkeys(buf, "\<ESC>S hello helio hero h\<C-X>\<C-P>\<C-P>") + call TermWait(buf, 50) + call VerifyScreenDump(buf, 'Test_pum_highlights_11', {}) + + " issue #15357 + call term_sendkeys(buf, "\<ESC>S/non_exit_folder\<C-X>\<C-F>") + call TermWait(buf, 50) + call VerifyScreenDump(buf, 'Test_pum_highlights_15', {}) + + call term_sendkeys(buf, "\<C-E>\<Esc>") + call TermWait(buf) + + call StopVimInTerminal(buf) +endfunc + +func Test_pum_user_hl_group() + CheckScreendump + let lines =<< trim END + func CompleteFunc( findstart, base ) + if a:findstart + return 0 + endif + return { + \ 'words': [ + \ { 'word': 'aword1', 'menu': 'extra text 1', 'kind': 'W', 'hl_group': 'StrikeFake' }, + \ { 'word': 'aword2', 'menu': 'extra text 2', 'kind': 'W', }, + \ { 'word': 'ä½ å¥½', 'menu': 'extra text 3', 'kind': 'W', 'hl_group': 'StrikeFake' }, + \]} + endfunc + set completeopt=menu + set completefunc=CompleteFunc + + hi StrikeFake ctermfg=9 + func HlMatch() + hi PmenuMatchSel ctermfg=6 ctermbg=7 cterm=underline + hi PmenuMatch ctermfg=4 ctermbg=225 cterm=underline + endfunc + END + call writefile(lines, 'Xscript', 'D') + let buf = RunVimInTerminal('-S Xscript', {}) + + call TermWait(buf) + call term_sendkeys(buf, "Saw\<C-X>\<C-U>") + call VerifyScreenDump(buf, 'Test_pum_highlights_12', {}) + call term_sendkeys(buf, "\<C-E>\<Esc>") + + call TermWait(buf) + call term_sendkeys(buf, ":call HlMatch()\<CR>") + + call TermWait(buf) + call term_sendkeys(buf, "Saw\<C-X>\<C-U>") + call VerifyScreenDump(buf, 'Test_pum_highlights_13', {}) + call term_sendkeys(buf, "\<C-N>") + call VerifyScreenDump(buf, 'Test_pum_highlights_14', {}) call term_sendkeys(buf, "\<C-E>\<Esc>") + + call StopVimInTerminal(buf) +endfunc + +func Test_pum_user_kind_hlgroup() + CheckScreendump + let lines =<< trim END + func CompleteFunc( findstart, base ) + if a:findstart + return 0 + endif + return { + \ 'words': [ + \ { 'word': 'aword1', 'menu': 'extra text 1', 'kind': 'variable', 'kind_hlgroup': 'KindVar', 'hl_group': 'StrikeFake' }, + \ { 'word': 'aword2', 'menu': 'extra text 2', 'kind': 'function', 'kind_hlgroup': 'KindFunc' }, + \ { 'word': 'ä½ å¥½', 'menu': 'extra text 3', 'kind': 'class', 'kind_hlgroup': 'KindClass' }, + \]} + endfunc + set completeopt=menu + set completefunc=CompleteFunc + + hi StrikeFake ctermfg=9 + hi KindVar ctermfg=yellow + hi KindFunc ctermfg=blue + hi KindClass ctermfg=green + END + call writefile(lines, 'Xscript', 'D') + let buf = RunVimInTerminal('-S Xscript', {}) + call TermWait(buf) + call term_sendkeys(buf, "S\<C-X>\<C-U>") + call VerifyScreenDump(buf, 'Test_pum_highlights_16', {}) + call term_sendkeys(buf, "\<C-E>\<Esc>") call StopVimInTerminal(buf) endfunc diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index a397f70..64aa654 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -2499,6 +2499,88 @@ func Test_popup_settext_null() call popup_close(id) endfunc +func Test_popup_setbuf() + CheckScreendump + + let lines =<< trim END + let opts = #{wrap: 0} + let p = popup_create('test', opts) + let buf = bufnr('%') + END + + call writefile(lines, 'XtestPopupSetBuf', 'D') + let buf = RunVimInTerminal('-S XtestPopupSetBuf', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_popup_setbuf_01', {}) + + " Setting to an non-existing buffer doesn't do anything + call term_sendkeys(buf, ":call popup_setbuf(p, 'foobar.txt')\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_02', {}) + + " Error + call term_sendkeys(buf, ":call popup_setbuf(p, ['a','b','c'])\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_03', {}) + + " Set to help window + call term_sendkeys(buf, ":help\<CR>") + call term_sendkeys(buf, ":call popup_setbuf(p, 'help.txt')\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_04', {}) + + " Setting back to original buffer + call term_sendkeys(buf, ":call popup_setbuf(p, buf)\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_05', {}) + + " use method + call term_sendkeys(buf, ":echo p->popup_setbuf('help.txt')\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_06', {}) + + call term_sendkeys(buf, ":echo p->popup_setbuf(buf)\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_05', {}) + + " clean up + call StopVimInTerminal(buf) +endfunc + +func Test_popup_setbuf_terminal() + CheckFeature terminal + + " Check Terminal Feature + let termbuf = term_start(&shell, #{hidden: 1}) + " Wait for shell to start + call WaitForAssert({-> assert_equal("run", job_status(term_getjob(termbuf)))}) + + let popup = popup_create('test', {}) + call assert_true(popup->popup_setbuf(termbuf)) + call popup_close(popup) + + let popup1 = popup_create(termbuf, #{minwidth: 40, minheight: 10, border: []}) + + let popup = popup_create('test', {}) + try + call assert_fails(call popup_setbuf(popup, termbuf)) + catch + endtry + call popup_close(popup) + call popup_close(popup1) + call assert_equal([], popup_list()) + " Close the terminal + call term_sendkeys(termbuf, "exit\<CR>") + " Wait for shell to exit + call WaitForAssert({-> assert_equal("dead", job_status(term_getjob(termbuf)))}) +endfunc + +func Test_popup_setbuf_null() + let id = popup_create('', {}) + call assert_false(popup_setbuf(id, -1)) + call popup_close(id) + + let id = popup_create('', {}) + call assert_true(popup_setbuf(id, test_null_string())) + call assert_true(popup_setbuf(id, '')) + call popup_close(id) + + call assert_false(popup_setbuf(id, 0)) +endfunc + func Test_popup_hidden() new diff --git a/src/testdir/test_put.vim b/src/testdir/test_put.vim index 69c2943..94e4f47 100644 --- a/src/testdir/test_put.vim +++ b/src/testdir/test_put.vim @@ -168,10 +168,6 @@ func Test_very_large_count() endfunc func Test_very_large_count_64bit() - if v:sizeoflong < 8 - throw 'Skipped: only works with 64 bit long ints' - endif - new let @" = repeat('x', 100) call assert_fails('norm 999999999p', 'E1240:') @@ -188,10 +184,6 @@ func Test_very_large_count_block() endfunc func Test_very_large_count_block_64bit() - if v:sizeoflong < 8 - throw 'Skipped: only works with 64 bit long ints' - endif - new call setline(1, repeat('x', 100)) exe "norm \<C-V>$y" diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index 0b61815..47b9b47 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -893,7 +893,7 @@ func Test_helpgrep() endfunc def Test_helpgrep_vim9_restore_cpo() - assert_equal('aABceFs', &cpo) + assert_equal('aABceFsz', &cpo) var rtp_save = &rtp var dir = 'Xruntime/after' @@ -905,7 +905,7 @@ def Test_helpgrep_vim9_restore_cpo() cwindow silent helpgrep grail - assert_equal('aABceFs', &cpo) + assert_equal('aABceFsz', &cpo) &rtp = rtp_save cclose helpclose diff --git a/src/testdir/test_regexp_utf8.vim b/src/testdir/test_regexp_utf8.vim index bc70544..51c0984 100644 --- a/src/testdir/test_regexp_utf8.vim +++ b/src/testdir/test_regexp_utf8.vim @@ -587,4 +587,36 @@ func Test_combining_chars_in_collection() bw! endfunc +func Test_search_multibyte_match_ascii() + new + " Match single 'Å¿' and 's' + call setline(1, 'das abc heraus abc Å¿ich abc Å¿ind') + for i in range(0, 2) + exe "set re="..i + let ic_match = matchbufline('%', '\c\%u17f', 1, '$')->mapnew({idx, val -> val.text}) + let noic_match = matchbufline('%', '\C\%u17f', 1, '$')->mapnew({idx, val -> val.text}) + call assert_equal(['s', 's', 'Å¿','Å¿'], ic_match, "Ignorecase Regex-engine: " .. &re) + call assert_equal(['Å¿','Å¿'], noic_match, "No-Ignorecase Regex-engine: " .. &re) + endfor + " Match several 'Å¿Å¿' and 'ss' + call setline(1, 'das abc herauss abc Å¿Å¿ich abc Å¿ind') + for i in range(0, 2) + exe "set re="..i + let ic_match = matchbufline('%', '\c\%u17f\%u17f', 1, '$')->mapnew({idx, val -> val.text}) + let noic_match = matchbufline('%', '\C\%u17f\%u17f', 1, '$')->mapnew({idx, val -> val.text}) + let ic_match2 = matchbufline('%', '\c\%u17f\+', 1, '$')->mapnew({idx, val -> val.text}) + let noic_match2 = matchbufline('%', '\C\%u17f\+', 1, '$')->mapnew({idx, val -> val.text}) + let ic_match3 = matchbufline('%', '\c[\u17f]\+', 1, '$')->mapnew({idx, val -> val.text}) + let noic_match3 = matchbufline('%', '\C[\u17f]\+', 1, '$')->mapnew({idx, val -> val.text}) + + call assert_equal(['ss', 'Å¿Å¿'], ic_match, "Ignorecase Regex-engine: " .. &re) + call assert_equal(['Å¿Å¿'], noic_match, "No-Ignorecase Regex-engine: " .. &re) + call assert_equal(['s', 'ss', 'Å¿Å¿', 'Å¿'], ic_match2, "Ignorecase Regex-engine: " .. &re) + call assert_equal(['Å¿Å¿','Å¿'], noic_match2, "No-Ignorecase Regex-engine: " .. &re) + call assert_equal(['s', 'ss', 'Å¿Å¿', 'Å¿'], ic_match3, "Ignorecase Collection Regex-engine: " .. &re) + call assert_equal(['Å¿Å¿','Å¿'], noic_match3, "No-Ignorecase Collection Regex-engine: " .. &re) + endfor + bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim index 1a9f49b..708aca2 100644 --- a/src/testdir/test_search.vim +++ b/src/testdir/test_search.vim @@ -1747,6 +1747,37 @@ func Test_search_with_no_last_pat() call delete('Xresult') endfunc +" Test for using the last substitute pattern without last search pattern. +func Test_search_with_last_substitute_pat() + let lines =<< trim [SCRIPT] + new + set shortmess+=S + call setline(1, repeat(['foofoo'], 3)) + %s/foo/bar/ + call assert_equal(repeat(['barfoo'], 3), getline(1, '$')) + + call cursor(1, 1) + call assert_equal("/foo", execute('call feedkeys("/\r", "tx")', '')->trim()) + call assert_equal([0, 1, 4, 0], getpos('.')) + + if has('rightleft') + set rightleft rightleftcmd=search + call cursor(1, 1) + call assert_equal("oof/", execute('call feedkeys("/\r", "tx")', '')->trim()) + call assert_equal([0, 1, 4, 0], getpos('.')) + endif + + call writefile(v:errors, 'Xresult') + qall! + [SCRIPT] + call writefile(lines, 'Xscript', 'D') + + if RunVim([], [], '--clean -S Xscript') + call assert_equal([], readfile('Xresult')) + endif + call delete('Xresult') +endfunc + " Test for using tilde (~) atom in search. This should use the last used " substitute pattern func Test_search_tilde_pat() diff --git a/src/testdir/test_selectmode.vim b/src/testdir/test_selectmode.vim index bf1b52b..63aa0b9 100644 --- a/src/testdir/test_selectmode.vim +++ b/src/testdir/test_selectmode.vim @@ -321,4 +321,20 @@ func Test_ins_ctrl_o_in_insert_mode_resets_selectmode() bwipe! endfunc +" Test that an :lmap mapping for a printable keypad key is applied when typing +" it in Select mode. +func Test_selectmode_keypad_lmap() + new + lnoremap <buffer> <kPoint> ??? + lnoremap <buffer> <kEnter> !!! + setlocal iminsert=1 + call setline(1, 'abcdef') + call feedkeys("gH\<kPoint>\<Esc>", 'tx') + call assert_equal(['???'], getline(1, '$')) + call feedkeys("gH\<kEnter>\<Esc>", 'tx') + call assert_equal(['!!!'], getline(1, '$')) + + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_signs.vim b/src/testdir/test_signs.vim index 0d76d7a..7f53d62 100644 --- a/src/testdir/test_signs.vim +++ b/src/testdir/test_signs.vim @@ -245,7 +245,7 @@ func Test_sign_completion() call assert_equal('"sign define jump list place undefine unplace', @:) call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx') - call assert_equal('"sign define Sign culhl= icon= linehl= numhl= text= texthl=', @:) + call assert_equal('"sign define Sign culhl= icon= linehl= numhl= priority= text= texthl=', @:) for hl in ['culhl', 'linehl', 'numhl', 'texthl'] call feedkeys(":sign define Sign "..hl.."=Spell\<C-A>\<C-B>\"\<CR>", 'tx') @@ -1231,6 +1231,25 @@ func Test_sign_priority() call sign_define("sign1", attr) call sign_define("sign2", attr) call sign_define("sign3", attr) + let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Search', 'priority': 60} + call sign_define("sign4", attr) + + " Test for :sign list + let a = execute('sign list') + call assert_equal("\nsign sign1 text==> linehl=Search texthl=Search\n" . + \ "sign sign2 text==> linehl=Search texthl=Search\n" . + \ "sign sign3 text==> linehl=Search texthl=Search\n" . + \ "sign sign4 text==> priority=60 linehl=Search texthl=Search", a) + + " Test for sign_getdefined() + let s = sign_getdefined() + call assert_equal([ + \ {'name': 'sign1', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'}, + \ {'name': 'sign2', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'}, + \ {'name': 'sign3', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'}, + \ {'name': 'sign4', 'priority': 60, 'texthl': 'Search', 'linehl': 'Search', + \ 'text': '=>'}], + \ s) " Place three signs with different priority in the same line call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D') @@ -1586,6 +1605,25 @@ func Test_sign_priority() \ " line=10 id=5 group=g1 name=sign1 priority=20\n", a) call sign_unplace('*') + + " Test for sign with default priority. + call sign_place(1, 'g1', 'sign4', 'Xsign', {'lnum' : 3}) + sign place 2 line=5 name=sign4 group=g1 file=Xsign + + let s = sign_getplaced('Xsign', {'group' : '*'}) + call assert_equal([ + \ {'id' : 1, 'name' : 'sign4', 'lnum' : 3, 'group' : 'g1', + \ 'priority' : 60}, + \ {'id' : 2, 'name' : 'sign4', 'lnum' : 5, 'group' : 'g1', + \ 'priority' : 60}], + \ s[0].signs) + + let a = execute('sign place group=g1') + call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . + \ " line=3 id=1 group=g1 name=sign4 priority=60\n" . + \ " line=5 id=2 group=g1 name=sign4 priority=60\n", a) + + call sign_unplace('*') call sign_undefine() enew | only endfunc diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim index 1ddcd83..692e191 100644 --- a/src/testdir/test_spell.vim +++ b/src/testdir/test_spell.vim @@ -5,6 +5,7 @@ source check.vim CheckFeature spell source screendump.vim +source view_util.vim func TearDown() set nospell @@ -300,6 +301,20 @@ func Test_compl_with_CTRL_X_CTRL_K_using_spell() set spell& spelllang& dictionary& ignorecase& endfunc +func Test_compl_with_CTRL_X_s() + new + set spell spelllang=en_us showmode + inoremap <buffer><F2> <Cmd>let g:msg = Screenline(&lines)<CR> + + call feedkeys("STheatre\<C-X>s\<F2>\<C-Y>\<Esc>", 'tx') + call assert_equal(['Theater'], getline(1, '$')) + call assert_match('(^S^N^P)', g:msg) + + bwipe! + set spell& spelllang& showmode& + unlet g:msg +endfunc + func Test_spellrepall() new set spell diff --git a/src/testdir/test_spellfile.vim b/src/testdir/test_spellfile.vim index d8d954b..8abb680 100644 --- a/src/testdir/test_spellfile.vim +++ b/src/testdir/test_spellfile.vim @@ -845,6 +845,22 @@ func Test_spell_add_word() %bw! endfunc +func Test_spell_add_long_word() + set spell spellfile=./Xspellfile.add spelllang=en + + let word = repeat('a', 9000) + let v:errmsg = '' + " Spell checking doesn't really work for such a long word, + " but this should not cause an E1510 error. + exe 'spellgood ' .. word + call assert_equal('', v:errmsg) + call assert_equal([word], readfile('./Xspellfile.add')) + + set spell& spellfile= spelllang& encoding=utf-8 + call delete('./Xspellfile.add') + call delete('./Xspellfile.add.spl') +endfunc + func Test_spellfile_verbose() call writefile(['1', 'one'], 'XtestVerbose.dic', 'D') call writefile([], 'XtestVerbose.aff', 'D') diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim index afdc104..b25cd60 100644 --- a/src/testdir/test_substitute.vim +++ b/src/testdir/test_substitute.vim @@ -806,7 +806,7 @@ func Test_replace_keeppatterns() a foobar -substitute foo asdf +substitute foo asdf foo one two . @@ -815,21 +815,26 @@ one two /^substitute s/foo/bar/ call assert_equal('foo', @/) - call assert_equal('substitute bar asdf', getline('.')) + call assert_equal('substitute bar asdf foo', getline('.')) /^substitute keeppatterns s/asdf/xyz/ call assert_equal('^substitute', @/) - call assert_equal('substitute bar xyz', getline('.')) + call assert_equal('substitute bar xyz foo', getline('.')) + + /^substitute + & + call assert_equal('^substitute', @/) + call assert_equal('substitute bar xyz bar', getline('.')) exe "normal /bar /e\<CR>" call assert_equal(15, col('.')) normal - keeppatterns /xyz call assert_equal('bar ', @/) - call assert_equal('substitute bar xyz', getline('.')) + call assert_equal('substitute bar xyz bar', getline('.')) exe "normal 0dn" - call assert_equal('xyz', getline('.')) + call assert_equal('xyz bar', getline('.')) close! endfunc diff --git a/src/testdir/test_tabpage.vim b/src/testdir/test_tabpage.vim index 3624790..1a40567 100644 --- a/src/testdir/test_tabpage.vim +++ b/src/testdir/test_tabpage.vim @@ -965,6 +965,64 @@ func Test_tabpage_alloc_failure() call assert_equal(1, tabpagenr('$')) endfunc +func Test_tabpage_tabclose() + " Default behaviour, move to the right. + call s:reconstruct_tabpage_for_test(6) + norm! 4gt + setl tcl= + tabclose + call assert_equal("n3", bufname()) + + " Move to the left. + call s:reconstruct_tabpage_for_test(6) + norm! 4gt + setl tcl=left + tabclose + call assert_equal("n1", bufname()) + + " Move to the last used tab page. + call s:reconstruct_tabpage_for_test(6) + norm! 5gt + norm! 2gt + setl tcl=uselast + tabclose + call assert_equal("n3", bufname()) + + " Same, but the last used tab page is invalid. Move to the right. + call s:reconstruct_tabpage_for_test(6) + norm! 5gt + norm! 3gt + setl tcl=uselast + tabclose 5 + tabclose! + call assert_equal("n2", bufname()) + + " Same, but the last used tab page is invalid. Move to the left. + call s:reconstruct_tabpage_for_test(6) + norm! 5gt + norm! 3gt + setl tcl=uselast,left + tabclose 5 + tabclose! + call assert_equal("n0", bufname()) + + " Move left when moving right is not possible. + call s:reconstruct_tabpage_for_test(6) + setl tcl= + norm! 6gt + tabclose + call assert_equal("n3", bufname()) + + " Move right when moving left is not possible. + call s:reconstruct_tabpage_for_test(6) + setl tcl=left + norm! 1gt + tabclose + call assert_equal("n0", bufname()) + + setl tcl& +endfunc + " this was giving ml_get errors func Test_tabpage_last_line() enew diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim index 432906e..c241937 100644 --- a/src/testdir/test_tagjump.vim +++ b/src/testdir/test_tagjump.vim @@ -958,8 +958,63 @@ func Test_tag_stack() call settagstack(1, {'items' : []}) call assert_fails('pop', 'E73:') + " References to wiped buffer are deleted. + for i in range(10, 20) + edit Xtest + exe "tag var" .. i + endfor + edit Xtest + + let t = gettagstack() + call assert_equal(11, t.length) + call assert_equal(12, t.curidx) + + bwipe! + + let t = gettagstack() + call assert_equal(0, t.length) + call assert_equal(1, t.curidx) + + " References to wiped buffer are deleted with multiple tabpages. + let w1 = win_getid() + call settagstack(1, {'items' : []}) + for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor + enew + + new + let w2 = win_getid() + call settagstack(1, {'items' : []}) + for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor + enew + + tabnew + let w3 = win_getid() + call settagstack(1, {'items' : []}) + for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor + enew + + new + let w4 = win_getid() + call settagstack(1, {'items' : []}) + for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor + enew + + for w in [w1, w2, w3, w4] + let t = gettagstack(w) + call assert_equal(11, t.length) + call assert_equal(12, t.curidx) + endfor + + bwipe! Xtest + + for w in [w1, w2, w3, w4] + let t = gettagstack(w) + call assert_equal(0, t.length) + call assert_equal(1, t.curidx) + endfor + + %bwipe! set tags& - %bwipe endfunc " Test for browsing multiple matching tags diff --git a/src/testdir/test_taglist.vim b/src/testdir/test_taglist.vim index 2dd2366..c5c7df2 100644 --- a/src/testdir/test_taglist.vim +++ b/src/testdir/test_taglist.vim @@ -100,9 +100,9 @@ func Test_tagfiles() help let tf = tagfiles() - " if 'helplang includes another language, then we may find - " 2 tagfiles (e.g.: for EN and RU) - " we may need to adjust this, if further translated help files are included + " If 'helplang' includes another language, then we may find 2 tagfiles + " (e.g.: for EN and RU). + " We may need to adjust this, if further translated help files are included. call assert_inrange(1, 2, len(tf)) call assert_equal(fnamemodify(expand('$VIMRUNTIME/doc/tags'), ':p:gs?\\?/?'), \ fnamemodify(tf[0], ':p:gs?\\?/?')) @@ -127,6 +127,47 @@ func Test_tagsfile_without_trailing_newline() set tags& endfunc +" Check that specifying a stop directory in 'tags' works properly. +func Test_tagfiles_stopdir() + let save_cwd = getcwd() + + call mkdir('Xtagsdir1/Xtagsdir2/Xtagsdir3', 'pR') + call writefile([], 'Xtagsdir1/Xtags', 'D') + + cd Xtagsdir1/ + let &tags = './Xtags;' .. fnamemodify('..', ':p') + call assert_equal(1, len(tagfiles())) + + cd Xtagsdir2/ + let &tags = './Xtags;' .. fnamemodify('..', ':p') + call assert_equal(1, len(tagfiles())) + + cd Xtagsdir3/ + let &tags = './Xtags;' .. fnamemodify('..', ':p') + call assert_equal(0, len(tagfiles())) + + let &tags = './Xtags;../' + call assert_equal(0, len(tagfiles())) + + cd .. + call assert_equal(1, len(tagfiles())) + + cd .. + call assert_equal(1, len(tagfiles())) + + let &tags = './Xtags;..' + call assert_equal(1, len(tagfiles())) + + cd Xtagsdir2/ + call assert_equal(1, len(tagfiles())) + + cd Xtagsdir3/ + call assert_equal(0, len(tagfiles())) + + set tags& + call chdir(save_cwd) +endfunc + " Test for ignoring comments in a tags file func Test_tagfile_ignore_comments() call writefile([ diff --git a/src/testdir/test_termcodes.vim b/src/testdir/test_termcodes.vim index 7e450d9..507753c 100644 --- a/src/testdir/test_termcodes.vim +++ b/src/testdir/test_termcodes.vim @@ -2256,6 +2256,17 @@ func Test_modifyOtherKeys_mapped() iunmap ' iunmap <C-W><C-A> + + " clean buffer + %d _ + imap B b + imap BBB blimp + let input = repeat(GetEscCodeCSI27('B', 2), 3) + call feedkeys("a" .. input .. "\<Esc>", 'Lx!') + call assert_equal('blimp', getline(1)) + " cleanup + iunmap BBB + iunmap B set timeoutlen& endfunc diff --git a/src/testdir/test_termdebug.vim b/src/testdir/test_termdebug.vim index a9762df..b5c12ae 100644 --- a/src/testdir/test_termdebug.vim +++ b/src/testdir/test_termdebug.vim @@ -63,6 +63,7 @@ func Test_termdebug_basic() edit XTD_basic.c Termdebug ./XTD_basic + call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))}) call WaitForAssert({-> assert_equal(3, winnr('$'))}) let gdb_buf = winbufnr(1) wincmd b @@ -123,13 +124,13 @@ func Test_termdebug_basic() " 60 is approx spaceBuffer * 3 if winwidth(0) <= 78 + 60 Var - call assert_equal(winnr(), winnr('$')) - call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]]) + call assert_equal(winnr('$'), winnr()) + call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]], winlayout()) let cn += 1 bw! Asm - call assert_equal(winnr(), winnr('$')) - call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]]) + call assert_equal(winnr('$'), winnr()) + call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]], winlayout()) let cn += 1 bw! endif @@ -138,16 +139,16 @@ func Test_termdebug_basic() let winw = winwidth(0) Var if winwidth(0) < winw - call assert_equal(winnr(), winnr('$') - 1) - call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]]) + call assert_equal(winnr('$') - 1, winnr()) + call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]], winlayout()) let cn += 1 bw! endif let winw = winwidth(0) Asm if winwidth(0) < winw - call assert_equal(winnr(), winnr('$') - 1) - call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]]) + call assert_equal(winnr('$') - 1, winnr()) + call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]], winlayout()) let cn += 1 bw! endif @@ -160,6 +161,19 @@ func Test_termdebug_basic() call WaitForAssert({-> assert_equal(1, winnr('$'))}) call assert_equal([], sign_getplaced('', #{group: 'TermDebug'})[0].signs) + for use_prompt in [v:true, v:false] + let g:termdebug_config = {} + let g:termdebug_config['use_prompt'] = use_prompt + TermdebugCommand ./XTD_basic arg args + call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))}) + call WaitForAssert({-> assert_equal(3, winnr('$'))}) + wincmd t + quit! + redraw! + call WaitForAssert({-> assert_equal(1, winnr('$'))}) + unlet g:termdebug_config + endfor + call s:cleanup_files(bin_name) %bw! endfunc @@ -174,6 +188,7 @@ func Test_termdebug_tbreak() execute 'edit ' .. src_name execute 'Termdebug ./' .. bin_name + call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))}) call WaitForAssert({-> assert_equal(3, winnr('$'))}) let gdb_buf = winbufnr(1) wincmd b @@ -234,6 +249,7 @@ func Test_termdebug_mapping() call assert_true(maparg('-', 'n', 0, 1)->empty()) call assert_true(maparg('+', 'n', 0, 1)->empty()) Termdebug + call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))}) call WaitForAssert({-> assert_equal(3, winnr('$'))}) wincmd b call assert_false(maparg('K', 'n', 0, 1)->empty()) @@ -256,6 +272,7 @@ func Test_termdebug_mapping() nnoremap - :echom "-"<cr> nnoremap + :echom "+"<cr> Termdebug + call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))}) call WaitForAssert({-> assert_equal(3, winnr('$'))}) wincmd b call assert_false(maparg('K', 'n', 0, 1)->empty()) @@ -278,76 +295,184 @@ func Test_termdebug_mapping() call assert_equal(':echom "K"<cr>', maparg('K', 'n', 0, 1).rhs) %bw! + + " -- Test that local-buffer mappings are restored in the correct buffers -- + " local mappings for foo + file foo nnoremap <buffer> K :echom "bK"<cr> nnoremap <buffer> - :echom "b-"<cr> nnoremap <buffer> + :echom "b+"<cr> + + " no mappings for 'bar' + enew + file bar + + " Start termdebug from foo + buffer foo Termdebug + call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))}) call WaitForAssert({-> assert_equal(3, winnr('$'))}) wincmd b call assert_true(maparg('K', 'n', 0, 1).buffer) call assert_true(maparg('-', 'n', 0, 1).buffer) call assert_true(maparg('+', 'n', 0, 1).buffer) call assert_equal(maparg('K', 'n', 0, 1).rhs, ':echom "bK"<cr>') + + Source + buffer bar + call assert_false(maparg('K', 'n', 0, 1)->empty()) + call assert_false(maparg('-', 'n', 0, 1)->empty()) + call assert_false(maparg('+', 'n', 0, 1)->empty()) + call assert_true(maparg('K', 'n', 0, 1).buffer->empty()) + call assert_true(maparg('-', 'n', 0, 1).buffer->empty()) + call assert_true(maparg('+', 'n', 0, 1).buffer->empty()) wincmd t quit! redraw! call WaitForAssert({-> assert_equal(1, winnr('$'))}) + + " Termdebug session ended. Buffer 'bar' shall have no mappings + call assert_true(bufname() ==# 'bar') + call assert_false(maparg('K', 'n', 0, 1)->empty()) + call assert_false(maparg('-', 'n', 0, 1)->empty()) + call assert_false(maparg('+', 'n', 0, 1)->empty()) + call assert_true(maparg('K', 'n', 0, 1).buffer->empty()) + call assert_true(maparg('-', 'n', 0, 1).buffer->empty()) + call assert_true(maparg('+', 'n', 0, 1).buffer->empty()) + + " Buffer 'foo' shall have the same mapping as before running the termdebug + " session + buffer foo + call assert_true(bufname() ==# 'foo') call assert_true(maparg('K', 'n', 0, 1).buffer) call assert_true(maparg('-', 'n', 0, 1).buffer) call assert_true(maparg('+', 'n', 0, 1).buffer) call assert_equal(':echom "bK"<cr>', maparg('K', 'n', 0, 1).rhs) + nunmap K + nunmap + + nunmap - %bw! endfunc -func Test_termdebug_bufnames() - " Test if user has filename/folders named gdb, Termdebug-gdb-console, - " etc. in the current directory +function Test_termdebug_save_restore_variables() + " saved mousemodel + let &mousemodel='' + + " saved keys + nnoremap K :echo "hello world!"<cr> + let expected_map_K = maparg('K', 'n', 0 , 1) + nnoremap + :echo "hello plus!"<cr> + let expected_map_plus = maparg('+', 'n', 0 , 1) + let expected_map_minus = {} + + " saved &columns + let expected_columns = &columns + + " We want termdebug to overwrite 'K' map but not '+' map. let g:termdebug_config = {} - let g:termdebug_config['use_prompt'] = 1 - let filename = 'gdb' - let replacement_filename = 'Termdebug-gdb-console' + let g:termdebug_config['map_K'] = v:true - call writefile(['This', 'is', 'a', 'test'], filename, 'D') - " Throw away the file once the test has done. Termdebug - " Once termdebug has completed the startup you should have 3 windows on screen + call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))}) call WaitForAssert({-> assert_equal(3, winnr('$'))}) - " A file named filename already exists in the working directory, - " hence you must call the newly created buffer differently - call WaitForAssert({-> assert_false(bufexists(filename))}) - call WaitForAssert({-> assert_true(bufexists(replacement_filename))}) + call WaitForAssert({-> assert_match(&mousemodel, 'popup_setpos')}) + wincmd t quit! call WaitForAssert({-> assert_equal(1, winnr('$'))}) - " Check if error message is in :message - let g:termdebug_config['disasm_window'] = 1 - let filename = 'Termdebug-asm-listing' - call writefile(['This', 'is', 'a', 'test'], filename, 'D') - " Check only the head of the error message - let error_message = "You have a file/folder named '" .. filename .. "'" - Termdebug - " Once termdebug has completed the startup you should have 4 windows on screen - call WaitForAssert({-> assert_equal(4, winnr('$'))}) - call WaitForAssert({-> assert_notequal(-1, stridx(execute('messages'), error_message))}) - quit! - wincmd b - wincmd q - call WaitForAssert({-> assert_equal(1, winnr('$'))}) + call assert_true(empty(&mousemodel)) + call assert_true(empty(expected_map_minus)) + call assert_equal(expected_map_K.rhs, maparg('K', 'n', 0, 1).rhs) + call assert_equal(expected_map_plus.rhs, maparg('+', 'n', 0, 1).rhs) + + call assert_equal(expected_columns, &columns) + + nunmap K + nunmap + unlet g:termdebug_config -endfunc +endfunction -function Test_termdebug_save_restore_variables() - let &mousemodel='' +function Test_termdebug_sanity_check() + " Test if user has filename/folders with wrong names + let g:termdebug_config = {} + let s:dict = {'disasm_window': 'Termdebug-asm-listing', 'use_prompt': 'gdb', 'variables_window': 'Termdebug-variables-listing'} + + for key in keys(s:dict) + let s:filename = s:dict[key] + let g:termdebug_config[key] = v:true + let s:error_message = "You have a file/folder named '" .. s:filename .. "'" + + " Write dummy file with bad name + call writefile(['This', 'is', 'a', 'test'], s:filename, 'D') + Termdebug + call WaitForAssert({-> assert_true(execute('messages') =~ s:error_message)}) + call WaitForAssert({-> assert_equal(1, winnr('$'))}) + + call delete(s:filename) + call remove(g:termdebug_config, key) + endfor + + unlet g:termdebug_config +endfunction + +function Test_termdebug_double_termdebug_instances() + let s:error_message = 'Terminal debugger already running, cannot run two' Termdebug + call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))}) call WaitForAssert({-> assert_equal(3, winnr('$'))}) - call WaitForAssert({-> assert_match(&mousemodel, 'popup_setpos')}) + Termdebug + call WaitForAssert({-> assert_true(execute('messages') =~ s:error_message)}) wincmd t quit! call WaitForAssert({-> assert_equal(1, winnr('$'))}) - call WaitForAssert({-> assert_true(empty(&mousemodel))}) + :%bw! endfunction +function Test_termdebug_config_types() + " TODO Remove the deprecated features after 1 Jan 2025. + let g:termdebug_config = {} + let s:error_message = 'Deprecation Warning:' + call assert_true(maparg('K', 'n', 0, 1)->empty()) + + for key in ['disasm_window', 'variables_window', 'map_K'] + for val in [0, 1, v:true, v:false] + let g:termdebug_config[key] = val + Termdebug + + " Type check: warning is displayed + if typename(val) == 'number' + call WaitForAssert({-> assert_true(execute('messages') =~ s:error_message)}) + endif + + " Test on g:termdebug_config keys + if val && key != 'map_K' + call WaitForAssert({-> assert_equal(4, winnr('$'))}) + call remove(g:termdebug_config, key) + else + call WaitForAssert({-> assert_equal(3, winnr('$'))}) + endif + + " Test on mapping + if key == 'map_K' + if val + call assert_equal(':Evaluate<CR>', maparg('K', 'n', 0, 1).rhs) + else + call assert_true(maparg('K', 'n', 0, 1)->empty()) + endif + endif + + " Shutoff termdebug + wincmd t + quit! + call WaitForAssert({-> assert_equal(1, winnr('$'))}) + :%bw! + + endfor + endfor + + unlet g:termdebug_config +endfunction " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_textobjects.vim b/src/testdir/test_textobjects.vim index d5e772d..2622b06 100644 --- a/src/testdir/test_textobjects.vim +++ b/src/testdir/test_textobjects.vim @@ -201,6 +201,18 @@ func Test_string_html_objects() normal! 2k0vaty call assert_equal("<div><div\nattr=\"attr\"\n></div></div>", @", e) + " tag, that includes a > in some attribute + let t = "<div attr=\"attr >> foo >> bar \">Hello</div>" + $put =t + normal! fHyit + call assert_equal("Hello", @", e) + + " tag, that includes a > in some attribute + let t = "<div attr='attr >> foo >> bar '>Hello 123</div>" + $put =t + normal! fHyit + call assert_equal("Hello 123", @", e) + set quoteescape& " this was going beyond the end of the line diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index 2bf2834..57277f7 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -2901,6 +2901,10 @@ func Test_prop_inserts_text_before_double_width_wrap() call writefile(lines, 'XscriptPropsBeforeDoubleWidthWrap', 'D') let buf = RunVimInTerminal('-S XscriptPropsBeforeDoubleWidthWrap', #{rows: 3, cols: 50}) call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_double_width_wrap_1', {}) + call term_sendkeys(buf, 'g0') + call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_double_width_wrap_2', {}) + call term_sendkeys(buf, ":set showbreak=+++\<CR>") + call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_double_width_wrap_3', {}) call StopVimInTerminal(buf) endfunc diff --git a/src/testdir/test_tohtml.vim b/src/testdir/test_tohtml.vim new file mode 100644 index 0000000..a1c8572 --- /dev/null +++ b/src/testdir/test_tohtml.vim @@ -0,0 +1,72 @@ +" Tests for Vim :TOhtml + +source check.vim + +func s:setup_basic(src_name) + let lines =<< trim END + #include <stdio.h> + #include <stdlib.h> + + int isprime(int n) + { + if (n <= 1) + return 0; + + for (int i = 2; i <= n / 2; i++) + if (n % i == 0) + return 0; + + return 1; + } + + int main(int argc, char *argv[]) + { + int n = 7; + + printf("%d is %s prime\n", n, isprime(n) ? "a" : "not a"); + + return 0; + } + END + call writefile(lines, a:src_name) + exe 'edit ' . a:src_name + TOhtml + write +endfunc + +func s:cleanup_basic(src_name) + call delete(a:src_name) + call delete(a:src_name . ".html") +endfunc + +source $VIMRUNTIME/plugin/tohtml.vim + +func Test_tohtml_basic() + let src_name = "Test_tohtml_basic.c" + call s:setup_basic(src_name) + let expected = readfile("samples/" . src_name . ".html") + let actual = readfile(src_name . ".html") + call assert_equal(expected[0:3], actual[0:3]) + " Ignore the title + call assert_equal(expected[5:11], actual[5:11]) + " Ignore pre and body css + call assert_equal(expected[14:], actual[14:]) + call s:cleanup_basic(src_name) +endfunc + +func Test_tohtml_basic_no_css() + let g:html_use_css = 0 + let src_name = "Test_tohtml_basic_no_css.c" + call s:setup_basic(src_name) + let expected = readfile("samples/" . src_name . ".html") + let actual = readfile(src_name . ".html") + call assert_equal(expected[0:3], actual[0:3]) + " Ignore the title + call assert_equal(expected[5:10], actual[5:10]) + " Ignore body's inline css + call assert_equal(expected[12:], actual[12:]) + call s:cleanup_basic(src_name) + unlet g:html_use_css +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_usercommands.vim b/src/testdir/test_usercommands.vim index e161ee6..fe08b95 100644 --- a/src/testdir/test_usercommands.vim +++ b/src/testdir/test_usercommands.vim @@ -133,6 +133,10 @@ function Test_cmdmods() \ 'silent verbose aboveleft belowright botright tab topleft vertical', \ g:mods) + kee keep keepm keepma keepmar keepmarks keepa keepalt keepj keepjumps + \ keepp keeppatterns MyCmd + call assert_equal('keepalt keepjumps keepmarks keeppatterns', g:mods) + let g:mods = '' command! -nargs=* MyQCmd let g:mods .= '<q-mods> ' diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 6b1a50d..7ed9123 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -497,6 +497,56 @@ def Test_call_call() v9.CheckSourceDefAndScriptFailure(['call("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) enddef +def Test_call_imports() + # Use call with an imported function + var lines =<< trim END + vim9script + + export const foo = 'foo' + + export def Imported() + enddef + + var count: number + export def ImportedListArg(l: list<number>) + count += 1 + l[0] += count + enddef + END + writefile(lines, 'Test_call_imports_importme', 'D') + lines =<< trim END + vim9script + import './Test_call_imports_importme' as i_imp + + var l = [12] + call('i_imp.ImportedListArg', [l]) + assert_equal(13, l[0]) + const ImportedListArg = i_imp.ImportedListArg + call('ImportedListArg', [l]) + assert_equal(15, l[0]) + const Imported = i_imp.Imported + call("Imported", []) + + assert_equal('foo', i_imp.foo) + const foo = i_imp.foo + assert_equal('foo', foo) + END + v9.CheckSourceScriptSuccess(lines) + + # A few error cases + lines =<< trim END + vim9script + import './Test_call_imports_importme' as i_imp + const Imported = i_imp.Imported + const foo = i_imp.foo + + assert_fails('call("i_imp.foo", [])', 'E117:') # foo is not a function + assert_fails('call("foo", [])', 'E117:') # foo is not a function + assert_fails('call("i_xxx.foo", [])', 'E117:') # i_xxx not imported file + END + v9.CheckSourceScriptSuccess(lines) +enddef + def Test_ch_canread() if !has('channel') CheckFeature channel @@ -1969,6 +2019,17 @@ def Test_getreginfo() getreginfo('').regcontents->assert_equal(['D1E2F3']) enddef +def Test_getregionpos() + var lines =<< trim END + cursor(1, 1) + var pos = getregionpos(getpos('.'), getpos('$')) + for p in pos + assert_equal(bufnr('%'), p[0][0]) + endfor + END + v9.CheckSourceDefSuccess(lines) +enddef + def Test_getregtype() var lines = ['aaa', 'bbb', 'ccc'] setreg('a', lines) @@ -3152,6 +3213,11 @@ def Test_popup_settext() v9.CheckSourceDefAndScriptFailure(['popup_settext(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1222: String or List required for argument 2']) enddef +def Test_popup_setbuf() + v9.CheckSourceDefAndScriptFailure(['popup_setbuf([], "abc")'], ['E1013: Argument 1: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_setbuf(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2']) +enddef + def Test_popup_show() v9.CheckSourceDefAndScriptFailure(['popup_show("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) v9.CheckSourceDefAndScriptFailure(['popup_show(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index e92fcc5..8791a52 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -661,6 +661,44 @@ def Test_object_not_set() Func() END v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1) + + # Reference a object variable through a null class object which is stored in a + # variable of type "any". + lines =<< trim END + vim9script + + def Z() + var o: any = null_object + o.v = 4 + enddef + Z() + END + v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2) + + # Do "echom" of a null object variable. + lines =<< trim END + vim9script + + def X() + var x = null_object + echom x + enddef + X() + END + v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 2) + + # Use a null object variable that vim wants to force to number. + lines =<< trim END + vim9script + + def X() + var o = null_object + var l = [ 1, o] + sort(l, 'N') + enddef + X() + END + v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 3) enddef " Null object assignment and comparison @@ -2246,6 +2284,47 @@ def Test_class_object_to_string() assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos)) END v9.CheckSourceSuccess(lines) + + # check string() with object nesting + lines =<< trim END + vim9script + class C + var nest1: C + var nest2: C + def Init(n1: C, n2: C) + this.nest1 = n1 + this.nest2 = n2 + enddef + endclass + + var o1 = C.new() + var o2 = C.new() + o1.Init(o1, o2) + o2.Init(o2, o1) + + # The following previously put's vim into an infinite loop. + + var expect = "object of C {nest1: object of C {...}, nest2: object of C {nest1: object of C {...}, nest2: object of C {...}}}" + assert_equal(expect, string(o1)) + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + + class B + endclass + + class C + var b: B + var c: C + endclass + + var o1 = C.new(B.new(), C.new(B.new())) + var expect = "object of C {b: object of B {}, c: object of C {b: object of B {}, c: object of [unknown]}}" + assert_equal(expect, string(o1)) + END + v9.CheckSourceSuccess(lines) enddef def Test_interface_basics() @@ -3173,6 +3252,141 @@ def Test_using_base_class() v9.CheckSourceSuccess(lines) enddef +def Test_super_dispatch() + # See #15448 and #15463 + var lines =<< trim END + vim9script + + class A + def String(): string + return 'A' + enddef + endclass + + class B extends A + def String(): string + return super.String() + enddef + endclass + + class C extends B + endclass + + assert_equal('A', C.new().String()) + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + + class A + def F(): string + return 'AA' + enddef + endclass + + class B extends A + def F(): string + return 'BB' + enddef + def S(): string + return super.F() + enddef + def S0(): string + return this.S() + enddef + endclass + + class C extends B + def F(): string + return 'CC' + enddef + def ToB(): string + return super.F() + enddef + endclass + + assert_equal('AA', B.new().S()) + assert_equal('AA', C.new().S()) + assert_equal('AA', B.new().S0()) + assert_equal('AA', C.new().S0()) + + assert_equal('BB', C.new().ToB()) + + assert_equal('CC', C.new().F()) + assert_equal('BB', B.new().F()) + assert_equal('AA', A.new().F()) + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + + var call_chain: list<string> + + abstract class A + abstract def _G(): string + + def F(): string + call_chain->add('A.F()') + return this._G() + enddef + def _H(): string + call_chain->add('A._H()') + return this.F() + enddef + endclass + + class B extends A + def _G(): string + call_chain->add('B.G()') + return 'BBB' + enddef + def SF(): string + call_chain->add('B.SF()') + return super._H() + enddef + endclass + + class C extends B + endclass + + class D extends C + def SF(): string + call_chain->add('D.SF()') + return super.SF() + enddef + endclass + + class E extends D + def SF(): string + call_chain->add('E.SF()') + return super.SF() + enddef + endclass + + class F extends E + def _G(): string + call_chain->add('F._G()') + return 'FFF' + enddef + endclass + + # E.new() -> A.F() -> B._G() + call_chain = [] + var o1 = E.new() + assert_equal('BBB', o1.F()) + assert_equal(['A.F()', 'B.G()'], call_chain) + + # F.new() -> E.SF() -> D.SF() -> B.SF() -> A._H() -> A.F() -> F._G() + call_chain = [] + var o2 = F.new() + assert_equal('FFF', o2.SF()) + assert_equal(['E.SF()', 'D.SF()', 'B.SF()', 'A._H()', 'A.F()', 'F._G()'], call_chain) + END + v9.CheckSourceSuccess(lines) +enddef + def Test_class_import() var lines =<< trim END vim9script @@ -7162,6 +7376,47 @@ def Test_null_object_method_call() T() END v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2) + + # Calling an object method defined in a class that is extended. This differs + # from the previous by invoking ISN_METHODCALL instead of ISN_DCALL. + lines =<< trim END + vim9script + + class C0 + def F() + enddef + endclass + + class C extends C0 + endclass + + def X() + var o: C0 = null_object + o.F() + enddef + X() + END + v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2) + + # Getting a function ref an object method. + lines =<< trim END + vim9script + + class C0 + def F() + enddef + endclass + + class C extends C0 + endclass + + def X() + var o: C0 = null_object + var XXX = o.F + enddef + X() + END + v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2) enddef " Test for using a dict as an object member @@ -10425,6 +10680,20 @@ func Test_object_string() call v9.CheckSourceSuccess(lines) endfunc +" Test for using the string() builtin method with an object's method +def Test_method_string() + var lines =<< trim END + vim9script + class A + def F() + enddef + endclass + assert_match('function(''<SNR>\d\+_A\.F'')', string(A.new().F)) + END + v9.CheckScriptSuccess(lines) +enddef + + " Test for using a class in the class definition def Test_Ref_Class_Within_Same_Class() var lines =<< trim END @@ -10486,6 +10755,156 @@ def Test_Ref_Class_Within_Same_Class() v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3) enddef +" Test for comparing a class referencing itself +def Test_Object_Compare_With_Recursive_Class_Ref() + var lines =<< trim END + vim9script + + class C + public var nest: C + endclass + + var o1 = C.new() + o1.nest = o1 + + var result = o1 == o1 + assert_equal(true, result) + END + v9.CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + + class C + public var nest: C + endclass + var o1 = C.new() + var o2 = C.new(C.new()) + + var result = o1 == o2 + assert_equal(false, result) + END + v9.CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + class C + var nest1: C + var nest2: C + def Init(n1: C, n2: C) + this.nest1 = n1 + this.nest2 = n2 + enddef + endclass + + var o1 = C.new() + var o2 = C.new() + o1.Init(o1, o2) + o2.Init(o2, o1) + + var result = o1 == o2 + assert_equal(true, result) + END + v9.CheckScriptSuccess(lines) +enddef + +" Test for comparing a class with nesting objects +def Test_Object_Compare_With_Nesting_Objects() + # On a compare, after vim equal recurses 1000 times, not finding an unequal, + # return the compare is equal. + # Test that limit + + var lines =<< trim END + vim9script + class C + public var n: number + public var nest: C + + # Create a "C" that chains/nests to indicated depth. + # return {head: firstC, tail: lastC} + static def CreateNested(depth: number): dict<C> + var first = C.new(1, null_object) + var last = first + for i in range(2, depth) + last.nest = C.new(i, null_object) + last = last.nest + endfor + return {head: first, tail: last} + enddef + + # Return pointer to nth item in chain. + def GetLink(depth: number): C + var count = 1 + var p: C = this + while count < depth + p = p.nest + if p == null + throw "too deep" + endif + count += 1 + endwhile + return p + enddef + + # Return the length of the chain + def len(): number + var count = 1 + var p: C = this + while p.nest != null + p = p.nest + count += 1 + endwhile + return count + enddef + endclass + + var chain = C.CreateNested(3) + var s = "object of C {n: 1, nest: object of C {n: 2, nest: object of C {n: 3, nest: object of [unknown]}}}" + assert_equal(s, string(chain.head)) + assert_equal(3, chain.head->len()) + + var chain1 = C.CreateNested(100) + var chain2 = C.CreateNested(100) + assert_true(chain1.head == chain2.head) + + # modify the tail of chain2, compare not equal + chain2.tail.n = 123456 + assert_true(chain1.head != chain2.head) + + # a tail of a different length compares not equal + chain2 = C.CreateNested(101) + assert_true(chain1.head != chain2.head) + + chain1 = C.CreateNested(1000) + chain2 = C.CreateNested(1000) + assert_true(chain1.head == chain2.head) + + # modify the tail of chain2, compare not equal + chain2.tail.n = 123456 + assert_true(chain1.head != chain2.head) + + # try a chain longer that the limit + chain1 = C.CreateNested(1001) + chain2 = C.CreateNested(1001) + assert_true(chain1.head == chain2.head) + + # modify the tail, but still equal + chain2.tail.n = 123456 + assert_true(chain1.head == chain2.head) + + # remove 2 items from front, shorten the chain by two. + chain1.head = chain1.head.GetLink(3) + chain2.head = chain2.head.GetLink(3) + assert_equal(3, chain1.head.n) + assert_equal(3, chain2.head.n) + assert_equal(999, chain1.head->len()) + assert_equal(999, chain2.head->len()) + # Now less than the limit, compare not equal + assert_true(chain1.head != chain2.head) + END + v9.CheckScriptSuccess(lines) +enddef + " Test for using a compound operator from a lambda function in an object method def Test_compound_op_in_objmethod_lambda() # Test using the "+=" operator @@ -10744,4 +11163,54 @@ def Test_class_object_index() v9.CheckScriptFailure(lines, 'E689: Index not allowed after a object: a[10] = 1', 5) enddef +def Test_class_member_init_typecheck() + # Ensure the class member is assigned its declared type. + var lines =<< trim END + vim9script + class S + static var l: list<string> = [] + endclass + S.l->add(123) + END + v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 5) + + # Ensure the initializer value and the declared type match. + lines =<< trim END + vim9script + class S + var l: list<string> = [1, 2, 3] + endclass + var o = S.new() + END + v9.CheckScriptFailure(lines, 'E1382: Variable "l": type mismatch, expected list<string> but got list<number>') + + # Ensure the class member is assigned its declared type. + lines =<< trim END + vim9script + class S + var l: list<string> = [] + endclass + var o = S.new() + o.l->add(123) + END + v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 6) +enddef + +def Test_class_cast() + var lines =<< trim END + vim9script + class A + endclass + class B extends A + var mylen: number + endclass + def F(o: A): number + return (<B>o).mylen + enddef + + defcompile F + END + v9.CheckScriptSuccess(lines) +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim index a9e10e7..51ae7e6 100644 --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -2036,6 +2036,14 @@ def Test_no_space_after_command() v9.CheckDefExecAndScriptFailure(lines, 'E486:', 1) enddef +def Test_lambda_crash() + # This used to crash Vim + var lines =<< trim END + vim9 () => super => { + END + v9.CheckScriptFailureList(lines, ["E1356:", "E1405:"]) +enddef + " Test for the 'previewpopup' option def Test_previewpopup() set previewpopup=height:10,width:60 @@ -2044,6 +2052,7 @@ def Test_previewpopup() assert_notequal(id, 0) assert_match('Xppfile', popup_getoptions(id).title) popup_clear() + bw Xppfile set previewpopup& enddef diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index c74cce4..7746b23 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -1761,6 +1761,74 @@ def Test_disassemble_typecast() instr) enddef +def Test_disassemble_object_cast() + # Downcasting. + var lines =<< trim END + vim9script + class A + endclass + class B extends A + var mylen: number + endclass + def F(o: A): number + return (<B>o).mylen + enddef + + g:instr = execute('disassemble F') + END + v9.CheckScriptSuccess(lines) + assert_match('\<SNR>\d*_F\_s*' .. + 'return (<B>o).mylen\_s*' .. + '0 LOAD arg\[-1\]\_s*' .. + '1 CHECKTYPE object<B> stack\[-1\]\_s*' .. + '2 OBJ_MEMBER 0\_s*' .. + '3 RETURN\_s*', + g:instr) + + # Upcasting. + lines =<< trim END + vim9script + class A + var mylen: number + endclass + class B extends A + endclass + def F(o: B): number + return (<A>o).mylen + enddef + + g:instr = execute('disassemble F') + END + v9.CheckScriptSuccess(lines) + assert_match('\<SNR>\d*_F\_s*' .. + 'return (<A>o).mylen\_s*' .. + '0 LOAD arg\[-1\]\_s*' .. + '1 OBJ_MEMBER 0\_s*' .. + '2 RETURN\_s*', + g:instr) + + # Casting, type is not statically known. + lines =<< trim END + vim9script + class A + endclass + class B extends A + endclass + def F(o: any): any + return <A>o + enddef + + g:instr = execute('disassemble F') + END + v9.CheckScriptSuccess(lines) + assert_match('\<SNR>\d*_F\_s*' .. + 'return <A>o\_s*' .. + '0 LOAD arg\[-1\]\_s*' .. + '1 CHECKTYPE object<A> stack\[-1\]\_s*' .. + '2 RETURN\_s*', + g:instr) +enddef + def s:Computing() var nr = 3 var nrres = nr + 7 @@ -3496,4 +3564,26 @@ def Test_disassemble_compound_op_in_closure() unlet g:instr enddef +def Test_disassemble_member_initializer() + var lines =<< trim END + vim9script + class A + var l: list<string> = [] + var d: dict<string> = {} + endclass + g:instr = execute('disassemble A.new') + END + v9.CheckScriptSuccess(lines) + # Ensure SETTYPE is emitted and that matches the declared type. + assert_match('new\_s*' .. + '0 NEW A size \d\+\_s*' .. + '1 NEWLIST size 0\_s*' .. + '2 SETTYPE list<string>\_s*' .. + '3 STORE_THIS 0\_s*' .. + '4 NEWDICT size 0\_s*' .. + '5 SETTYPE dict<string>\_s*' .. + '6 STORE_THIS 1', g:instr) + unlet g:instr +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index d07bbfb..030ff83 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -164,6 +164,16 @@ def Test_wrong_function_name() END v9.CheckScriptFailure(lines, 'E1182:') delfunc g:Define + + lines =<< trim END + vim9script + var F1_ref: func + def Start() + F1_ref() + enddef + Start() + END + v9.CheckScriptFailure(lines, 'E117:') enddef " Check that in a legacy script a :def accesses the correct script variables. diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index 0b17150..bcb590d 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -4007,7 +4007,7 @@ def Test_restoring_cpo() edit XanotherScript so % assert_equal('aABceFsMny>', &cpo) - assert_equal('aABceFs', g:cpoval) + assert_equal('aABceFsz', g:cpoval) :1del setline(1, 'let g:cpoval = &cpo') w @@ -4048,10 +4048,10 @@ def Test_restoring_cpo() exe "silent !" .. cmd assert_equal([ - 'before: aABceFs', - 'after: aABceFsM', - 'later: aABceFsM', - 'vim9: aABceFs'], readfile('Xrporesult')) + 'before: aABceFsz', + 'after: aABceFszM', + 'later: aABceFszM', + 'vim9: aABceFsz'], readfile('Xrporesult')) $HOME = save_HOME delete('Xrporesult') @@ -5085,15 +5085,19 @@ def Test_null_values() var nullValues = [ [null, 1, 'null', 7, 'special'], [null_blob, 1, '0z', 10, 'blob'], - [null_channel, 1, 'channel fail', 9, 'channel'], [null_dict, 1, '{}', 4, 'dict<any>'], [null_function, 1, "function('')", 2, 'func(...): unknown'], - [null_job, 1, 'no process', 8, 'job'], [null_list, 1, '[]', 3, 'list<any>'], [null_object, 1, 'object of [unknown]', 13, 'object<Unknown>'], [null_partial, 1, "function('')", 2, 'func(...): unknown'], [null_string, 1, "''", 1, 'string'] ] + if has('channel') + nullValues->add([null_channel, 1, 'channel fail', 9, 'channel']) + endif + if has('job') + nullValues->add([null_job, 1, 'no process', 8, 'job']) + endif for [Val, emptyExp, stringExp, typeExp, typenameExp] in nullValues assert_equal(emptyExp, empty(Val)) diff --git a/src/testdir/test_vimscript.vim b/src/testdir/test_vimscript.vim index 8976779..21f894e 100644 --- a/src/testdir/test_vimscript.vim +++ b/src/testdir/test_vimscript.vim @@ -7536,6 +7536,31 @@ func Test_deeply_nested_source() call system(cmd) endfunc +func Test_exception_silent() + XpathINIT + let lines =<< trim END + func Throw() + Xpath 'a' + throw "Uncaught" + " This line is not executed. + Xpath 'b' + endfunc + " The exception is suppressed due to the presence of silent!. + silent! call Throw() + try + call DoesNotExist() + catch /E117:/ + Xpath 'c' + endtry + Xpath 'd' + END + let verify =<< trim END + call assert_equal('acd', g:Xpath) + END + + call RunInNewVim(lines, verify) +endfunc + "------------------------------------------------------------------------------- " Modelines {{{1 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_winfixbuf.vim b/src/testdir/test_winfixbuf.vim index f800338..3cec4ed 100644 --- a/src/testdir/test_winfixbuf.vim +++ b/src/testdir/test_winfixbuf.vim @@ -2934,6 +2934,7 @@ func Test_tfirst() \ "Xtags", 'D') call writefile(["one", "two", "three"], "Xfile", 'D') call writefile(["one"], "Xother", 'D') + tag one edit Xother set winfixbuf diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim index a91a1fc..99e4998 100644 --- a/src/testdir/test_xxd.vim +++ b/src/testdir/test_xxd.vim @@ -73,21 +73,21 @@ func Test_xxd() exe '0r! ' . s:xxd_cmd . ' -l 120 -ps -c20 ' . man_copy $d let expected = [ - \ '2e54482058584420312022417567757374203139', - \ '39362220224d616e75616c207061676520666f72', - \ '20787864220a2e5c220a2e5c222032317374204d', - \ '617920313939360a2e5c22204d616e2070616765', - \ '20617574686f723a0a2e5c2220202020546f6e79', - \ '204e7567656e74203c746f6e79407363746e7567'] + \ '2e544820585844203120224d6179203230323422', + \ '20224d616e75616c207061676520666f72207878', + \ '64220a2e5c220a2e5c222032317374204d617920', + \ '313939360a2e5c22204d616e2070616765206175', + \ '74686f723a0a2e5c2220202020546f6e79204e75', + \ '67656e74203c746f6e79407363746e7567656e2e'] call assert_equal(expected, getline(1,'$'), s:Mess(s:test)) " Test 6: Print the date from xxd.1 let s:test += 1 for arg in ['-l 13', '-l13', '-len 13'] %d - exe '0r! ' . s:xxd_cmd . ' -s 0x36 ' . arg . ' -cols 13 ' . man_copy + exe '0r! ' . s:xxd_cmd . ' -s 0x33 ' . arg . ' -cols 13 ' . man_copy $d - call assert_equal('00000036: 3231 7374 204d 6179 2031 3939 36 21st May 1996', getline(1), s:Mess(s:test)) + call assert_equal('00000033: 3231 7374 204d 6179 2031 3939 36 21st May 1996', getline(1), s:Mess(s:test)) endfor " Cleanup after tests 5 and 6 diff --git a/src/testdir/test_zip_plugin.vim b/src/testdir/test_zip_plugin.vim new file mode 100644 index 0000000..e831f26 --- /dev/null +++ b/src/testdir/test_zip_plugin.vim @@ -0,0 +1,237 @@ +so check.vim + +CheckExecutable unzip + +if 0 " Find uncovered line + profile start zip_profile + profile! file */zip*.vim +endif + +runtime plugin/zipPlugin.vim + +def Test_zip_basic() + + ### get our zip file + if !filecopy("samples/test.zip", "X.zip") + assert_report("Can't copy samples/test.zip") + return + endif + defer delete("X.zip") + + e X.zip + + ### Check header + assert_match('^" zip\.vim version v\d\+', getline(1)) + assert_match('^" Browsing zipfile .*/X.zip', getline(2)) + assert_match('^" Select a file with cursor and press ENTER', getline(3)) + assert_match('^$', getline(4)) + + ### Check files listing + assert_equal(["Xzip/", "Xzip/dir/", "Xzip/file.txt"], getline(5, 7)) + + ### Check ENTER on header + :1 + exe ":normal \<cr>" + assert_equal("X.zip", @%) + + ### Check ENTER on directory + :1|:/^$//dir/ + assert_match('Please specify a file, not a directory', + execute("normal \<CR>")) + + ### Check ENTER on file + :1 + search('file.txt') + exe ":normal \<cr>" + assert_match('zipfile://.*/X.zip::Xzip/file.txt', @%) + assert_equal('one', getline(1)) + + ### Check editing file + if executable("zip") + s/one/two/ + assert_equal("two", getline(1)) + w + bw|bw + e X.zip + + :1|:/^$//file/ + exe "normal \<cr>" + assert_equal("two", getline(1)) + endif + + only + e X.zip + + ### Check extracting file + :1|:/^$//file/ + normal x + assert_true(filereadable("Xzip/file.txt")) + + ## Check not overwriting existing file + assert_match('<Xzip/file.txt> .* not overwriting!', execute("normal x")) + + delete("Xzip", "rf") + + ### Check extracting directory + :1|:/^$//dir/ + assert_match('Please specify a file, not a directory', execute("normal x")) + assert_equal("X.zip", @%) + + ### Check "x" on header + :1 + normal x + assert_equal("X.zip", @%) + bw + + ### Check opening zip when "unzip" program is missing + var save_zip_unzipcmd = g:zip_unzipcmd + g:zip_unzipcmd = "/" + assert_match('unzip not available on your system', execute("e X.zip")) + + ### Check when "unzip" don't work + if executable("false") + g:zip_unzipcmd = "false" + assert_match('X\.zip is not a zip file', execute("e X.zip")) + endif + bw + + g:zip_unzipcmd = save_zip_unzipcmd + e X.zip + + ### Check opening file when "unzip" is missing + g:zip_unzipcmd = "/" + assert_match('sorry, your system doesn''t appear to have the / program', + execute("normal \<CR>")) + + bw|bw + g:zip_unzipcmd = save_zip_unzipcmd + e X.zip + + ### Check :write when "zip" program is missing + :1|:/^$//file/ + exe "normal \<cr>Goanother\<esc>" + var save_zip_zipcmd = g:zip_zipcmd + g:zip_zipcmd = "/" + assert_match('sorry, your system doesn''t appear to have the / program', + execute("write")) + + ### Check when "zip" report failure + if executable("false") + g:zip_zipcmd = "false" + assert_match('sorry, unable to update .*/X.zip with Xzip/file.txt', + execute("write")) + endif + bw!|bw + + g:zip_zipcmd = save_zip_zipcmd + + ### Check opening an no zipfile + writefile(["qsdf"], "Xcorupt.zip", "D") + e! Xcorupt.zip + assert_equal("qsdf", getline(1)) + + bw + + ### Check no existing zipfile + assert_match('File not readable', execute("e Xnot_exists.zip")) + + bw +enddef + +def Test_zip_glob_fname() + CheckNotMSWindows + # does not work on Windows, why? + + ### copy sample zip file + if !filecopy("samples/testa.zip", "X.zip") + assert_report("Can't copy samples/testa.zip") + return + endif + defer delete("X.zip") + defer delete('zipglob', 'rf') + + e X.zip + + ### 1) Check extracting strange files + :1 + var fname = 'a[a].txt' + search('\V' .. fname) + normal x + assert_true(filereadable('zipglob/' .. fname)) + delete('zipglob', 'rf') + + :1 + fname = 'a*.txt' + search('\V' .. fname) + normal x + assert_true(filereadable('zipglob/' .. fname)) + delete('zipglob', 'rf') + + :1 + fname = 'a?.txt' + search('\V' .. fname) + normal x + assert_true(filereadable('zipglob/' .. fname)) + delete('zipglob', 'rf') + + :1 + fname = 'a\.txt' + search('\V' .. escape(fname, '\\')) + normal x + assert_true(filereadable('zipglob/' .. fname)) + delete('zipglob', 'rf') + + :1 + fname = 'a\\.txt' + search('\V' .. escape(fname, '\\')) + normal x + assert_true(filereadable('zipglob/' .. fname)) + delete('zipglob', 'rf') + + ### 2) Check entering strange file names + :1 + fname = 'a[a].txt' + search('\V' .. fname) + exe ":normal \<cr>" + assert_match('zipfile://.*/X.zip::zipglob/a\[a\].txt', @%) + assert_equal('a test file with []', getline(1)) + bw + + e X.zip + :1 + fname = 'a*.txt' + search('\V' .. fname) + exe ":normal \<cr>" + assert_match('zipfile://.*/X.zip::zipglob/a\*.txt', @%) + assert_equal('a test file with a*', getline(1)) + bw + + e X.zip + :1 + fname = 'a?.txt' + search('\V' .. fname) + exe ":normal \<cr>" + assert_match('zipfile://.*/X.zip::zipglob/a?.txt', @%) + assert_equal('a test file with a?', getline(1)) + bw + + e X.zip + :1 + fname = 'a\.txt' + search('\V' .. escape(fname, '\\')) + exe ":normal \<cr>" + assert_match('zipfile://.*/X.zip::zipglob/a\\.txt', @%) + assert_equal('a test file with a\', getline(1)) + bw + + e X.zip + :1 + fname = 'a\\.txt' + search('\V' .. escape(fname, '\\')) + exe ":normal \<cr>" + assert_match('zipfile://.*/X.zip::zipglob/a\\\\.txt', @%) + assert_equal('a test file with a double \', getline(1)) + bw + + bw +enddef diff --git a/src/testdir/view_util.vim b/src/testdir/view_util.vim index 71cb071..161c8b2 100644 --- a/src/testdir/view_util.vim +++ b/src/testdir/view_util.vim @@ -71,7 +71,7 @@ endfunc " than the raw code. " Return the modifyOtherKeys level 2 encoding for "key" with "modifier" -" (number value, e.g. CTRL is 5). +" (number value, e.g. CTRL is 5, Shift is 2, Alt is 3). func GetEscCodeCSI27(key, modifier) let key = printf("%d", char2nr(a:key)) let mod = printf("%d", a:modifier) diff --git a/src/testdir/viewdumps.vim b/src/testdir/viewdumps.vim new file mode 100644 index 0000000..62f7bbe --- /dev/null +++ b/src/testdir/viewdumps.vim @@ -0,0 +1,11 @@ +vim9script + +exec 'source ' .. (((cwdpath: string) => cwdpath + ->strpart(0, cwdpath->strridx('/vim')))(getcwd())) + .. '/vim/src/testdir/commondumps.vim' +g:Init('\<src\>', 0) + +# Match ":language" of runtest.vim. +language messages C + +# vim:fdm=syntax:sw=2:ts=8:noet:nolist:nosta: diff --git a/src/testing.c b/src/testing.c index 3e9e077..7ab109c 100644 --- a/src/testing.c +++ b/src/testing.c @@ -99,7 +99,7 @@ ga_concat_shorten_esc(garray_T *gap, char_u *str) return; } - for (p = str; *p != NUL; ++p) + for (p = str; *p != NUL; ) { same_len = 1; s = p; @@ -118,10 +118,13 @@ ga_concat_shorten_esc(garray_T *gap, char_u *str) vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len); ga_concat(gap, buf); ga_concat(gap, (char_u *)" times]"); - p = s - 1; + p = s; } else + { ga_concat_esc(gap, p, clen); + p += clen; + } } } @@ -187,7 +190,7 @@ fill_assert_error( { item2 = dict_find(got_d, hi->hi_key, -1); if (item2 == NULL || !tv_equal(&HI2DI(hi)->di_tv, - &item2->di_tv, FALSE, FALSE)) + &item2->di_tv, FALSE)) { // item of exp_d not present in got_d or values differ. dict_add_tv(exp_tv->vval.v_dict, @@ -262,7 +265,7 @@ assert_equal_common(typval_T *argvars, assert_type_T atype) { garray_T ga; - if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE) + if (tv_equal(&argvars[0], &argvars[1], FALSE) != (atype == ASSERT_EQUAL)) { prepare_assert_error(&ga); diff --git a/src/textobject.c b/src/textobject.c index 1890d7c..aa2db07 100644 --- a/src/textobject.c +++ b/src/textobject.c @@ -1426,15 +1426,22 @@ again: if (!do_include) { - // Exclude the start tag. + // Exclude the start tag, + // but skip over '>' if it appears in quotes + int in_quotes = FALSE; curwin->w_cursor = start_pos; while (inc_cursor() >= 0) - if (*ml_get_cursor() == '>') + { + p = ml_get_cursor(); + if (*p == '>' && !in_quotes) { inc_cursor(); start_pos = curwin->w_cursor; break; } + else if (*p == '"' || *p == '\'') + in_quotes = !in_quotes; + } curwin->w_cursor = end_pos; // If we are in Visual mode and now have the same text as before set diff --git a/src/textprop.c b/src/textprop.c index 83c42a3..fe0c8d2 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -2060,7 +2060,7 @@ list_types(hashtab_T *ht, list_T *l) * prop_type_list([{bufnr}]) */ void -f_prop_type_list(typval_T *argvars, typval_T *rettv UNUSED) +f_prop_type_list(typval_T *argvars, typval_T *rettv) { buf_T *buf = NULL; diff --git a/src/typval.c b/src/typval.c index 6a73719..01ffef5 100644 --- a/src/typval.c +++ b/src/typval.c @@ -267,11 +267,16 @@ tv_get_bool_or_number_chk( break; case VAR_OBJECT: { - class_T *cl = varp->vval.v_object->obj_class; - if (cl != NULL && IS_ENUM(cl)) - semsg(_(e_using_enum_str_as_number), cl->class_name); + if (varp->vval.v_object == NULL) + emsg(_(e_using_object_as_string)); else - emsg(_(e_using_object_as_number)); + { + class_T *cl = varp->vval.v_object->obj_class; + if (cl != NULL && IS_ENUM(cl)) + semsg(_(e_using_enum_str_as_number), cl->class_name); + else + emsg(_(e_using_object_as_number)); + } } break; case VAR_VOID: @@ -1146,11 +1151,16 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict) break; case VAR_OBJECT: { - class_T *cl = varp->vval.v_object->obj_class; - if (cl != NULL && IS_ENUM(cl)) - semsg(_(e_using_enum_str_as_string), cl->class_name); - else + if (varp->vval.v_object == NULL) emsg(_(e_using_object_as_string)); + else + { + class_T *cl = varp->vval.v_object->obj_class; + if (cl != NULL && IS_ENUM(cl)) + semsg(_(e_using_enum_str_as_string), cl->class_name); + else + emsg(_(e_using_object_as_string)); + } } break; case VAR_JOB: @@ -1605,8 +1615,7 @@ typval_compare_list( } else { - val = list_equal(tv1->vval.v_list, tv2->vval.v_list, - ic, FALSE); + val = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); if (type == EXPR_NEQUAL) val = !val; } @@ -1699,24 +1708,6 @@ typval_compare_blob( } /* - * Compare "tv1" to "tv2" as classes according to "type". - * Put the result, false or true, in "res". - * Return FAIL and give an error message when the comparison can't be done. - */ - int -typval_compare_class( - typval_T *tv1, - typval_T *tv2, - exprtype_T type UNUSED, - int ic UNUSED, - int *res) -{ - // TODO: use "type" - *res = tv1->vval.v_class == tv2->vval.v_class; - return OK; -} - -/* * Compare "tv1" to "tv2" as objects according to "type". * Put the result, false or true, in "res". * Return FAIL and give an error message when the comparison can't be done. @@ -1742,14 +1733,6 @@ typval_compare_object( return OK; } - class_T *cl1 = tv1->vval.v_object->obj_class; - class_T *cl2 = tv2->vval.v_object->obj_class; - if (cl1 != cl2 || cl1 == NULL || cl2 == NULL) - { - *res = !res_match; - return OK; - } - object_T *obj1 = tv1->vval.v_object; object_T *obj2 = tv2->vval.v_object; if (type == EXPR_IS || type == EXPR_ISNOT) @@ -1758,14 +1741,7 @@ typval_compare_object( return OK; } - for (int i = 0; i < cl1->class_obj_member_count; ++i) - if (!tv_equal((typval_T *)(obj1 + 1) + i, - (typval_T *)(obj2 + 1) + i, ic, TRUE)) - { - *res = !res_match; - return OK; - } - *res = res_match; + *res = object_equal(obj1, obj2, ic) ? res_match : !res_match; return OK; } @@ -1802,7 +1778,7 @@ typval_compare_dict( } else { - val = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, FALSE); + val = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); if (type == EXPR_NEQUAL) val = !val; } @@ -1841,14 +1817,14 @@ typval_compare_func( if (tv1->v_type == VAR_FUNC && tv2->v_type == VAR_FUNC) // strings are considered the same if their value is // the same - val = tv_equal(tv1, tv2, ic, FALSE); + val = tv_equal(tv1, tv2, ic); else if (tv1->v_type == VAR_PARTIAL && tv2->v_type == VAR_PARTIAL) val = (tv1->vval.v_partial == tv2->vval.v_partial); else val = FALSE; } else - val = tv_equal(tv1, tv2, ic, FALSE); + val = tv_equal(tv1, tv2, ic); if (type == EXPR_NEQUAL || type == EXPR_ISNOT) val = !val; *res = val; @@ -2003,7 +1979,7 @@ func_equal( if (d1 != d2) return FALSE; } - else if (!dict_equal(d1, d2, ic, TRUE)) + else if (!dict_equal(d1, d2, ic)) return FALSE; // empty list and no list considered the same @@ -2013,7 +1989,7 @@ func_equal( return FALSE; for (i = 0; i < a1; ++i) if (!tv_equal(tv1->vval.v_partial->pt_argv + i, - tv2->vval.v_partial->pt_argv + i, ic, TRUE)) + tv2->vval.v_partial->pt_argv + i, ic)) return FALSE; return TRUE; @@ -2028,8 +2004,7 @@ func_equal( tv_equal( typval_T *tv1, typval_T *tv2, - int ic, // ignore case - int recursive) // TRUE when used recursively + int ic) // ignore case { char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; char_u *s1, *s2; @@ -2043,7 +2018,7 @@ tv_equal( // Reduce the limit every time running into it. That should work fine for // deeply linked structures that are not recursively linked and catch // recursiveness quickly. - if (!recursive) + if (recursive_cnt == 0) tv_equal_recurse_limit = 1000; if (recursive_cnt >= tv_equal_recurse_limit) { @@ -2073,13 +2048,13 @@ tv_equal( { case VAR_LIST: ++recursive_cnt; - r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE); + r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); --recursive_cnt; return r; case VAR_DICT: ++recursive_cnt; - r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE); + r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); --recursive_cnt; return r; @@ -2114,7 +2089,9 @@ tv_equal( return tv1->vval.v_class == tv2->vval.v_class; case VAR_OBJECT: - (void)typval_compare_object(tv1, tv2, EXPR_EQUAL, ic, &r); + ++recursive_cnt; + r = object_equal(tv1->vval.v_object, tv2->vval.v_object, ic); + --recursive_cnt; return r; case VAR_PARTIAL: @@ -2237,7 +2214,7 @@ eval_number( char_u **arg, typval_T *rettv, int evaluate, - int want_string UNUSED) + int want_string) { int len; int skip_quotes = !in_old_script(4); @@ -3683,7 +3683,7 @@ u_eval_tree(buf_T *buf, u_header_T *first_uhp, list_T *list) * "undofile(name)" function */ void -f_undofile(typval_T *argvars UNUSED, typval_T *rettv) +f_undofile(typval_T *argvars, typval_T *rettv) { if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) return; @@ -3738,7 +3738,7 @@ u_undofile_reset_and_delete(buf_T *buf) * "undotree(expr)" function */ void -f_undotree(typval_T *argvars UNUSED, typval_T *rettv) +f_undotree(typval_T *argvars, typval_T *rettv) { if (in_vim9script() && check_for_opt_buffer_arg(argvars, 0) == FAIL) return; diff --git a/src/usercmd.c b/src/usercmd.c index e2c0114..585ced3 100644 --- a/src/usercmd.c +++ b/src/usercmd.c @@ -16,6 +16,7 @@ typedef struct ucmd { char_u *uc_name; // The command name + size_t uc_namelen; // The length of the command name (excluding the NUL) long_u uc_argt; // The argument type char_u *uc_rep; // The command's replacement string long uc_def; // The default value for a range/count @@ -39,93 +40,100 @@ static int ucmd_locked = 0; /* * List of names for completion for ":command" with the EXPAND_ flag. - * Must be alphabetical for completion. + * Must be alphabetical on the 'value' field for completion and because + * it is used by bsearch()! */ -static struct +static keyvalue_T command_complete_tab[] = { - int expand; - char *name; -} command_complete[] = -{ - {EXPAND_ARGLIST, "arglist"}, - {EXPAND_AUGROUP, "augroup"}, - {EXPAND_BEHAVE, "behave"}, - {EXPAND_BUFFERS, "buffer"}, - {EXPAND_COLORS, "color"}, - {EXPAND_COMMANDS, "command"}, - {EXPAND_COMPILER, "compiler"}, + KEYVALUE_ENTRY(EXPAND_ARGLIST, "arglist"), + KEYVALUE_ENTRY(EXPAND_AUGROUP, "augroup"), + KEYVALUE_ENTRY(EXPAND_BEHAVE, "behave"), +#if defined(FEAT_EVAL) + KEYVALUE_ENTRY(EXPAND_BREAKPOINT, "breakpoint"), +#endif + KEYVALUE_ENTRY(EXPAND_BUFFERS, "buffer"), + KEYVALUE_ENTRY(EXPAND_COLORS, "color"), + KEYVALUE_ENTRY(EXPAND_COMMANDS, "command"), + KEYVALUE_ENTRY(EXPAND_COMPILER, "compiler"), #if defined(FEAT_CSCOPE) - {EXPAND_CSCOPE, "cscope"}, + KEYVALUE_ENTRY(EXPAND_CSCOPE, "cscope"), #endif #if defined(FEAT_EVAL) - {EXPAND_USER_DEFINED, "custom"}, - {EXPAND_USER_LIST, "customlist"}, + KEYVALUE_ENTRY(EXPAND_USER_DEFINED, "custom"), + KEYVALUE_ENTRY(EXPAND_USER_LIST, "customlist"), #endif - {EXPAND_DIFF_BUFFERS, "diff_buffer"}, - {EXPAND_DIRECTORIES, "dir"}, - {EXPAND_ENV_VARS, "environment"}, - {EXPAND_EVENTS, "event"}, - {EXPAND_EXPRESSION, "expression"}, - {EXPAND_FILES, "file"}, - {EXPAND_FILES_IN_PATH, "file_in_path"}, - {EXPAND_FILETYPE, "filetype"}, - {EXPAND_FUNCTIONS, "function"}, - {EXPAND_HELP, "help"}, - {EXPAND_HIGHLIGHT, "highlight"}, - {EXPAND_HISTORY, "history"}, + KEYVALUE_ENTRY(EXPAND_DIFF_BUFFERS, "diff_buffer"), + KEYVALUE_ENTRY(EXPAND_DIRECTORIES, "dir"), + KEYVALUE_ENTRY(EXPAND_DIRS_IN_CDPATH, "dir_in_path"), + KEYVALUE_ENTRY(EXPAND_ENV_VARS, "environment"), + KEYVALUE_ENTRY(EXPAND_EVENTS, "event"), + KEYVALUE_ENTRY(EXPAND_EXPRESSION, "expression"), + KEYVALUE_ENTRY(EXPAND_FILES, "file"), + KEYVALUE_ENTRY(EXPAND_FILES_IN_PATH, "file_in_path"), + KEYVALUE_ENTRY(EXPAND_FILETYPE, "filetype"), + KEYVALUE_ENTRY(EXPAND_FUNCTIONS, "function"), + KEYVALUE_ENTRY(EXPAND_HELP, "help"), + KEYVALUE_ENTRY(EXPAND_HIGHLIGHT, "highlight"), + KEYVALUE_ENTRY(EXPAND_HISTORY, "history"), #if defined(FEAT_KEYMAP) - {EXPAND_KEYMAP, "keymap"}, + KEYVALUE_ENTRY(EXPAND_KEYMAP, "keymap"), #endif #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) - {EXPAND_LOCALES, "locale"}, + KEYVALUE_ENTRY(EXPAND_LOCALES, "locale"), #endif - {EXPAND_MAPCLEAR, "mapclear"}, - {EXPAND_MAPPINGS, "mapping"}, - {EXPAND_MENUS, "menu"}, - {EXPAND_MESSAGES, "messages"}, - {EXPAND_OWNSYNTAX, "syntax"}, -#if defined(FEAT_PROFILE) - {EXPAND_SYNTIME, "syntime"}, + KEYVALUE_ENTRY(EXPAND_MAPCLEAR, "mapclear"), + KEYVALUE_ENTRY(EXPAND_MAPPINGS, "mapping"), + KEYVALUE_ENTRY(EXPAND_MENUS, "menu"), + KEYVALUE_ENTRY(EXPAND_MESSAGES, "messages"), + KEYVALUE_ENTRY(EXPAND_SETTINGS, "option"), + KEYVALUE_ENTRY(EXPAND_PACKADD, "packadd"), + KEYVALUE_ENTRY(EXPAND_RUNTIME, "runtime"), +#if defined(FEAT_EVAL) + KEYVALUE_ENTRY(EXPAND_SCRIPTNAMES, "scriptnames"), #endif - {EXPAND_SETTINGS, "option"}, - {EXPAND_PACKADD, "packadd"}, - {EXPAND_RUNTIME, "runtime"}, - {EXPAND_SHELLCMD, "shellcmd"}, + KEYVALUE_ENTRY(EXPAND_SHELLCMD, "shellcmd"), #if defined(FEAT_SIGNS) - {EXPAND_SIGN, "sign"}, + KEYVALUE_ENTRY(EXPAND_SIGN, "sign"), #endif - {EXPAND_TAGS, "tag"}, - {EXPAND_TAGS_LISTFILES, "tag_listfiles"}, - {EXPAND_USER, "user"}, - {EXPAND_USER_VARS, "var"}, -#if defined(FEAT_EVAL) - {EXPAND_BREAKPOINT, "breakpoint"}, - {EXPAND_SCRIPTNAMES, "scriptnames"}, + KEYVALUE_ENTRY(EXPAND_OWNSYNTAX, "syntax"), +#if defined(FEAT_PROFILE) + KEYVALUE_ENTRY(EXPAND_SYNTIME, "syntime"), #endif - {0, NULL} + KEYVALUE_ENTRY(EXPAND_TAGS, "tag"), + KEYVALUE_ENTRY(EXPAND_TAGS_LISTFILES, "tag_listfiles"), + KEYVALUE_ENTRY(EXPAND_USER, "user"), + KEYVALUE_ENTRY(EXPAND_USER_VARS, "var") }; +typedef struct +{ + cmd_addr_T key; + char *fullname; + size_t fullnamelen; + char *shortname; + size_t shortnamelen; +} addrtype_T; + /* * List of names of address types. Must be alphabetical for completion. + * Must be sorted by the 'fullname' field because it is used by bsearch()! */ -static struct +#define ADDRTYPE_ENTRY(k, fn, sn) \ + {(k), (fn), STRLEN_LITERAL(fn), (sn), STRLEN_LITERAL(sn)} +static addrtype_T addr_type_complete_tab[] = { - cmd_addr_T expand; - char *name; - char *shortname; -} addr_type_complete[] = -{ - {ADDR_ARGUMENTS, "arguments", "arg"}, - {ADDR_LINES, "lines", "line"}, - {ADDR_LOADED_BUFFERS, "loaded_buffers", "load"}, - {ADDR_TABS, "tabs", "tab"}, - {ADDR_BUFFERS, "buffers", "buf"}, - {ADDR_WINDOWS, "windows", "win"}, - {ADDR_QUICKFIX, "quickfix", "qf"}, - {ADDR_OTHER, "other", "?"}, - {ADDR_NONE, NULL, NULL} + ADDRTYPE_ENTRY(ADDR_ARGUMENTS, "arguments", "arg"), + ADDRTYPE_ENTRY(ADDR_BUFFERS, "buffers", "buf"), + ADDRTYPE_ENTRY(ADDR_LINES, "lines", "line"), + ADDRTYPE_ENTRY(ADDR_LOADED_BUFFERS, "loaded_buffers", "load"), + ADDRTYPE_ENTRY(ADDR_OTHER, "other", "?"), + ADDRTYPE_ENTRY(ADDR_QUICKFIX, "quickfix", "qf"), + ADDRTYPE_ENTRY(ADDR_TABS, "tabs", "tab"), + ADDRTYPE_ENTRY(ADDR_WINDOWS, "windows", "win") }; +static int cmp_addr_type(const void *a, const void *b); + /* * Search for a user command that matches "eap->cmd". * Return cmdidx in "eap->cmdidx", flags in "eap->argt", idx in "eap->useridx". @@ -271,19 +279,16 @@ set_context_in_user_cmd(expand_T *xp, char_u *arg_in) { xp->xp_context = EXPAND_USER_COMPLETE; xp->xp_pattern = p + 1; - return NULL; } else if (STRNICMP(arg, "nargs", p - arg) == 0) { xp->xp_context = EXPAND_USER_NARGS; xp->xp_pattern = p + 1; - return NULL; } else if (STRNICMP(arg, "addr", p - arg) == 0) { xp->xp_context = EXPAND_USER_ADDR_TYPE; xp->xp_pattern = p + 1; - return NULL; } return NULL; } @@ -416,7 +421,9 @@ get_user_command_name(int idx, int cmdidx) char_u * get_user_cmd_addr_type(expand_T *xp UNUSED, int idx) { - return (char_u *)addr_type_complete[idx].name; + if (idx < 0 || idx >= (int)ARRAY_LENGTH(addr_type_complete_tab)) + return NULL; + return (char_u *)addr_type_complete_tab[idx].fullname; } /* @@ -431,7 +438,7 @@ get_user_cmd_flags(expand_T *xp UNUSED, int idx) "count", "nargs", "range", "register", "keepscript" }; - if (idx >= (int)ARRAY_LENGTH(user_cmd_flags)) + if (idx < 0 || idx >= (int)ARRAY_LENGTH(user_cmd_flags)) return NULL; return (char_u *)user_cmd_flags[idx]; } @@ -444,7 +451,7 @@ get_user_cmd_nargs(expand_T *xp UNUSED, int idx) { static char *user_cmd_nargs[] = {"0", "1", "*", "?", "+"}; - if (idx >= (int)ARRAY_LENGTH(user_cmd_nargs)) + if (idx < 0 || idx >= (int)ARRAY_LENGTH(user_cmd_nargs)) return NULL; return (char_u *)user_cmd_nargs[idx]; } @@ -456,7 +463,24 @@ get_user_cmd_nargs(expand_T *xp UNUSED, int idx) char_u * get_user_cmd_complete(expand_T *xp UNUSED, int idx) { - return (char_u *)command_complete[idx].name; + if (idx < 0 || idx >= (int)ARRAY_LENGTH(command_complete_tab)) + return NULL; + return (char_u *)command_complete_tab[idx].value; +} + +/* + * Return the row in the command_complete_tab table that contains the given key. + */ + static keyvalue_T * +get_commandtype(int expand) +{ + int i; + + for (i = 0; i < (int)ARRAY_LENGTH(command_complete_tab); ++i) + if (command_complete_tab[i].key == expand) + return &command_complete_tab[i]; + + return NULL; } #ifdef FEAT_EVAL @@ -466,13 +490,11 @@ get_user_cmd_complete(expand_T *xp UNUSED, int idx) char_u * cmdcomplete_type_to_str(int expand) { - int i; + keyvalue_T *kv; - for (i = 0; command_complete[i].expand != 0; i++) - if (command_complete[i].expand == expand) - return (char_u *)command_complete[i].name; + kv = get_commandtype(expand); - return NULL; + return (kv == NULL) ? NULL : (char_u *)kv->value; } /* @@ -482,18 +504,35 @@ cmdcomplete_type_to_str(int expand) int cmdcomplete_str_to_type(char_u *complete_str) { - int i; + keyvalue_T target; + keyvalue_T *entry; + static keyvalue_T *last_entry = NULL; // cached result if (STRNCMP(complete_str, "custom,", 7) == 0) return EXPAND_USER_DEFINED; if (STRNCMP(complete_str, "customlist,", 11) == 0) return EXPAND_USER_LIST; - for (i = 0; command_complete[i].expand != 0; ++i) - if (STRCMP(complete_str, command_complete[i].name) == 0) - return command_complete[i].expand; + target.key = 0; + target.value = (char *)complete_str; + target.length = 0; // not used, see cmp_keyvalue_value() + + if (last_entry != NULL && cmp_keyvalue_value(&target, last_entry) == 0) + entry = last_entry; + else + { + entry = (keyvalue_T *)bsearch(&target, + &command_complete_tab, + ARRAY_LENGTH(command_complete_tab), + sizeof(command_complete_tab[0]), + cmp_keyvalue_value); + if (entry == NULL) + return EXPAND_NOTHING; + + last_entry = entry; + } - return EXPAND_NOTHING; + return entry->key; } #endif @@ -510,6 +549,7 @@ uc_list(char_u *name, size_t name_len) int over; long a; garray_T *gap; + keyvalue_T *entry; // don't allow for adding or removing user commands here ++ucmd_locked; @@ -563,7 +603,7 @@ uc_list(char_u *name, size_t name_len) msg_putchar(' '); msg_outtrans_attr(cmd->uc_name, HL_ATTR(HLF_D)); - len = (int)STRLEN(cmd->uc_name) + 4; + len = (int)cmd->uc_namelen + 4; do { msg_putchar(' '); @@ -595,16 +635,14 @@ uc_list(char_u *name, size_t name_len) if (a & EX_COUNT) { // -count=N - sprintf((char *)IObuff + len, "%ldc", cmd->uc_def); - len += (int)STRLEN(IObuff + len); + len += vim_snprintf((char *)IObuff + len, IOSIZE - len, "%ldc", cmd->uc_def); } else if (a & EX_DFLALL) IObuff[len++] = '%'; else if (cmd->uc_def >= 0) { // -range=N - sprintf((char *)IObuff + len, "%ld", cmd->uc_def); - len += (int)STRLEN(IObuff + len); + len += vim_snprintf((char *)IObuff + len, IOSIZE - len, "%ld", cmd->uc_def); } else IObuff[len++] = '.'; @@ -615,12 +653,12 @@ uc_list(char_u *name, size_t name_len) } while (len < 8 - over); // Address Type - for (j = 0; addr_type_complete[j].expand != ADDR_NONE; ++j) - if (addr_type_complete[j].expand != ADDR_LINES - && addr_type_complete[j].expand == cmd->uc_addr_type) + for (j = 0; j < (int)ARRAY_LENGTH(addr_type_complete_tab); ++j) + if (addr_type_complete_tab[j].key != ADDR_LINES + && addr_type_complete_tab[j].key == cmd->uc_addr_type) { - STRCPY(IObuff + len, addr_type_complete[j].shortname); - len += (int)STRLEN(IObuff + len); + STRCPY(IObuff + len, addr_type_complete_tab[j].shortname); + len += (int)addr_type_complete_tab[j].shortnamelen; break; } @@ -629,28 +667,31 @@ uc_list(char_u *name, size_t name_len) } while (len < 13 - over); // Completion - for (j = 0; command_complete[j].expand != 0; ++j) - if (command_complete[j].expand == cmd->uc_compl) - { - STRCPY(IObuff + len, command_complete[j].name); - len += (int)STRLEN(IObuff + len); + entry = get_commandtype(cmd->uc_compl); + if (entry != NULL) + { + STRCPY(IObuff + len, entry->value); + len += entry->length; #ifdef FEAT_EVAL - if (p_verbose > 0 && cmd->uc_compl_arg != NULL - && STRLEN(cmd->uc_compl_arg) < 200) + if (p_verbose > 0 && cmd->uc_compl_arg != NULL) + { + size_t uc_compl_arglen = STRLEN(cmd->uc_compl_arg); + + if (uc_compl_arglen < 200) { - IObuff[len] = ','; - STRCPY(IObuff + len + 1, cmd->uc_compl_arg); - len += (int)STRLEN(IObuff + len); + IObuff[len++] = ','; + STRCPY(IObuff + len, cmd->uc_compl_arg); + len += uc_compl_arglen; } -#endif - break; } +#endif + } do { IObuff[len++] = ' '; } while (len < 25 - over); - IObuff[len] = '\0'; + IObuff[len] = NUL; msg_outtrans(IObuff); msg_outtrans_special(cmd->uc_rep, FALSE, @@ -686,7 +727,7 @@ uc_fun_cmd(void) for (i = 0; fcmd[i]; ++i) IObuff[i] = fcmd[i] - 0x40; - IObuff[i] = 0; + IObuff[i] = NUL; return (char *)IObuff; } @@ -699,33 +740,52 @@ parse_addr_type_arg( int vallen, cmd_addr_T *addr_type_arg) { - int i, a, b; + addrtype_T target; + addrtype_T *entry; + static addrtype_T *last_entry; // cached result + + target.key = 0; + target.fullname = (char *)value; + target.fullnamelen = vallen; - for (i = 0; addr_type_complete[i].expand != ADDR_NONE; ++i) + if (last_entry != NULL && cmp_addr_type(&target, last_entry) == 0) + entry = last_entry; + else { - a = (int)STRLEN(addr_type_complete[i].name) == vallen; - b = STRNCMP(value, addr_type_complete[i].name, vallen) == 0; - if (a && b) + entry = (addrtype_T *)bsearch(&target, + &addr_type_complete_tab, + ARRAY_LENGTH(addr_type_complete_tab), + sizeof(addr_type_complete_tab[0]), + cmp_addr_type); + if (entry == NULL) { - *addr_type_arg = addr_type_complete[i].expand; - break; - } - } + int i; + char_u *err = value; - if (addr_type_complete[i].expand == ADDR_NONE) - { - char_u *err = value; + for (i = 0; err[i] != NUL && !VIM_ISWHITE(err[i]); i++) + ; + err[i] = NUL; + semsg(_(e_invalid_address_type_value_str), err); + return FAIL; + } - for (i = 0; err[i] != NUL && !VIM_ISWHITE(err[i]); i++) - ; - err[i] = NUL; - semsg(_(e_invalid_address_type_value_str), err); - return FAIL; + last_entry = entry; } + *addr_type_arg = entry->key; + return OK; } + static int +cmp_addr_type(const void *a, const void *b) +{ + addrtype_T *at1 = (addrtype_T *)a; + addrtype_T *at2 = (addrtype_T *)b; + + return STRNCMP(at1->fullname, at2->fullname, MAX(at1->fullnamelen, at2->fullnamelen)); +} + /* * Parse a completion argument "value[vallen]". * The detected completion goes in "*complp", argument type in "*argt". @@ -747,6 +807,9 @@ parse_compl_arg( # endif int i; int valend = vallen; + keyvalue_T target; + keyvalue_T *entry; + static keyvalue_T *last_entry = NULL; // cached result // Look for any argument part - which is the part after any ',' for (i = 0; i < vallen; ++i) @@ -762,33 +825,40 @@ parse_compl_arg( } } - for (i = 0; command_complete[i].expand != 0; ++i) + target.key = 0; + target.value = (char *)value; + target.length = valend; + + if (last_entry != NULL && cmp_keyvalue_value_n(&target, last_entry) == 0) + entry = last_entry; + else { - if ((int)STRLEN(command_complete[i].name) == valend - && STRNCMP(value, command_complete[i].name, valend) == 0) + entry = (keyvalue_T *)bsearch(&target, + &command_complete_tab, + ARRAY_LENGTH(command_complete_tab), + sizeof(command_complete_tab[0]), + cmp_keyvalue_value_n); + if (entry == NULL) { - *complp = command_complete[i].expand; - if (command_complete[i].expand == EXPAND_BUFFERS) - *argt |= EX_BUFNAME; - else if (command_complete[i].expand == EXPAND_DIRECTORIES - || command_complete[i].expand == EXPAND_FILES) - *argt |= EX_XFILE; - break; + semsg(_(e_invalid_complete_value_str), value); + return FAIL; } - } - if (command_complete[i].expand == 0) - { - semsg(_(e_invalid_complete_value_str), value); - return FAIL; + last_entry = entry; } + *complp = entry->key; + if (*complp == EXPAND_BUFFERS) + *argt |= EX_BUFNAME; + else if (*complp == EXPAND_DIRECTORIES || *complp == EXPAND_FILES) + *argt |= EX_XFILE; + + if ( # if defined(FEAT_EVAL) - if (*complp != EXPAND_USER_DEFINED && *complp != EXPAND_USER_LIST - && arg != NULL) -# else - if (arg != NULL) + *complp != EXPAND_USER_DEFINED && *complp != EXPAND_USER_LIST + && # endif + arg != NULL) { emsg(_(e_completion_argument_only_allowed_for_custom_completion)); return FAIL; @@ -805,6 +875,7 @@ parse_compl_arg( if (arg != NULL) *compl_arg = vim_strnsave(arg, arglen); # endif + return OK; } @@ -1022,16 +1093,13 @@ uc_add_command( // Search for the command in the already defined commands. for (i = 0; i < gap->ga_len; ++i) { - size_t len; - cmd = USER_CMD_GA(gap, i); - len = STRLEN(cmd->uc_name); cmp = STRNCMP(name, cmd->uc_name, name_len); if (cmp == 0) { - if (name_len < len) + if (name_len < cmd->uc_namelen) cmp = -1; - else if (name_len > len) + else if (name_len > cmd->uc_namelen) cmp = 1; } @@ -1077,6 +1145,7 @@ uc_add_command( ++gap->ga_len; cmd->uc_name = p; + cmd->uc_namelen = name_len; } cmd->uc_rep = rep_buf; @@ -1198,7 +1267,7 @@ ex_command(exarg_T *eap) p = skipwhite(end); if (!has_attr && ends_excmd2(eap->arg, p)) { - uc_list(name, end - name); + uc_list(name, name_len); } else if (!ASCII_ISUPPER(*name)) { @@ -1281,6 +1350,7 @@ uc_clear(garray_T *gap) { cmd = USER_CMD_GA(gap, i); vim_free(cmd->uc_name); + cmd->uc_namelen = 0; vim_free(cmd->uc_rep); # if defined(FEAT_EVAL) vim_free(cmd->uc_compl_arg); @@ -1438,30 +1508,31 @@ uc_split_args(char_u *arg, size_t *lenp) } } *q++ = '"'; - *q = 0; + *q = NUL; *lenp = len; return buf; } static size_t -add_cmd_modifier(char_u *buf, char *mod_str, int *multi_mods) +add_cmd_modifier(char_u *buf, size_t buflen, char *mod_str, size_t mod_strlen, int *multi_mods) { - size_t result; - - result = STRLEN(mod_str); - if (*multi_mods) - result += 1; if (buf != NULL) { if (*multi_mods) - STRCAT(buf, " "); - STRCAT(buf, mod_str); + { + STRCPY(buf + buflen, " "); // the separating space + ++buflen; + } + STRCPY(buf + buflen, mod_str); } - *multi_mods = 1; + if (*multi_mods) + ++mod_strlen; // +1 for the separating space + else + *multi_mods = 1; - return result; + return mod_strlen; } /* @@ -1471,17 +1542,17 @@ add_cmd_modifier(char_u *buf, char *mod_str, int *multi_mods) size_t add_win_cmd_modifiers(char_u *buf, cmdmod_T *cmod, int *multi_mods) { - size_t result = 0; + size_t buflen = 0; // :aboveleft and :leftabove if (cmod->cmod_split & WSP_ABOVE) - result += add_cmd_modifier(buf, "aboveleft", multi_mods); + buflen += add_cmd_modifier(buf, buflen, "aboveleft", STRLEN_LITERAL("aboveleft"), multi_mods); // :belowright and :rightbelow if (cmod->cmod_split & WSP_BELOW) - result += add_cmd_modifier(buf, "belowright", multi_mods); + buflen += add_cmd_modifier(buf, buflen, "belowright", STRLEN_LITERAL("belowright"), multi_mods); // :botright if (cmod->cmod_split & WSP_BOT) - result += add_cmd_modifier(buf, "botright", multi_mods); + buflen += add_cmd_modifier(buf, buflen, "botright", STRLEN_LITERAL("botright"), multi_mods); // :tab if (cmod->cmod_tab > 0) @@ -1492,27 +1563,29 @@ add_win_cmd_modifiers(char_u *buf, cmdmod_T *cmod, int *multi_mods) { // For compatibility, don't add a tabpage number if it is the same // as the default number for :tab. - result += add_cmd_modifier(buf, "tab", multi_mods); + buflen += add_cmd_modifier(buf, buflen, "tab", STRLEN_LITERAL("tab"), multi_mods); } else { char tab_buf[NUMBUFLEN + 3]; + size_t tab_buflen; - sprintf(tab_buf, "%dtab", tabnr); - result += add_cmd_modifier(buf, tab_buf, multi_mods); + tab_buflen = vim_snprintf(tab_buf, sizeof(tab_buf), "%dtab", tabnr); + buflen += add_cmd_modifier(buf, buflen, tab_buf, tab_buflen, multi_mods); } } // :topleft if (cmod->cmod_split & WSP_TOP) - result += add_cmd_modifier(buf, "topleft", multi_mods); + buflen += add_cmd_modifier(buf, buflen, "topleft", STRLEN_LITERAL("topleft"), multi_mods); // :vertical if (cmod->cmod_split & WSP_VERT) - result += add_cmd_modifier(buf, "vertical", multi_mods); + buflen += add_cmd_modifier(buf, buflen, "vertical", STRLEN_LITERAL("vertical"), multi_mods); // :horizontal if (cmod->cmod_split & WSP_HOR) - result += add_cmd_modifier(buf, "horizontal", multi_mods); - return result; + buflen += add_cmd_modifier(buf, buflen, "horizontal", STRLEN_LITERAL("horizontal"), multi_mods); + + return buflen; } /* @@ -1522,78 +1595,92 @@ add_win_cmd_modifiers(char_u *buf, cmdmod_T *cmod, int *multi_mods) size_t produce_cmdmods(char_u *buf, cmdmod_T *cmod, int quote) { - size_t result = 0; + size_t buflen = 0; int multi_mods = 0; int i; - typedef struct { - int flag; - char *name; - } mod_entry_T; - static mod_entry_T mod_entries[] = { + static keyvalue_T mod_entry_tab[] = + { #ifdef FEAT_BROWSE_CMD - {CMOD_BROWSE, "browse"}, + KEYVALUE_ENTRY(CMOD_BROWSE, "browse"), #endif #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) - {CMOD_CONFIRM, "confirm"}, + KEYVALUE_ENTRY(CMOD_CONFIRM, "confirm"), #endif - {CMOD_HIDE, "hide"}, - {CMOD_KEEPALT, "keepalt"}, - {CMOD_KEEPJUMPS, "keepjumps"}, - {CMOD_KEEPMARKS, "keepmarks"}, - {CMOD_KEEPPATTERNS, "keeppatterns"}, - {CMOD_LOCKMARKS, "lockmarks"}, - {CMOD_NOSWAPFILE, "noswapfile"}, - {CMOD_UNSILENT, "unsilent"}, - {CMOD_NOAUTOCMD, "noautocmd"}, + KEYVALUE_ENTRY(CMOD_HIDE, "hide"), + KEYVALUE_ENTRY(CMOD_KEEPALT, "keepalt"), + KEYVALUE_ENTRY(CMOD_KEEPJUMPS, "keepjumps"), + KEYVALUE_ENTRY(CMOD_KEEPMARKS, "keepmarks"), + KEYVALUE_ENTRY(CMOD_KEEPPATTERNS, "keeppatterns"), + KEYVALUE_ENTRY(CMOD_LOCKMARKS, "lockmarks"), + KEYVALUE_ENTRY(CMOD_NOSWAPFILE, "noswapfile"), + KEYVALUE_ENTRY(CMOD_UNSILENT, "unsilent"), + KEYVALUE_ENTRY(CMOD_NOAUTOCMD, "noautocmd"), #ifdef HAVE_SANDBOX - {CMOD_SANDBOX, "sandbox"}, + KEYVALUE_ENTRY(CMOD_SANDBOX, "sandbox"), #endif - {CMOD_LEGACY, "legacy"}, - {0, NULL} + KEYVALUE_ENTRY(CMOD_LEGACY, "legacy") }; - result = quote ? 2 : 0; - if (buf != NULL) + if (quote) { - if (quote) - *buf++ = '"'; - *buf = '\0'; + ++buflen; + if (buf != NULL) + { + *buf = '"'; + *(buf + buflen) = NUL; + } } + else + if (buf != NULL) + *buf = NUL; // the modifiers that are simple flags - for (i = 0; mod_entries[i].name != NULL; ++i) - if (cmod->cmod_flags & mod_entries[i].flag) - result += add_cmd_modifier(buf, mod_entries[i].name, &multi_mods); + for (i = 0; i < (int)ARRAY_LENGTH(mod_entry_tab); ++i) + if (cmod->cmod_flags & mod_entry_tab[i].key) + buflen += add_cmd_modifier(buf, buflen, mod_entry_tab[i].value, mod_entry_tab[i].length, &multi_mods); // :silent if (cmod->cmod_flags & CMOD_SILENT) - result += add_cmd_modifier(buf, - (cmod->cmod_flags & CMOD_ERRSILENT) ? "silent!" - : "silent", &multi_mods); + { + if (cmod->cmod_flags & CMOD_ERRSILENT) + buflen += add_cmd_modifier(buf, buflen, "silent!", STRLEN_LITERAL("silent!"), &multi_mods); + else + buflen += add_cmd_modifier(buf, buflen, "silent", STRLEN_LITERAL("silent"), &multi_mods); + } + // :verbose if (cmod->cmod_verbose > 0) { int verbose_value = cmod->cmod_verbose - 1; if (verbose_value == 1) - result += add_cmd_modifier(buf, "verbose", &multi_mods); + buflen += add_cmd_modifier(buf, buflen, "verbose", STRLEN_LITERAL("verbose"), &multi_mods); else { char verbose_buf[NUMBUFLEN]; + size_t verbose_buflen; - sprintf(verbose_buf, "%dverbose", verbose_value); - result += add_cmd_modifier(buf, verbose_buf, &multi_mods); + verbose_buflen = vim_snprintf(verbose_buf, sizeof(verbose_buf), "%dverbose", verbose_value); + buflen += add_cmd_modifier(buf, buflen, verbose_buf, verbose_buflen, &multi_mods); } } + // flags from cmod->cmod_split - result += add_win_cmd_modifiers(buf, cmod, &multi_mods); + buflen += add_win_cmd_modifiers((buf == NULL) ? NULL : buf + buflen, cmod, &multi_mods); - if (quote && buf != NULL) + if (quote) { - buf += result - 2; - *buf = '"'; + if (buf == NULL) + ++buflen; + else + { + *(buf + buflen) = '"'; + ++buflen; + *(buf + buflen) = NUL; + } } - return result; + + return buflen; } /* @@ -1754,15 +1841,14 @@ uc_check_code( case ct_RANGE: case ct_COUNT: { - char num_buf[20]; + char num_buf[NUMBUFLEN]; long num = (type == ct_LINE1) ? eap->line1 : (type == ct_LINE2) ? eap->line2 : (type == ct_RANGE) ? eap->addr_count : (eap->addr_count > 0) ? eap->line2 : cmd->uc_def; size_t num_len; - sprintf(num_buf, "%ld", num); - num_len = STRLEN(num_buf); + num_len = vim_snprintf(num_buf, sizeof(num_buf), "%ld", num); result = num_len; if (quote) diff --git a/src/userfunc.c b/src/userfunc.c index 7536234..5d16710 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -2212,6 +2212,49 @@ find_func_with_prefix(char_u *name, int sid) } /* + * Find a function by name, return pointer to it. + * The name may be a local script variable, VAR_FUNC. or it may be a fully + * qualified import name such as 'i_imp.FuncName'. + * + * When VAR_FUNC, the import might either direct or autoload. + * When 'i_imp.FuncName' it is direct, autoload is rewritten as i_imp#FuncName + * in f_call and subsequently found. + */ + static ufunc_T * +find_func_imported(char_u *name, int flags) +{ + ufunc_T *func = NULL; + char_u *dot = name; // Find a dot, '.', in the name + + // Either run into '.' or the end of the string + while (eval_isnamec(*dot)) + ++dot; + + if (*dot == '.') + { + imported_T *import = find_imported(name, dot - name, FALSE); + if (import != NULL) + func = find_func_with_sid(dot + 1, import->imp_sid); + } + else if (*dot == NUL) // looking at the entire string + { + hashtab_T *ht = get_script_local_ht(); + if (ht != NULL) + { + hashitem_T *hi = hash_find(ht, name); + if (!HASHITEM_EMPTY(hi)) + { + dictitem_T *di = HI2DI(hi); + if (di->di_tv.v_type == VAR_FUNC + && di->di_tv.vval.v_string != NULL) + func = find_func_even_dead(di->di_tv.vval.v_string, flags); + } + } + } + return func; +} + +/* * Find a function by name, return pointer to it in ufuncs. * When "flags" has FFED_IS_GLOBAL don't find script-local or imported * functions. @@ -2260,8 +2303,15 @@ find_func_even_dead(char_u *name, int flags) } // Find autoload function if this is an autoload script. - return find_func_with_prefix(name[0] == 's' && name[1] == ':' + func = find_func_with_prefix(name[0] == 's' && name[1] == ':' ? name + 2 : name, current_sctx.sc_sid); + if (func != NULL) + return func; + + // Find a script-local "VAR_FUNC" or i_"imp.Func", so vim9script). + if (in_vim9script()) + func = find_func_imported(name, flags); + return func; } /* @@ -4009,7 +4059,7 @@ theend: int call_simple_func( char_u *funcname, // name of the function - int len, // length of "name" or -1 to use strlen() + size_t len, // length of "name" typval_T *rettv) // return value goes here { int ret = FAIL; @@ -5503,6 +5553,47 @@ ex_function(exarg_T *eap) ga_clear_strings(&lines_to_free); } + int +get_func_arity(char_u *name, int *required, int *optional, int *varargs) +{ + ufunc_T *ufunc = NULL; + int argcount = 0; + int min_argcount = 0; + int idx; + + idx = find_internal_func(name); + if (idx >= 0) + { + internal_func_get_argcount(idx, &argcount, &min_argcount); + *varargs = FALSE; + } + else + { + char_u fname_buf[FLEN_FIXED + 1]; + char_u *tofree = NULL; + funcerror_T error = FCERR_NONE; + char_u *fname; + + // May need to translate <SNR>123_ to K_SNR. + fname = fname_trans_sid(name, fname_buf, &tofree, &error); + if (error == FCERR_NONE) + ufunc = find_func(fname, FALSE); + vim_free(tofree); + + if (ufunc == NULL) + return FAIL; + + argcount = ufunc->uf_args.ga_len; + min_argcount = ufunc->uf_args.ga_len - ufunc->uf_def_args.ga_len; + *varargs = has_varargs(ufunc); + } + + *required = min_argcount; + *optional = argcount - min_argcount; + + return OK; +} + /* * Find a function by name, including "<lambda>123". * Check for "profile" and "debug" arguments and set"compile_type". diff --git a/src/version.c b/src/version.c index 14a5922..314a320 100644 --- a/src/version.c +++ b/src/version.c @@ -705,6 +705,410 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 698, +/**/ + 697, +/**/ + 696, +/**/ + 695, +/**/ + 694, +/**/ + 693, +/**/ + 692, +/**/ + 691, +/**/ + 690, +/**/ + 689, +/**/ + 688, +/**/ + 687, +/**/ + 686, +/**/ + 685, +/**/ + 684, +/**/ + 683, +/**/ + 682, +/**/ + 681, +/**/ + 680, +/**/ + 679, +/**/ + 678, +/**/ + 677, +/**/ + 676, +/**/ + 675, +/**/ + 674, +/**/ + 673, +/**/ + 672, +/**/ + 671, +/**/ + 670, +/**/ + 669, +/**/ + 668, +/**/ + 667, +/**/ + 666, +/**/ + 665, +/**/ + 664, +/**/ + 663, +/**/ + 662, +/**/ + 661, +/**/ + 660, +/**/ + 659, +/**/ + 658, +/**/ + 657, +/**/ + 656, +/**/ + 655, +/**/ + 654, +/**/ + 653, +/**/ + 652, +/**/ + 651, +/**/ + 650, +/**/ + 649, +/**/ + 648, +/**/ + 647, +/**/ + 646, +/**/ + 645, +/**/ + 644, +/**/ + 643, +/**/ + 642, +/**/ + 641, +/**/ + 640, +/**/ + 639, +/**/ + 638, +/**/ + 637, +/**/ + 636, +/**/ + 635, +/**/ + 634, +/**/ + 633, +/**/ + 632, +/**/ + 631, +/**/ + 630, +/**/ + 629, +/**/ + 628, +/**/ + 627, +/**/ + 626, +/**/ + 625, +/**/ + 624, +/**/ + 623, +/**/ + 622, +/**/ + 621, +/**/ + 620, +/**/ + 619, +/**/ + 618, +/**/ + 617, +/**/ + 616, +/**/ + 615, +/**/ + 614, +/**/ + 613, +/**/ + 612, +/**/ + 611, +/**/ + 610, +/**/ + 609, +/**/ + 608, +/**/ + 607, +/**/ + 606, +/**/ + 605, +/**/ + 604, +/**/ + 603, +/**/ + 602, +/**/ + 601, +/**/ + 600, +/**/ + 599, +/**/ + 598, +/**/ + 597, +/**/ + 596, +/**/ + 595, +/**/ + 594, +/**/ + 593, +/**/ + 592, +/**/ + 591, +/**/ + 590, +/**/ + 589, +/**/ + 588, +/**/ + 587, +/**/ + 586, +/**/ + 585, +/**/ + 584, +/**/ + 583, +/**/ + 582, +/**/ + 581, +/**/ + 580, +/**/ + 579, +/**/ + 578, +/**/ + 577, +/**/ + 576, +/**/ + 575, +/**/ + 574, +/**/ + 573, +/**/ + 572, +/**/ + 571, +/**/ + 570, +/**/ + 569, +/**/ + 568, +/**/ + 567, +/**/ + 566, +/**/ + 565, +/**/ + 564, +/**/ + 563, +/**/ + 562, +/**/ + 561, +/**/ + 560, +/**/ + 559, +/**/ + 558, +/**/ + 557, +/**/ + 556, +/**/ + 555, +/**/ + 554, +/**/ + 553, +/**/ + 552, +/**/ + 551, +/**/ + 550, +/**/ + 549, +/**/ + 548, +/**/ + 547, +/**/ + 546, +/**/ + 545, +/**/ + 544, +/**/ + 543, +/**/ + 542, +/**/ + 541, +/**/ + 540, +/**/ + 539, +/**/ + 538, +/**/ + 537, +/**/ + 536, +/**/ + 535, +/**/ + 534, +/**/ + 533, +/**/ + 532, +/**/ + 531, +/**/ + 530, +/**/ + 529, +/**/ + 528, +/**/ + 527, +/**/ + 526, +/**/ + 525, +/**/ + 524, +/**/ + 523, +/**/ + 522, +/**/ + 521, +/**/ + 520, +/**/ + 519, +/**/ + 518, +/**/ + 517, +/**/ + 516, +/**/ + 515, +/**/ + 514, +/**/ + 513, +/**/ + 512, +/**/ + 511, +/**/ + 510, +/**/ + 509, +/**/ + 508, +/**/ + 507, +/**/ + 506, +/**/ + 505, +/**/ + 504, +/**/ + 503, +/**/ + 502, +/**/ + 501, +/**/ + 500, +/**/ + 499, +/**/ + 498, +/**/ + 497, +/**/ 496, /**/ 495, @@ -598,7 +598,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); # ifdef bindtextdomain # undef bindtextdomain # endif -# define bindtextdomain(x, y) // empty +# define bindtextdomain(x, y) "" # ifdef bind_textdomain_codeset # undef bind_textdomain_codeset # endif @@ -843,6 +843,8 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define EXPAND_ARGOPT 56 #define EXPAND_TERMINALOPT 57 #define EXPAND_KEYMAP 58 +#define EXPAND_DIRS_IN_CDPATH 59 + // Values for exmode_active (0 is no exmode) #define EXMODE_NORMAL 1 @@ -898,6 +900,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define EW_DODOT 0x4000 // also files starting with a dot #define EW_EMPTYOK 0x8000 // no matches is not an error #define EW_NOTENV 0x10000 // do not expand environment variables +#define EW_CDPATH 0x20000 // search in 'cdpath' too // Flags for find_file_*() functions. #define FINDFILE_FILE 0 // only files @@ -1074,6 +1077,8 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); // Values for flags argument of do_buffer() #define DOBUF_FORCEIT 1 // :cmd! #define DOBUF_NOPOPUP 2 // skip popup window buffers +#define DOBUF_SKIPHELP 4 // skip or keep help buffers depending on b_help of the + // starting buffer // Values for sub_cmd and which_pat argument for search_regcomp() // Also used for which_pat argument for searchit() @@ -1361,6 +1366,7 @@ enum auto_event EVENT_CURSORHOLD, // cursor in same position for a while EVENT_CURSORHOLDI, // idem, in Insert mode EVENT_CURSORMOVED, // cursor was moved + EVENT_CURSORMOVEDC, // cursor was moved in Command line mode EVENT_CURSORMOVEDI, // cursor was moved in Insert mode EVENT_DIFFUPDATED, // after diffs were updated EVENT_DIRCHANGED, // after user changed directory @@ -1394,6 +1400,7 @@ enum auto_event EVENT_INSERTENTER, // when entering Insert mode EVENT_INSERTLEAVEPRE, // just before leaving Insert mode EVENT_INSERTLEAVE, // just after leaving Insert mode + EVENT_KEYINPUTPRE, // before key input EVENT_MENUPOPUP, // just before popup menu is displayed EVENT_MODECHANGED, // after changing the mode EVENT_OPTIONSET, // option was set @@ -1762,6 +1769,7 @@ void *vim_memset(void *, int, size_t); # define MB_STRICMP(d, s) mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL) # define MB_STRNICMP(d, s, n) mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n)) +# define MB_STRNICMP2(d, s, n1, n2) mb_strnicmp2((char_u *)(d), (char_u *)(s), (n1), (n2)) #define STRCAT(d, s) strcat((char *)(d), (char *)(s)) #define STRNCAT(d, s, n) strncat((char *)(d), (char *)(s), (size_t)(n)) @@ -238,8 +238,9 @@ typedef struct { // arguments to ISN_METHODCALL typedef struct { class_T *cmf_itf; // interface used - int cmf_idx; // index in "def_functions" for ISN_DCALL + int cmf_idx; // index in "def_functions" for ISN_METHODCALL int cmf_argcount; // number of arguments on top of stack + int cmf_is_super; // doing "super.Func", use cmf_itf, not cmf_idx } cmfunc_T; // arguments to ISN_PCALL diff --git a/src/vim9class.c b/src/vim9class.c index f66aa68..d8813c6 100644 --- a/src/vim9class.c +++ b/src/vim9class.c @@ -1280,6 +1280,7 @@ add_class_members(class_T *cl, exarg_T *eap, garray_T *type_list_gap) tv->v_type = m->ocm_type->tt_type; tv->vval.v_string = NULL; } + set_tv_type(tv, m->ocm_type); if (m->ocm_flags & OCMFLAG_CONST) item_lock(tv, DICT_MAXNEST, TRUE, TRUE); } @@ -2664,7 +2665,7 @@ typealias_unref(typealias_T *ta) * Handle ":type". Create an alias for a type specification. */ void -ex_type(exarg_T *eap UNUSED) +ex_type(exarg_T *eap) { char_u *arg = eap->arg; @@ -3100,7 +3101,7 @@ class_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx) { ret_m = m; ret_idx = i; - break; + break; } } if (idx != NULL) @@ -3183,11 +3184,11 @@ object_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx) } } else if (STRCMP(name, m->ocm_name) == 0) - { + { ret_m = m; ret_idx = i; - break; - } + break; + } } if (idx != NULL) *idx = ret_idx; @@ -3683,7 +3684,7 @@ method_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len) } else semsg(_(e_method_not_found_on_class_str_str), method_name, - cl->class_name); + cl->class_name); vim_free(method_name); } @@ -3842,7 +3843,38 @@ object_len(object_T *obj) } /* - * Return a textual representation of object "obj" + * Return TRUE when two objects have exactly the same values. + */ + int +object_equal( + object_T *o1, + object_T *o2, + int ic) // ignore case for strings +{ + class_T *cl1, *cl2; + + if (o1 == o2) + return TRUE; + if (o1 == NULL || o2 == NULL) + return FALSE; + + cl1 = o1->obj_class; + cl2 = o2->obj_class; + + if (cl1 != cl2 || cl1 == NULL || cl2 == NULL) + return FALSE; + + for (int i = 0; i < cl1->class_obj_member_count; ++i) + if (!tv_equal((typval_T *)(o1 + 1) + i, (typval_T *)(o2 + 1) + i, ic)) + return FALSE; + + return TRUE; +} + +/* + * Return a textual representation of object "obj". + * "obj" must not be NULL. + * May return NULL. */ char_u * object2string( @@ -3859,47 +3891,58 @@ object2string( == OK && rettv.vval.v_string != NULL) return rettv.vval.v_string; + + int ok = OK; + class_T *cl = obj->obj_class; + garray_T ga; + ga_init2(&ga, 1, 50); + + if (cl != NULL && IS_ENUM(cl)) + { + ga_concat(&ga, (char_u *)"enum "); + ga_concat(&ga, cl->class_name); + char_u *enum_name = ((typval_T *)(obj + 1))->vval.v_string; + ga_concat(&ga, (char_u *)"."); + ga_concat(&ga, enum_name); + } else { - garray_T ga; - ga_init2(&ga, 1, 50); - - class_T *cl = obj == NULL ? NULL : obj->obj_class; - if (cl != NULL && IS_ENUM(cl)) - { - ga_concat(&ga, (char_u *)"enum "); - ga_concat(&ga, cl->class_name); - char_u *enum_name = ((typval_T *)(obj + 1))->vval.v_string; - ga_concat(&ga, (char_u *)"."); - ga_concat(&ga, enum_name); - } - else - { - ga_concat(&ga, (char_u *)"object of "); - ga_concat(&ga, cl == NULL ? (char_u *)"[unknown]" - : cl->class_name); - } - if (cl != NULL) - { - ga_concat(&ga, (char_u *)" {"); - for (int i = 0; i < cl->class_obj_member_count; ++i) + ga_concat(&ga, (char_u *)"object of "); + ga_concat(&ga, cl == NULL ? (char_u *)"[unknown]" + : cl->class_name); + } + if (cl != NULL) + { + ga_concat(&ga, (char_u *)" {"); + for (int i = 0; i < cl->class_obj_member_count; ++i) + { + if (i > 0) + ga_concat(&ga, (char_u *)", "); + ocmember_T *m = &cl->class_obj_members[i]; + ga_concat(&ga, m->ocm_name); + ga_concat(&ga, (char_u *)": "); + char_u *tf = NULL; + char_u *s = echo_string_core((typval_T *)(obj + 1) + i, + &tf, numbuf, copyID, echo_style, + restore_copyID, composite_val); + if (s != NULL) + ga_concat(&ga, s); + vim_free(tf); + if (s == NULL || did_echo_string_emsg) { - if (i > 0) - ga_concat(&ga, (char_u *)", "); - ocmember_T *m = &cl->class_obj_members[i]; - ga_concat(&ga, m->ocm_name); - ga_concat(&ga, (char_u *)": "); - char_u *tf = NULL; - ga_concat(&ga, echo_string_core( - (typval_T *)(obj + 1) + i, - &tf, numbuf, copyID, echo_style, - restore_copyID, composite_val)); - vim_free(tf); + ok = FAIL; + break; } - ga_concat(&ga, (char_u *)"}"); + line_breakcheck(); } - return ga.ga_data; + ga_concat(&ga, (char_u *)"}"); + } + if (ok == FAIL) + { + vim_free(ga.ga_data); + return NULL; } + return (char_u *)ga.ga_data; } /* diff --git a/src/vim9cmds.c b/src/vim9cmds.c index 694bb33..c7fa60a 100644 --- a/src/vim9cmds.c +++ b/src/vim9cmds.c @@ -1639,7 +1639,7 @@ compile_try(char_u *arg, cctx_T *cctx) * Compile "catch {expr}". */ char_u * -compile_catch(char_u *arg, cctx_T *cctx UNUSED) +compile_catch(char_u *arg, cctx_T *cctx) { scope_T *scope = cctx->ctx_scope; garray_T *instr = &cctx->ctx_instr; @@ -1923,7 +1923,7 @@ compile_endtry(char_u *arg, cctx_T *cctx) * compile "throw {expr}" */ char_u * -compile_throw(char_u *arg, cctx_T *cctx UNUSED) +compile_throw(char_u *arg, cctx_T *cctx) { char_u *p = skipwhite(arg); diff --git a/src/vim9compile.c b/src/vim9compile.c index 8e6f6e2..ea305b7 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -522,6 +522,8 @@ use_typecheck(type_T *actual, type_T *expected) (actual->tt_member == &t_void) == (expected->tt_member == &t_void)))) return TRUE; + if (actual->tt_type == VAR_OBJECT && expected->tt_type == VAR_OBJECT) + return TRUE; if ((actual->tt_type == VAR_LIST || actual->tt_type == VAR_DICT) && actual->tt_type == expected->tt_type) // This takes care of a nested list or dict. @@ -3315,7 +3317,7 @@ obj_constructor_prologue(ufunc_T *ufunc, cctx_T *cctx) // the initialization expression type. m->ocm_type = type; } - else if (m->ocm_type->tt_type != type->tt_type) + else { // The type of the member initialization expression is // determined at run time. Add a runtime type check. @@ -3330,6 +3332,15 @@ obj_constructor_prologue(ufunc_T *ufunc, cctx_T *cctx) else push_default_value(cctx, m->ocm_type->tt_type, FALSE, NULL); + if ((m->ocm_type->tt_type == VAR_DICT + || m->ocm_type->tt_type == VAR_LIST) + && m->ocm_type->tt_member != NULL + && m->ocm_type->tt_member != &t_any + && m->ocm_type->tt_member != &t_unknown) + // Set the type in the list or dict, so that it can be checked, + // also in legacy script. + generate_SETTYPE(cctx, m->ocm_type); + generate_STORE_THIS(cctx, i); } diff --git a/src/vim9execute.c b/src/vim9execute.c index 3a3960a..f523e27 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2254,26 +2254,35 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx) { // Need to get the member index now that the class is known. object_T *obj = tv_dest->vval.v_object; - class_T *cl = obj->obj_class; - char_u *member = tv_idx->vval.v_string; - - int m_idx; - ocmember_T *m = object_member_lookup(cl, member, 0, &m_idx); - if (m != NULL) + if (obj == NULL) { - if (*member == '_') - { - emsg_var_cl_define(e_cannot_access_protected_variable_str, - m->ocm_name, 0, cl); - status = FAIL; - } - - lidx = m_idx; + emsg(_(e_using_null_object)); + status = FAIL; } else { - member_not_found_msg(cl, VAR_OBJECT, member, 0); - status = FAIL; + class_T *cl = obj->obj_class; + char_u *member = tv_idx->vval.v_string; + + int m_idx; + ocmember_T *m = object_member_lookup(cl, member, 0, &m_idx); + if (m != NULL) + { + if (*member == '_') + { + emsg_var_cl_define( + e_cannot_access_protected_variable_str, + m->ocm_name, 0, cl); + status = FAIL; + } + + lidx = m_idx; + } + else + { + member_not_found_msg(cl, VAR_OBJECT, member, 0); + status = FAIL; + } } } else if ((dest_type == VAR_LIST || dest_type == VAR_OBJECT) @@ -3567,7 +3576,10 @@ exec_instructions(ectx_T *ectx) p = tv_get_string_buf(tv, buf); } else + { + SOURCING_LNUM = iptr->isn_lnum; p = tv_stringify(tv, buf); + } len = (int)STRLEN(p); if (GA_GROW_FAILS(&ga, len + 2)) @@ -4380,15 +4392,31 @@ exec_instructions(ectx_T *ectx) object_required_error(tv); goto on_error; } + object_T *obj = tv->vval.v_object; - class_T *cl = obj->obj_class; + if (obj == NULL) + { + emsg(_(e_using_null_object)); + goto on_error; + } - // convert the interface index to the object index - int idx = object_index_from_itf_index(mfunc->cmf_itf, - TRUE, mfunc->cmf_idx, cl); + ufunc_T *ufunc; + if (mfunc->cmf_is_super) + // Doing "super.Func", use the specific ufunc. + ufunc = mfunc->cmf_itf->class_obj_methods[ + mfunc->cmf_idx]; + else + { + class_T *cl = obj->obj_class; - if (call_ufunc(cl->class_obj_methods[idx], NULL, - mfunc->cmf_argcount, ectx, NULL, NULL) == FAIL) + // convert the interface index to the object index + int idx = object_index_from_itf_index(mfunc->cmf_itf, + TRUE, mfunc->cmf_idx, cl); + ufunc = cl->class_obj_methods[idx]; + } + + if (call_ufunc(ufunc, NULL, mfunc->cmf_argcount, ectx, + NULL, NULL) == FAIL) goto on_error; } break; @@ -4536,12 +4564,21 @@ exec_instructions(ectx_T *ectx) tv = STACK_TV_BOT(-1); if (tv->v_type != VAR_OBJECT) { + SOURCING_LNUM = iptr->isn_lnum; object_required_error(tv); vim_free(pt); goto on_error; } object_T *obj = tv->vval.v_object; + if (obj == NULL) + { + SOURCING_LNUM = iptr->isn_lnum; + emsg(_(e_using_null_object)); + vim_free(pt); + goto on_error; + } + cl = obj->obj_class; // drop the value from the stack clear_tv(tv); diff --git a/src/vim9expr.c b/src/vim9expr.c index 8c412b8..cfdea7b 100644 --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -349,6 +349,11 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type) else { // type->tt_type == VAR_OBJECT: method call + // When compiling Func and doing "super.SomeFunc()", must be in the + // class context that defines Func. + if (is_super) + cl = cctx->ctx_ufunc->uf_defclass; + function_count = cl->class_obj_method_count; child_count = cl->class_obj_method_count_child; functions = cl->class_obj_methods; @@ -419,13 +424,13 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type) return generate_PCALL(cctx, argcount, name, ocm->ocm_type, TRUE); if (type->tt_type == VAR_OBJECT && (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED))) - return generate_CALL(cctx, ufunc, cl, fi, argcount); - return generate_CALL(cctx, ufunc, NULL, 0, argcount); + return generate_CALL(cctx, ufunc, cl, fi, argcount, is_super); + return generate_CALL(cctx, ufunc, NULL, 0, argcount, FALSE); } if (type->tt_type == VAR_OBJECT) { - ocmember_T *m = object_member_lookup(cl, name, len, &m_idx); + ocmember_T *m = object_member_lookup(cl, name, len, &m_idx); if (m_idx >= 0) { if (*name == '_' && !inside_class(cctx, cl)) @@ -1035,7 +1040,7 @@ compile_builtin_method_call(cctx_T *cctx, class_builtin_T builtin_method) ufunc_T *uf = class_get_builtin_method(type->tt_class, builtin_method, &method_idx); if (uf != NULL) - res = generate_CALL(cctx, uf, type->tt_class, method_idx, 0); + res = generate_CALL(cctx, uf, type->tt_class, method_idx, 0, FALSE); } return res; @@ -1238,7 +1243,7 @@ compile_call( { if (!func_is_global(ufunc)) { - res = generate_CALL(cctx, ufunc, NULL, 0, argcount); + res = generate_CALL(cctx, ufunc, NULL, 0, argcount, FALSE); goto theend; } if (!has_g_namespace @@ -1257,7 +1262,7 @@ compile_call( if (cctx->ctx_ufunc->uf_defclass == cl) { res = generate_CALL(cctx, cl->class_class_functions[mi], NULL, - 0, argcount); + 0, argcount, FALSE); } else { @@ -1285,7 +1290,7 @@ compile_call( // If we can find a global function by name generate the right call. if (ufunc != NULL) { - res = generate_CALL(cctx, ufunc, NULL, 0, argcount); + res = generate_CALL(cctx, ufunc, NULL, 0, argcount, FALSE); goto theend; } @@ -2836,12 +2841,13 @@ compile_expr8(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) type_T *actual; where_T where = WHERE_INIT; + where.wt_kind = WT_CAST; generate_ppconst(cctx, ppconst); actual = get_type_on_stack(cctx, 0); if (check_type_maybe(want_type, actual, FALSE, where) != OK) { - if (need_type(actual, want_type, FALSE, - -1, 0, cctx, FALSE, FALSE) == FAIL) + if (need_type_where(actual, want_type, FALSE, -1, where, cctx, FALSE, FALSE) + == FAIL) return FAIL; } } diff --git a/src/vim9instr.c b/src/vim9instr.c index ad8beb1..4368e3c 100644 --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -1805,6 +1805,8 @@ generate_BLOBAPPEND(cctx_T *cctx) * Generate an ISN_DCALL, ISN_UCALL or ISN_METHODCALL instruction. * When calling a method on an object, of which we know the interface only, * then "cl" is the interface and "mi" the method index on the interface. + * save is_super in the "isn->isn_arg"; it flags execution to use mfunc + * directly to determine ufunc. * Return FAIL if the number of arguments is wrong. */ int @@ -1813,7 +1815,8 @@ generate_CALL( ufunc_T *ufunc, class_T *cl, int mi, - int pushed_argcount) + int pushed_argcount, + int is_super) { isn_T *isn; int regular_args = ufunc->uf_args.ga_len; @@ -1898,6 +1901,7 @@ generate_CALL( ++cl->class_refcount; isn->isn_arg.mfunc->cmf_idx = mi; isn->isn_arg.mfunc->cmf_argcount = argcount; + isn->isn_arg.mfunc->cmf_is_super = is_super; } else if (isn->isn_type == ISN_DCALL) { diff --git a/src/vim9type.c b/src/vim9type.c index ffdf7fa..1f044d3 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -934,6 +934,7 @@ type_mismatch_where(type_T *expected, type_T *actual, where_T where) semsg(_(e_argument_nr_type_mismatch_expected_str_but_got_str_in_str), where.wt_index, typename1, typename2, where.wt_func_name); break; + case WT_CAST: case WT_UNKNOWN: if (where.wt_func_name == NULL) semsg(_(e_type_mismatch_expected_str_but_got_str), @@ -1090,7 +1091,15 @@ check_type_maybe( ret = FAIL; } else if (!class_instance_of(actual->tt_class, expected->tt_class)) - ret = FAIL; + { + // Check if this is an up-cast, if so we'll have to check the type at + // runtime. + if (where.wt_kind == WT_CAST && + class_instance_of(expected->tt_class, actual->tt_class)) + ret = MAYBE; + else + ret = FAIL; + } } if (ret == FAIL && give_msg) @@ -2129,12 +2138,13 @@ check_type_is_value(type_T *type) switch (type->tt_type) { case VAR_CLASS: - if (IS_ENUM(type->tt_class)) + if (type->tt_class != NULL && IS_ENUM(type->tt_class)) semsg(_(e_using_enum_as_value_str), type->tt_class->class_name); else semsg(_(e_using_class_as_value_str), - type->tt_class->class_name); + type->tt_class == NULL ? (char_u *)"" + : type->tt_class->class_name); return FAIL; case VAR_TYPEALIAS: diff --git a/src/viminfo.c b/src/viminfo.c index 540422c..11a2946 100644 --- a/src/viminfo.c +++ b/src/viminfo.c @@ -251,7 +251,7 @@ barline_writestring(FILE *fd, char_u *s, int remaining_start) viminfo_readstring( vir_T *virp, int off, // offset for virp->vir_line - int convert UNUSED) // convert the string + int convert) // convert the string { char_u *retval = NULL; char_u *s, *d; diff --git a/src/window.c b/src/window.c index 7322905..b2c90c7 100644 --- a/src/window.c +++ b/src/window.c @@ -1708,7 +1708,7 @@ win_count(void) int make_windows( int count, - int vertical UNUSED) // split windows vertically if TRUE + int vertical) // split windows vertically if TRUE { int maxcount; int todo; @@ -2511,7 +2511,7 @@ close_windows( for (wp = firstwin; wp != NULL && !ONE_WINDOW; ) { if (wp->w_buffer == buf && (!keep_curwin || wp != curwin) - && !(wp->w_closing || wp->w_buffer->b_locked > 0)) + && !(win_locked(wp) || wp->w_buffer->b_locked > 0)) { if (win_close(wp, FALSE) == FAIL) // If closing the window fails give up, to avoid looping @@ -2532,7 +2532,7 @@ close_windows( if (tp != curtab) FOR_ALL_WINDOWS_IN_TAB(tp, wp) if (wp->w_buffer == buf - && !(wp->w_closing || wp->w_buffer->b_locked > 0)) + && !(win_locked(wp) || wp->w_buffer->b_locked > 0)) { win_close_othertab(wp, FALSE, tp); @@ -2654,10 +2654,10 @@ win_close_buffer(win_T *win, int action, int abort_if_last) bufref_T bufref; set_bufref(&bufref, curbuf); - win->w_closing = TRUE; + win->w_locked = TRUE; close_buffer(win, win->w_buffer, action, abort_if_last, TRUE); if (win_valid_any_tab(win)) - win->w_closing = FALSE; + win->w_locked = FALSE; // Make sure curbuf is valid. It can become invalid if 'bufhidden' is // "wipe". if (!bufref_valid(&bufref)) @@ -2705,7 +2705,7 @@ win_close(win_T *win, int free_buf) if (window_layout_locked(CMD_close)) return FAIL; - if (win->w_closing || (win->w_buffer != NULL + if (win_locked(win) || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) return FAIL; // window is already being closed if (win_unlisted(win)) @@ -2754,19 +2754,19 @@ win_close(win_T *win, int free_buf) other_buffer = TRUE; if (!win_valid(win)) return FAIL; - win->w_closing = TRUE; + win->w_locked = TRUE; apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); if (!win_valid(win)) return FAIL; - win->w_closing = FALSE; + win->w_locked = FALSE; if (last_window()) return FAIL; } - win->w_closing = TRUE; + win->w_locked = TRUE; apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); if (!win_valid(win)) return FAIL; - win->w_closing = FALSE; + win->w_locked = FALSE; if (last_window()) return FAIL; #ifdef FEAT_EVAL @@ -3346,7 +3346,7 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) // Get here with win->w_buffer == NULL when win_close() detects the tab // page changed. - if (win->w_closing || (win->w_buffer != NULL + if (win_locked(win) || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) return; // window is already being closed @@ -3486,7 +3486,7 @@ win_free_all(void) win_T * winframe_remove( win_T *win, - int *dirp UNUSED, // set to 'v' or 'h' for direction if 'ea' + int *dirp, // set to 'v' or 'h' for direction if 'ea' tabpage_T *tp, // tab page "win" is in, NULL for current frame_T **unflat_altfr) // if not NULL, set to pointer of frame that got // the space, and it is not flattened @@ -3782,15 +3782,24 @@ win_altframe( static tabpage_T * alt_tabpage(void) { - tabpage_T *tp; + tabpage_T *tp = NULL; + int forward; - // Use the next tab page if possible. - if (curtab->tp_next != NULL) - return curtab->tp_next; + // Use the last accessed tab page, if possible. + if ((tcl_flags & TCL_USELAST) && valid_tabpage(lastused_tabpage)) + return lastused_tabpage; + + // Use the next tab page, if possible. + forward = curtab->tp_next != NULL && + ((tcl_flags & TCL_LEFT) == 0 || curtab == first_tabpage); + + if (forward) + tp = curtab->tp_next; + else + // Use the previous tab page. + for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next) + ; - // Find the last but one tab page. - for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next) - ; return tp; } @@ -4598,6 +4607,11 @@ free_tabpage(tabpage_T *tp) * It will edit the current buffer, like after ":split". * When "after" is 0 put it just after the current Tab page. * Otherwise put it just before tab page "after". + * + * Does not trigger WinNewPre, since the window structures + * are not completly setup yet and could cause dereferencing + * NULL pointers + * * Return FAIL or OK. */ int @@ -4631,8 +4645,6 @@ win_new_tabpage(int after) newtp->tp_localdir = (tp->tp_localdir == NULL) ? NULL : vim_strsave(tp->tp_localdir); - trigger_winnewpre(); - // Create a new empty window. if (win_alloc_firstwin(tp->tp_curwin) == OK) { @@ -4846,8 +4858,8 @@ tabpage_index(tabpage_T *ftp) */ static int leave_tabpage( - buf_T *new_curbuf UNUSED, // what is going to be the new curbuf, - // NULL if unknown + buf_T *new_curbuf, // what is going to be the new curbuf, + // NULL if unknown int trigger_leave_autocmds) { tabpage_T *tp = curtab; @@ -4899,7 +4911,7 @@ leave_tabpage( static void enter_tabpage( tabpage_T *tp, - buf_T *old_curbuf UNUSED, + buf_T *old_curbuf, int trigger_enter_autocmds, int trigger_leave_autocmds) { @@ -5828,10 +5840,7 @@ win_free( win_free_lsize(wp); for (i = 0; i < wp->w_tagstacklen; ++i) - { - vim_free(wp->w_tagstack[i].tagname); - vim_free(wp->w_tagstack[i].user_data); - } + tagstack_clear_entry(&wp->w_tagstack[i]); vim_free(wp->w_localdir); vim_free(wp->w_prevdir); @@ -7846,7 +7855,7 @@ get_win_number(win_T *wp, win_T *first_win) } int -get_tab_number(tabpage_T *tp UNUSED) +get_tab_number(tabpage_T *tp) { int i = 1; tabpage_T *t; @@ -7991,3 +8000,12 @@ get_last_winid(void) { return last_win_id; } + +/* + * Don't let autocommands close the given window + */ + int +win_locked(win_T *wp) +{ + return wp->w_locked; +} diff --git a/src/xxd/Make_ming.mak b/src/xxd/Make_ming.mak index 2d32261..e621e67 100644 --- a/src/xxd/Make_ming.mak +++ b/src/xxd/Make_ming.mak @@ -16,7 +16,7 @@ CC = gcc CFLAGS = -O2 -Wall -DWIN32 $(DEFINES) ifneq (sh.exe, $(SHELL)) -DEL = rm +DEL = rm -f else DEL = del endif diff --git a/src/xxd/Make_mvc.mak b/src/xxd/Make_mvc.mak index 0133d73..2361ab3 100644 --- a/src/xxd/Make_mvc.mak +++ b/src/xxd/Make_mvc.mak @@ -9,7 +9,7 @@ SUBSYSTEM = $(SUBSYSTEM),$(SUBSYSTEM_VER) xxd: xxd.exe xxd.exe: xxd.c - cl /nologo -DWIN32 xxd.c -link -subsystem:$(SUBSYSTEM) + cl /nologo /source-charset:utf-8 -DWIN32 xxd.c -link -subsystem:$(SUBSYSTEM) # This was for an older compiler # cl /nologo -DWIN32 xxd.c /link setargv.obj |