From dbf749bd5aaef6ea2d28bce081349785d174d96a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Mon, 16 Oct 2023 09:53:37 +0200 Subject: [PATCH 01/13] runtime: Fix more typos (#13354) * Fix more typos * Fix typos in ignored runtime/ directory Signed-off-by: Christian Brabandt --- runtime/autoload/netrw.vim | 4 ++-- runtime/autoload/phpcomplete.vim | 2 +- runtime/autoload/rustfmt.vim | 2 +- runtime/autoload/typeset.vim | 2 +- runtime/colors/README.txt | 4 ++-- runtime/indent/cdl.vim | 8 ++++---- runtime/indent/erlang.vim | 2 +- runtime/indent/julia.vim | 2 +- runtime/indent/krl.vim | 4 ++-- runtime/indent/rapid.vim | 2 +- runtime/indent/systemverilog.vim | 4 ++-- runtime/keymap/greek_utf-8.vim | 2 +- runtime/macros/maze/maze_mac | 2 +- runtime/macros/urm/README.txt | 2 +- runtime/makemenu.vim | 4 ++-- .../opt/editorconfig/autoload/editorconfig_core/ini.vim | 2 +- runtime/pack/dist/opt/termdebug/plugin/termdebug.vim | 2 +- runtime/synmenu.vim | 4 ++-- runtime/syntax/abap.vim | 2 +- runtime/syntax/asm68k.vim | 4 ++-- runtime/syntax/chill.vim | 2 +- runtime/syntax/debcontrol.vim | 2 +- runtime/syntax/nix.vim | 2 +- runtime/syntax/ora.vim | 2 +- runtime/syntax/po.vim | 2 +- runtime/syntax/ppd.vim | 4 ++-- runtime/syntax/spup.vim | 2 +- runtime/syntax/tsscl.vim | 2 +- runtime/syntax/zsh.vim | 2 +- src/errors.h | 2 +- src/option.c | 2 +- 31 files changed, 42 insertions(+), 42 deletions(-) diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim index 2358e2627b..33a2fdd897 100644 --- a/runtime/autoload/netrw.vim +++ b/runtime/autoload/netrw.vim @@ -1961,7 +1961,7 @@ endfun " Doing this means that netrw will not come up as having changed a " setting last when it really didn't actually change it. " -" Used by s:NetrwOptionsRestore() to restore each netrw-senstive setting +" Used by s:NetrwOptionsRestore() to restore each netrw-sensitive setting " keepvars are set up by s:NetrwOptionsSave fun! s:NetrwRestoreSetting(keepvar,setting) """ call Dfunc("s:NetrwRestoreSetting(a:keepvar<".a:keepvar."> a:setting<".a:setting.">)") @@ -5562,7 +5562,7 @@ fun! netrw#BrowseX(fname,remote) " cleanup: remove temporary file, " delete current buffer if success with handler, " return to prior buffer (directory listing) - " Feb 12, 2008: had to de-activiate removal of + " Feb 12, 2008: had to de-activate removal of " temporary file because it wasn't getting seen. " if remote == 1 && fname != a:fname "" call Decho("deleting temporary file<".fname.">",'~'.expand("")) diff --git a/runtime/autoload/phpcomplete.vim b/runtime/autoload/phpcomplete.vim index f9448cbd9b..5b4263ae45 100644 --- a/runtime/autoload/phpcomplete.vim +++ b/runtime/autoload/phpcomplete.vim @@ -2907,7 +2907,7 @@ endfor " builtin class information let g:php_builtin_object_functions = {} -" When completing for 'everyting imaginable' (no class context, not a +" When completing for 'everything imaginable' (no class context, not a " variable) we need a list of built-in classes in a format of {'classname':''} " for performance reasons we precompile this too let g:php_builtin_classnames = {} diff --git a/runtime/autoload/rustfmt.vim b/runtime/autoload/rustfmt.vim index 652e6af33a..8fd3858178 100644 --- a/runtime/autoload/rustfmt.vim +++ b/runtime/autoload/rustfmt.vim @@ -25,7 +25,7 @@ function! rustfmt#DetectVersion() silent let s:rustfmt_help = system(g:rustfmt_command . " --help") let s:rustfmt_unstable_features = s:rustfmt_help =~# "--unstable-features" - " Build a comparable rustfmt version varible out of its `--version` output: + " Build a comparable rustfmt version variable out of its `--version` output: silent let l:rustfmt_version_full = system(g:rustfmt_command . " --version") let l:rustfmt_version_list = matchlist(l:rustfmt_version_full, \ '\vrustfmt ([0-9]+[.][0-9]+[.][0-9]+)') diff --git a/runtime/autoload/typeset.vim b/runtime/autoload/typeset.vim index 35cf17ba87..a1a809221c 100644 --- a/runtime/autoload/typeset.vim +++ b/runtime/autoload/typeset.vim @@ -97,7 +97,7 @@ enddef # Public interface {{{ # When a TeX document is split into several source files, each source file -# may contain a "magic line" specifiying the "root" file, e.g.: +# may contain a "magic line" specifying the "root" file, e.g.: # # % !TEX root = main.tex # diff --git a/runtime/colors/README.txt b/runtime/colors/README.txt index e4af1b9a9c..f48c11e6fa 100644 --- a/runtime/colors/README.txt +++ b/runtime/colors/README.txt @@ -111,11 +111,11 @@ please check the following items: - Do not use hard coded escape sequences, these will not work in other terminals. Always use #RRGGBB for the GUI. -- When targetting 8-16 colors terminals, don't count on "darkblue" to be blue +- When targeting 8-16 colors terminals, don't count on "darkblue" to be blue and dark, or on "2" to be even vaguely reddish. Names are more portable than numbers, though. -- When targetting 256 colors terminals, prefer colors 16-255 to colors 0-15 +- When targeting 256 colors terminals, prefer colors 16-255 to colors 0-15 for the same reason. - Typographic attributes (bold, italic, underline, reverse, etc.) are not diff --git a/runtime/indent/cdl.vim b/runtime/indent/cdl.vim index 2c0fc7988e..da675698cf 100644 --- a/runtime/indent/cdl.vim +++ b/runtime/indent/cdl.vim @@ -21,7 +21,7 @@ endif " find out if an "...=..." expression is an assignment (or a conditional) " it scans 'line' first, and then the previous lines -fun! CdlAsignment(lnum, line) +fun! CdlAssignment(lnum, line) let f = -1 let lnum = a:lnum let line = a:line @@ -90,7 +90,7 @@ fun! CdlGetIndent(lnum) end end - " remove members [a] of [b]:[c]... (inicio remainds valid) + " remove members [a] of [b]:[c]... (inicio remains valid) let line = substitute(line, '\c\(\[[^]]*]\(\s*of\s*\|:\)*\)\+', ' ', 'g') while 1 " search for the next interesting element @@ -111,7 +111,7 @@ fun! CdlGetIndent(lnum) else " c == '=' " if it is an assignment increase indent if f == -1 " we don't know yet, find out - let f = CdlAsignment(lnum, strpart(line, 0, inicio)) + let f = CdlAssignment(lnum, strpart(line, 0, inicio)) end if f == 1 " formula increase it let ind = ind + shiftwidth() @@ -125,7 +125,7 @@ fun! CdlGetIndent(lnum) let ind = ind - shiftwidth() elseif match(thisline, '^\s*=') >= 0 if f == -1 " we don't know yet if is an assignment, find out - let f = CdlAsignment(lnum, "") + let f = CdlAssignment(lnum, "") end if f == 1 " formula increase it let ind = ind + shiftwidth() diff --git a/runtime/indent/erlang.vim b/runtime/indent/erlang.vim index 7aa38587a6..5682c31ef3 100644 --- a/runtime/indent/erlang.vim +++ b/runtime/indent/erlang.vim @@ -1324,7 +1324,7 @@ function! s:ErlangCalcIndent2(lnum, stack) " maybe A else " LTI " - " Note about Emacs compabitility {{{ + " Note about Emacs compatibility {{{ " " It would be fine to indent the examples above the following way: " diff --git a/runtime/indent/julia.vim b/runtime/indent/julia.vim index 36f39f6652..efc98a2851 100644 --- a/runtime/indent/julia.vim +++ b/runtime/indent/julia.vim @@ -310,7 +310,7 @@ function IsFunctionArgPar(lnum, c) endfunction function JumpToMatch(lnum, last_closed_bracket) - " we use the % command to skip back (tries to ues matchit if possible, + " we use the % command to skip back (tries to use matchit if possible, " otherwise resorts to vim's default, which is buggy but better than " nothing) call cursor(a:lnum, a:last_closed_bracket) diff --git a/runtime/indent/krl.vim b/runtime/indent/krl.vim index cc3cbd1abb..89f45356ba 100644 --- a/runtime/indent/krl.vim +++ b/runtime/indent/krl.vim @@ -41,7 +41,7 @@ function GetKrlIndent() abort let currentLine = getline(v:lnum) if currentLine =~? '\v^;(\s*(end)?fold>)@!' && !get(g:, 'krlCommentIndent', 0) " If current line has a ; in column 1 and is no fold, keep zero indent. - " This may be usefull if code is commented out at the first column. + " This may be useful if code is commented out at the first column. return 0 endif @@ -117,7 +117,7 @@ function s:KrlPreNoneBlank(lnum) abort let nPreNoneBlank = prevnonblank(a:lnum) while nPreNoneBlank > 0 && getline(nPreNoneBlank) =~? '\v^\s*(\&\w\+|;|continue>)' - " Previouse none blank line irrelevant. Look further aback. + " Previous none blank line irrelevant. Look further aback. let nPreNoneBlank = prevnonblank(nPreNoneBlank - 1) endwhile diff --git a/runtime/indent/rapid.vim b/runtime/indent/rapid.vim index 2c99bb2491..b1fa00b8cc 100644 --- a/runtime/indent/rapid.vim +++ b/runtime/indent/rapid.vim @@ -74,7 +74,7 @@ function s:GetRapidIndentIntern() abort if l:currentLine =~ '^!' && !get(g:,'rapidCommentIndent',0) " If current line is ! line comment, do not change indent - " This may be usefull if code is commented out at the first column. + " This may be useful if code is commented out at the first column. return 0 endif diff --git a/runtime/indent/systemverilog.vim b/runtime/indent/systemverilog.vim index a5f4d5b90d..42a05a03aa 100644 --- a/runtime/indent/systemverilog.vim +++ b/runtime/indent/systemverilog.vim @@ -78,10 +78,10 @@ function SystemVerilogIndent() " Multiple-line comment count if curr_line =~ '^\s*/\*' && curr_line !~ '/\*.\{-}\*/' let s:multiple_comment += 1 - if vverb | echom vverb_str "Start of multiple-line commnt" | endif + if vverb | echom vverb_str "Start of multiple-line comment" | endif elseif curr_line =~ '\*/\s*$' && curr_line !~ '/\*.\{-}\*/' let s:multiple_comment -= 1 - if vverb | echom vverb_str "End of multiple-line commnt" | endif + if vverb | echom vverb_str "End of multiple-line comment" | endif return ind endif " Maintain indentation during commenting. diff --git a/runtime/keymap/greek_utf-8.vim b/runtime/keymap/greek_utf-8.vim index 17564542d9..c6cc32563e 100644 --- a/runtime/keymap/greek_utf-8.vim +++ b/runtime/keymap/greek_utf-8.vim @@ -34,7 +34,7 @@ " without having to combine them with letters (usufull for grammarians " in particular) (especially for dasia and psiln we use ' for psili " (that is apostrophe) and ;' for dasia. This is done in order to -" preserve the posibility to write a plain < or >. +" preserve the possibility to write a plain < or >. " Ypogegrammeni is | following the character (the originally proposed " i after the character is problematic: can't write easily ai or vi) : diff --git a/runtime/macros/maze/maze_mac b/runtime/macros/maze/maze_mac index 621aeec2b7..b1e3487a95 100644 --- a/runtime/macros/maze/maze_mac +++ b/runtime/macros/maze/maze_mac @@ -190,7 +190,7 @@ map I G$?. ^GYKeDP0S2Gl " into the Macro register " GVJ - on bottom line, create a command to restore the current character " 0H - and save the command into the second Macro register -" `a@r - go back to the current position and exectute the macro to restore +" `a@r - go back to the current position and execute the macro to restore " the current character " @m - execute the action associated with this state " U - and repeat diff --git a/runtime/macros/urm/README.txt b/runtime/macros/urm/README.txt index a1ecc658ca..3995813689 100644 --- a/runtime/macros/urm/README.txt +++ b/runtime/macros/urm/README.txt @@ -10,7 +10,7 @@ in vim: :so urm.vim in vim: * (to load the registers and boot the URM-machine :-) in vim: g (for 'go') and watch the fun. Per default, 3 and 4 are multiplied. Watch the Program counter, it is - visible as a komma moving around. + visible as a comma moving around. This is a "standard URM" (Universal register machine) interpreter. The URM concept is used in theoretical computer science to aid in theorem proving. diff --git a/runtime/makemenu.vim b/runtime/makemenu.vim index 4de9d48233..0479f7ba7f 100644 --- a/runtime/makemenu.vim +++ b/runtime/makemenu.vim @@ -89,7 +89,7 @@ SynMenu AB.Assembly.PIC:pic SynMenu AB.Assembly.Turbo:tasm SynMenu AB.Assembly.VAX\ Macro\ Assembly:vmasm SynMenu AB.Assembly.Z-80:z8a -SynMenu AB.Assembly.xa\ 6502\ cross\ assember:a65 +SynMenu AB.Assembly.xa\ 6502\ cross\ assembler:a65 SynMenu AB.ASN\.1:asn SynMenu AB.Asterisk\ config:asterisk SynMenu AB.Asterisk\ voicemail\ config:asteriskvm @@ -327,7 +327,7 @@ SynMenu HIJK.Kivy:kivy SynMenu HIJK.KixTart:kix SynMenu L.Lace:lace -SynMenu L.LamdaProlog:lprolog +SynMenu L.LambdaProlog:lprolog SynMenu L.Latte:latte SynMenu L.Ld\ script:ld SynMenu L.LDAP.LDIF:ldif diff --git a/runtime/pack/dist/opt/editorconfig/autoload/editorconfig_core/ini.vim b/runtime/pack/dist/opt/editorconfig/autoload/editorconfig_core/ini.vim index 55d2dee4ea..73716969e7 100644 --- a/runtime/pack/dist/opt/editorconfig/autoload/editorconfig_core/ini.vim +++ b/runtime/pack/dist/opt/editorconfig/autoload/editorconfig_core/ini.vim @@ -1,6 +1,6 @@ " autoload/editorconfig_core/ini.vim: Config-file parser for " editorconfig-core-vimscript and editorconfig-vim. -" Modifed from the Python core's ini.py. +" Modified from the Python core's ini.py. " Copyright (c) 2012-2019 EditorConfig Team {{{2 " All rights reserved. diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim index 7d9b80f510..e6126ee6f3 100644 --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -1219,7 +1219,7 @@ func s:Run(args) call s:SendResumingCommand('-exec-run') endfunc -" :Frame - go to a specfic frame in the stack +" :Frame - go to a specific frame in the stack func s:Frame(arg) " Note: we explicit do not use mi's command " call s:SendCommand('-stack-select-frame "' . a:arg .'"') diff --git a/runtime/synmenu.vim b/runtime/synmenu.vim index 5251045a96..12cdcbdddf 100644 --- a/runtime/synmenu.vim +++ b/runtime/synmenu.vim @@ -73,7 +73,7 @@ an 50.10.440 &Syntax.AB.Assembly.PIC :cal SetSyn("pic") an 50.10.450 &Syntax.AB.Assembly.Turbo :cal SetSyn("tasm") an 50.10.460 &Syntax.AB.Assembly.VAX\ Macro\ Assembly :cal SetSyn("vmasm") an 50.10.470 &Syntax.AB.Assembly.Z-80 :cal SetSyn("z8a") -an 50.10.480 &Syntax.AB.Assembly.xa\ 6502\ cross\ assember :cal SetSyn("a65") +an 50.10.480 &Syntax.AB.Assembly.xa\ 6502\ cross\ assembler :cal SetSyn("a65") an 50.10.490 &Syntax.AB.ASN\.1 :cal SetSyn("asn") an 50.10.500 &Syntax.AB.Asterisk\ config :cal SetSyn("asterisk") an 50.10.510 &Syntax.AB.Asterisk\ voicemail\ config :cal SetSyn("asteriskvm") @@ -303,7 +303,7 @@ an 50.50.710 &Syntax.HIJK.Kimwitu++ :cal SetSyn("kwt") an 50.50.720 &Syntax.HIJK.Kivy :cal SetSyn("kivy") an 50.50.730 &Syntax.HIJK.KixTart :cal SetSyn("kix") an 50.60.100 &Syntax.L.Lace :cal SetSyn("lace") -an 50.60.110 &Syntax.L.LamdaProlog :cal SetSyn("lprolog") +an 50.60.110 &Syntax.L.LambdaProlog :cal SetSyn("lprolog") an 50.60.120 &Syntax.L.Latte :cal SetSyn("latte") an 50.60.130 &Syntax.L.Ld\ script :cal SetSyn("ld") an 50.60.140 &Syntax.L.LDAP.LDIF :cal SetSyn("ldif") diff --git a/runtime/syntax/abap.vim b/runtime/syntax/abap.vim index e48dfc3603..627e51504a 100644 --- a/runtime/syntax/abap.vim +++ b/runtime/syntax/abap.vim @@ -122,7 +122,7 @@ syn keyword abapStatement TABLES TIMES TRANSFER TRANSLATE TRY TYPE TYPES syn keyword abapStatement UNASSIGN ULINE UNPACK UPDATE syn keyword abapStatement WHEN WHILE WINDOW WRITE -" More statemets +" More statements syn keyword abapStatement LINES syn keyword abapStatement INTO GROUP BY HAVING ORDER BY SINGLE syn keyword abapStatement APPENDING CORRESPONDING FIELDS OF TABLE diff --git a/runtime/syntax/asm68k.vim b/runtime/syntax/asm68k.vim index e13dfe6389..104887d026 100644 --- a/runtime/syntax/asm68k.vim +++ b/runtime/syntax/asm68k.vim @@ -4,7 +4,7 @@ " Last change: 2001 May 01 " " This is incomplete. In particular, support for 68020 and -" up and 68851/68881 co-processors is partial or non-existant. +" up and 68851/68881 co-processors is partial or non-existent. " Feel free to contribute... " @@ -220,7 +220,7 @@ syn match asm68kOperator "<>" " inequality syn match asm68kOperator "=" " must be before other ops containing '=' syn match asm68kOperator ">=" syn match asm68kOperator "<=" -syn match asm68kOperator "==" " operand existance - used in macro definitions +syn match asm68kOperator "==" " operand existence - used in macro definitions " Condition code style operators syn match asm68kOperator "<[CV][CS]>" diff --git a/runtime/syntax/chill.vim b/runtime/syntax/chill.vim index f3c66c2b4d..b95df68bc8 100644 --- a/runtime/syntax/chill.vim +++ b/runtime/syntax/chill.vim @@ -24,7 +24,7 @@ syn keyword chillLogical NOT not syn keyword chillRepeat while WHILE for FOR do DO od OD TO to syn keyword chillProcess START start STACKSIZE stacksize PRIORITY priority THIS this STOP stop syn keyword chillBlock PROC proc PROCESS process -syn keyword chillSignal RECEIVE receive SEND send NONPERSISTENT nonpersistent PERSISTENT peristent SET set EVER ever +syn keyword chillSignal RECEIVE receive SEND send NONPERSISTENT nonpersistent PERSISTENT persistent SET set EVER ever syn keyword chillTodo contained TODO FIXME XXX diff --git a/runtime/syntax/debcontrol.vim b/runtime/syntax/debcontrol.vim index c79b702f92..af78ebc3ae 100644 --- a/runtime/syntax/debcontrol.vim +++ b/runtime/syntax/debcontrol.vim @@ -22,7 +22,7 @@ syn iskeyword @,48-57,- " Everything that is not explicitly matched by the rules below syn match debcontrolElse "^.*$" -" Common seperators +" Common separators syn match debControlComma ",[ \t]*" syn match debControlSpace "[ \t]" diff --git a/runtime/syntax/nix.vim b/runtime/syntax/nix.vim index 671b269c04..ef52cddf46 100644 --- a/runtime/syntax/nix.vim +++ b/runtime/syntax/nix.vim @@ -99,7 +99,7 @@ syn match nixArgOperator '[a-zA-Z_][a-zA-Z0-9_'-]*\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{ " " "\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*" " -" It is also used throught the whole file and is marked with 'v's as well. +" It is also used throughout the whole file and is marked with 'v's as well. " " Fortunately the matching rules for function arguments are much simpler than " for real attribute sets, because we can stop when we hit the first ellipsis or diff --git a/runtime/syntax/ora.vim b/runtime/syntax/ora.vim index 99034793f2..ab091a2eee 100644 --- a/runtime/syntax/ora.vim +++ b/runtime/syntax/ora.vim @@ -449,7 +449,7 @@ hi def link oraString String "strings hi def link oraSpecial Special "special characters hi def link oraError Error "errors -hi def link oraParenError oraError "errors caused by mismatching parantheses +hi def link oraParenError oraError "errors caused by mismatching parentheses hi def link oraComment Comment "comments diff --git a/runtime/syntax/po.vim b/runtime/syntax/po.vim index 15d09b18bd..08d6baec27 100644 --- a/runtime/syntax/po.vim +++ b/runtime/syntax/po.vim @@ -42,7 +42,7 @@ syn match poHeaderItem "\(Project-Id-Version\|Report-Msgid-Bugs-To\|POT-Crea syn match poHeaderUndefined "\(PACKAGE VERSION\|YEAR-MO-DA HO:MI+ZONE\|FULL NAME \|LANGUAGE \|CHARSET\|ENCODING\|INTEGER\|EXPRESSION\)" contained syn match poCopyrightUnset "SOME DESCRIPTIVE TITLE\|FIRST AUTHOR , YEAR\|Copyright (C) YEAR Free Software Foundation, Inc\|YEAR THE PACKAGE\'S COPYRIGHT HOLDER\|PACKAGE" contained -" Translation comment block including: translator comment, automatic coments, flags and locations +" Translation comment block including: translator comment, automatic comments, flags and locations syn match poComment "^#.*$" syn keyword poFlagFuzzy fuzzy contained syn match poCommentTranslator "^# .*$" contains=poCopyrightUnset diff --git a/runtime/syntax/ppd.vim b/runtime/syntax/ppd.vim index da67e1f39f..6bd57f34e5 100644 --- a/runtime/syntax/ppd.vim +++ b/runtime/syntax/ppd.vim @@ -15,7 +15,7 @@ syn match ppdDefine "\*[a-zA-Z0-9\-_]\+:" syn match ppdUI "\*[a-zA-Z]*\(Open\|Close\)UI" syn match ppdUIGroup "\*[a-zA-Z]*\(Open\|Close\)Group" syn match ppdGUIText "/.*:" -syn match ppdContraints "^*UIConstraints:" +syn match ppdConstraints "^*UIConstraints:" " Define the default highlighting. " Only when an item doesn't have highlighting yet @@ -27,7 +27,7 @@ hi def link ppdUI Function hi def link ppdUIGroup Function hi def link ppdDef String hi def link ppdGUIText Type -hi def link ppdContraints Special +hi def link ppdConstraints Special let b:current_syntax = "ppd" diff --git a/runtime/syntax/spup.vim b/runtime/syntax/spup.vim index 9284abf63f..222caa779e 100644 --- a/runtime/syntax/spup.vim +++ b/runtime/syntax/spup.vim @@ -29,7 +29,7 @@ set cpo&vim "let strict_subsections = 1 " highlight types usually found in DECLARE section -if !exists("hightlight_types") +if !exists("highlight_types") let highlight_types = 1 endif diff --git a/runtime/syntax/tsscl.vim b/runtime/syntax/tsscl.vim index fd2a5e2ba9..df804b2f88 100644 --- a/runtime/syntax/tsscl.vim +++ b/runtime/syntax/tsscl.vim @@ -22,7 +22,7 @@ syn case ignore " " -" Begin syntax definitions for tss geomtery file. +" Begin syntax definitions for tss geometry file. " " Load TSS geometry syntax file diff --git a/runtime/syntax/zsh.vim b/runtime/syntax/zsh.vim index 69671c59ca..084f8cdb41 100644 --- a/runtime/syntax/zsh.vim +++ b/runtime/syntax/zsh.vim @@ -88,7 +88,7 @@ syn match zshOperator '||\|&&\|;\|&!\=' syn match zshRedir '\d\=\(<<<\|<&\s*[0-9p-]\=\|<>\?\)' " >, >>, and variants. syn match zshRedir '\d\=\(>&\s*[0-9p-]\=\|&>>\?\|>>\?&\?\)[|!]\=' - " | and |&, but only if it's not preceeded or + " | and |&, but only if it's not preceded or " followed by a | to avoid matching ||. syn match zshRedir '|\@1 Date: Mon, 16 Oct 2023 09:57:43 +0200 Subject: [PATCH 02/13] patch 9.0.2033: gcc overflow-warning for f_resolve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: gcc overflow-warning for f_resolve Solution: use pointer p instead of pointer q[-1] Suppress the following warning: ``` filepath.c: In function ‘f_resolve’: filepath.c:2162:27: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 2162 | q[-1] = NUL; ``` Closes: #13352 closes: #13353 Signed-off-by: Christian Brabandt Co-authored-by: Ken Takata --- src/filepath.c | 2 +- src/version.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/filepath.c b/src/filepath.c index c30d9bf82b..1ea0623867 100644 --- a/src/filepath.c +++ b/src/filepath.c @@ -2159,7 +2159,7 @@ f_resolve(typval_T *argvars, typval_T *rettv) if (q > p && *q == NUL) { // Ignore trailing path separator. - q[-1] = NUL; + p[q - p - 1] = NUL; q = gettail(p); } if (q > p && !mch_isFullName(buf)) diff --git a/src/version.c b/src/version.c index 2e14a90bba..761cdd5e27 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2033, /**/ 2032, /**/ From 5a679b2263f597950f99c60a99d4d1a192e9f639 Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Mon, 16 Oct 2023 10:17:13 +0200 Subject: [PATCH 03/13] patch 9.0.2034: don't try to copy SMACK attribute, when none exist Problem: don't try to copy SMACK attribute, when none exist Solution: return early if SMACK extended attributes do not exist or if they are not supported closes: #1711 closes: #13348 Signed-off-by: Christian Brabandt --- src/os_unix.c | 5 +++++ src/version.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/os_unix.c b/src/os_unix.c index 237171b4fa..11448c5c62 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3047,6 +3047,11 @@ mch_copy_sec(char_u *from_file, char_u *to_file) if (from_file == NULL) return; + size = listxattr((char *)from_file, NULL, 0); + // not supported or no attributes to copy + if (errno == ENOTSUP || size == 0) + return; + for (index = 0 ; index < (int)(sizeof(smack_copied_attributes) / sizeof(smack_copied_attributes)[0]) ; index++) { diff --git a/src/version.c b/src/version.c index 761cdd5e27..695b0cd56e 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2034, /**/ 2033, /**/ From 8f4fb007e4d472b09ff6bed9ffa485e0c3093699 Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Tue, 17 Oct 2023 10:06:56 +0200 Subject: [PATCH 04/13] patch 9.0.2035: [security] use-after-free with wildmenu Problem: [security] use-after-free with wildmenu Solution: properly clean up the wildmenu when exiting Fix wildchar/wildmenu/pum memory corruption with special wildchar's Currently, using `wildchar=` or `wildchar=` can lead to a memory corruption if using wildmenu+pum, or wrong states if only using wildmenu. This is due to the code only using one single place inside the cmdline process loop to perform wild menu clean up (by checking `end_wildmenu`) but there are other odd situations where the loop could have exited and we need a post-loop clean up just to be sure. If the clean up was not done you would have a stale popup menu referring to invalid memory, or if not using popup menu, incorrect status line (if `laststatus=0`). For example, if you hit `` two times when it's wildchar, there's a hard-coded behavior to exit command-line as a failsafe for user, and if you hit `` it will also exit command-line, but the clean up code would not have hit because of specialized `` handling. Fix Ctrl-E / Ctrl-Y to not cancel/accept wildmenu if they are also used for 'wildchar'/'wildcharm'. Currently they don't behave properly, and also have potentially memory unsafe behavior as the logic is currently not accounting for this situation and try to do both. (Previous patch that addressed this: #11677) Also, correctly document Escape key behavior (double-hit it to escape) in wildchar docs as it's previously undocumented. In addition, block known invalid chars to be set in `wildchar` option, such as Ctrl-C and ``. This is just to make it clear to the user they shouldn't be set, and is not required for this bug fix. closes: #13361 Signed-off-by: Christian Brabandt Co-authored-by: Yee Cheng Chin --- runtime/doc/options.txt | 2 + src/ex_getln.c | 14 ++++- src/option.c | 15 ++++++ src/optiondefs.h | 4 +- src/proto/option.pro | 1 + src/testdir/dumps/Test_wildmenu_5.dump | 8 +++ src/testdir/dumps/Test_wildmenu_6.dump | 8 +++ ... => Test_wildmenu_pum_odd_wildchar_1.dump} | 0 .../Test_wildmenu_pum_odd_wildchar_2.dump | 10 ++++ .../Test_wildmenu_pum_odd_wildchar_3.dump | 10 ++++ src/testdir/test_cmdline.vim | 51 +++++++++++++++++-- src/testdir/test_options.vim | 5 ++ src/version.c | 2 + 13 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 src/testdir/dumps/Test_wildmenu_5.dump create mode 100644 src/testdir/dumps/Test_wildmenu_6.dump rename src/testdir/dumps/{Test_wildmenu_pum_clear_entries_1.dump => Test_wildmenu_pum_odd_wildchar_1.dump} (100%) create mode 100644 src/testdir/dumps/Test_wildmenu_pum_odd_wildchar_2.dump create mode 100644 src/testdir/dumps/Test_wildmenu_pum_odd_wildchar_3.dump diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 6f38bc02be..86a734f6e6 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -9253,6 +9253,8 @@ A jump table for the options with a short description can be found at |Q_op|. The character is not recognized when used inside a macro. See 'wildcharm' for that. Some keys will not work, such as CTRL-C, and Enter. + can be used, but hitting it twice in a row will still exit + command-line as a failsafe measure. Although 'wc' is a number option, you can set it to a special key: > :set wc= < NOTE: This option is set to the Vi default value when 'compatible' is diff --git a/src/ex_getln.c b/src/ex_getln.c index 5baffa77fb..711e08e886 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -1877,7 +1877,8 @@ getcmdline_int( if (p_wmnu) c = wildmenu_translate_key(&ccline, c, &xpc, did_wild_list); - if (cmdline_pum_active()) + int key_is_wc = (c == p_wc && KeyTyped) || c == p_wcm; + if (cmdline_pum_active() && !key_is_wc) { // Ctrl-Y: Accept the current selection and close the popup menu. // Ctrl-E: cancel the cmdline popup menu and return the original @@ -1897,7 +1898,7 @@ getcmdline_int( // 'wildcharm' or Ctrl-N or Ctrl-P or Ctrl-A or Ctrl-L). // If the popup menu is displayed, then PageDown and PageUp keys are // also used to navigate the menu. - end_wildmenu = (!(c == p_wc && KeyTyped) && c != p_wcm + end_wildmenu = (!key_is_wc && c != Ctrl_N && c != Ctrl_P && c != Ctrl_A && c != Ctrl_L); end_wildmenu = end_wildmenu && (!cmdline_pum_active() || (c != K_PAGEDOWN && c != K_PAGEUP @@ -2504,6 +2505,15 @@ getcmdline_int( cmdmsg_rl = FALSE; #endif + // We could have reached here without having a chance to clean up wild menu + // if certain special keys like or were used as wildchar. Make + // sure to still clean up to avoid memory corruption. + if (cmdline_pum_active()) + cmdline_pum_remove(); + wildmenu_cleanup(&ccline); + did_wild_list = FALSE; + wim_index = 0; + ExpandCleanup(&xpc); ccline.xpc = NULL; diff --git a/src/option.c b/src/option.c index 53e956c8b1..180aca221d 100644 --- a/src/option.c +++ b/src/option.c @@ -4392,6 +4392,21 @@ did_set_weirdinvert(optset_T *args) return NULL; } +/* + * Process the new 'wildchar' / 'wildcharm' option value. + */ + char * +did_set_wildchar(optset_T *args) +{ + long c = *(long *)args->os_varp; + + // Don't allow key values that wouldn't work as wildchar. + if (c == Ctrl_C || c == '\n' || c == '\r' || c == K_KENTER) + return e_invalid_argument; + + return NULL; +} + /* * Process the new 'window' option value. */ diff --git a/src/optiondefs.h b/src/optiondefs.h index c4810e7d5d..d5887e1d41 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -2812,11 +2812,11 @@ static struct vimoption options[] = (char_u *)&p_ww, PV_NONE, did_set_whichwrap, expand_set_whichwrap, {(char_u *)"", (char_u *)"b,s"} SCTX_INIT}, {"wildchar", "wc", P_NUM|P_VIM, - (char_u *)&p_wc, PV_NONE, NULL, NULL, + (char_u *)&p_wc, PV_NONE, did_set_wildchar, NULL, {(char_u *)(long)Ctrl_E, (char_u *)(long)TAB} SCTX_INIT}, {"wildcharm", "wcm", P_NUM|P_VI_DEF, - (char_u *)&p_wcm, PV_NONE, NULL, NULL, + (char_u *)&p_wcm, PV_NONE, did_set_wildchar, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"wildignore", "wig", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, (char_u *)&p_wig, PV_NONE, NULL, NULL, diff --git a/src/proto/option.pro b/src/proto/option.pro index ec0013dbfa..effa81315b 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -81,6 +81,7 @@ char *did_set_undofile(optset_T *args); char *did_set_undolevels(optset_T *args); char *did_set_updatecount(optset_T *args); char *did_set_weirdinvert(optset_T *args); +char *did_set_wildchar(optset_T *args); char *did_set_window(optset_T *args); char *did_set_winheight_helpheight(optset_T *args); char *did_set_winminheight(optset_T *args); diff --git a/src/testdir/dumps/Test_wildmenu_5.dump b/src/testdir/dumps/Test_wildmenu_5.dump new file mode 100644 index 0000000000..ca9c5be126 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_5.dump @@ -0,0 +1,8 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|:+0#0000000&|v|i|m| > @69 diff --git a/src/testdir/dumps/Test_wildmenu_6.dump b/src/testdir/dumps/Test_wildmenu_6.dump new file mode 100644 index 0000000000..6b7ef83555 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_6.dump @@ -0,0 +1,8 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff --git a/src/testdir/dumps/Test_wildmenu_pum_clear_entries_1.dump b/src/testdir/dumps/Test_wildmenu_pum_odd_wildchar_1.dump similarity index 100% rename from src/testdir/dumps/Test_wildmenu_pum_clear_entries_1.dump rename to src/testdir/dumps/Test_wildmenu_pum_odd_wildchar_1.dump diff --git a/src/testdir/dumps/Test_wildmenu_pum_odd_wildchar_2.dump b/src/testdir/dumps/Test_wildmenu_pum_odd_wildchar_2.dump new file mode 100644 index 0000000000..2887895b60 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_odd_wildchar_2.dump @@ -0,0 +1,10 @@ +| +0#0000001#ffd7ff255|!| @14| +0#0000000#0000001| +0&#ffffff0@56 +| +0#0000001#e0e0e08|#| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56 +| +0#0000001#ffd7ff255|&| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56 +| +0#0000001#ffd7ff255|*| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56 +| +0#0000001#ffd7ff255|+@1| @13| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56 +| +0#0000001#ffd7ff255|-@1| @13| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56 +| +0#0000001#ffd7ff255|<| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56 +| +0#0000001#ffd7ff255|=| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56 +| +0#0000001#ffd7ff255|>| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56 +|:+0#0000000&|#> @72 diff --git a/src/testdir/dumps/Test_wildmenu_pum_odd_wildchar_3.dump b/src/testdir/dumps/Test_wildmenu_pum_odd_wildchar_3.dump new file mode 100644 index 0000000000..270a23344e --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_odd_wildchar_3.dump @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index ddfeba28ff..c285b087a4 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -171,6 +171,7 @@ func Test_wildmenu_screendump() [SCRIPT] call writefile(lines, 'XTest_wildmenu', 'D') + " Test simple wildmenu let buf = RunVimInTerminal('-S XTest_wildmenu', {'rows': 8}) call term_sendkeys(buf, ":vim\") call VerifyScreenDump(buf, 'Test_wildmenu_1', {}) @@ -181,9 +182,23 @@ func Test_wildmenu_screendump() call term_sendkeys(buf, "\") call VerifyScreenDump(buf, 'Test_wildmenu_3', {}) + " Looped back to the original value call term_sendkeys(buf, "\\") call VerifyScreenDump(buf, 'Test_wildmenu_4', {}) + + " Test that the wild menu is cleared properly + call term_sendkeys(buf, " ") + call VerifyScreenDump(buf, 'Test_wildmenu_5', {}) + + " Test that a different wildchar still works + call term_sendkeys(buf, "\:set wildchar=\") + call term_sendkeys(buf, ":vim\") + call VerifyScreenDump(buf, 'Test_wildmenu_1', {}) + + " Double- is a hard-coded method to escape while wildchar=. Make + " sure clean up is properly done in edge case like this. call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_6', {}) " clean up call StopVimInTerminal(buf) @@ -2636,10 +2651,11 @@ func Test_wildmenu_pum_from_terminal() call StopVimInTerminal(buf) endfunc -func Test_wildmenu_pum_clear_entries() +func Test_wildmenu_pum_odd_wildchar() CheckRunVimInTerminal - " This was using freed memory. Run in a terminal to get the pum to update. + " Test odd wildchar interactions with pum. Make sure they behave properly + " and don't lead to memory corruption due to improperly cleaned up memory. let lines =<< trim END set wildoptions=pum set wildchar= @@ -2647,10 +2663,35 @@ func Test_wildmenu_pum_clear_entries() call writefile(lines, 'XwildmenuTest', 'D') let buf = RunVimInTerminal('-S XwildmenuTest', #{rows: 10}) - call term_sendkeys(buf, ":\\") - call VerifyScreenDump(buf, 'Test_wildmenu_pum_clear_entries_1', {}) + call term_sendkeys(buf, ":\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_1', {}) + + " being a wildchar takes priority over its original functionality + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_2', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_3', {}) - set wildoptions& wildchar& + " Escape key can be wildchar too. Double- is hard-coded to escape + " command-line, and we need to make sure to clean up properly. + call term_sendkeys(buf, ":set wildchar=\") + call term_sendkeys(buf, ":\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_1', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_3', {}) + + " can also be wildchar. however will still escape cmdline + " and we again need to make sure we clean up properly. + call term_sendkeys(buf, ":set wildchar=\") + call term_sendkeys(buf, ":\\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_1', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_3', {}) + + call StopVimInTerminal(buf) endfunc " Test for completion after a :substitute command followed by a pipe (|) diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim index ba0808956d..6b2b7482a7 100644 --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -228,6 +228,11 @@ func Test_keymap_valid() call assert_fails(":set kmp=trunc\x00name", "trunc") endfunc +func Test_wildchar_valid() + call assert_fails("set wildchar=", "E474:") + call assert_fails("set wildcharm=", "E474:") +endfunc + func Check_dir_option(name) " Check that it's possible to set the option. exe 'set ' . a:name . '=/usr/share/dict/words' diff --git a/src/version.c b/src/version.c index 695b0cd56e..6f39f950f8 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2035, /**/ 2034, /**/ From 396058acd0cc66e5071d052e03d2067b134952af Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Tue, 17 Oct 2023 10:38:11 +0200 Subject: [PATCH 05/13] patch 9.0.2036: if_python: rework python3.12 build dependency Problem: if_python: rework python3.12 build dependency (after 9.0.1996) Solution: use PyTuple_Size instead of inlining the Py_SIZE into the Vim code base Use a simpler fix for Python 3.12 build issues Python 3.12 introduced link dependencies to their `Py_SIZE()` inline function, which #13290 fixed by copying the inline function to Vim's Python binding code. This works but it's fragile, as a future update may change the implementation of `Py_SIZE` and there is no way for us to know. The reason we need `Py_SIZE` to begin with is that we use `PyTuple_GET_SIZE()` which calls that. Just fix it by mapping that to (confusingly similarly named) `PyTuple_Size()`, which we already do in the stable ABI implementation. There's a minor performance cost in that it's not inlined and it does error checking but that's fine as we only call this function rarely (in an error handler). related: #13290 closes: #13359 Signed-off-by: Christian Brabandt Co-authored-by: Yee Cheng Chin --- src/if_python3.c | 46 ++++++---------------------------------------- src/version.c | 2 ++ 2 files changed, 8 insertions(+), 40 deletions(-) diff --git a/src/if_python3.c b/src/if_python3.c index a177371720..c39f42a6c7 100644 --- a/src/if_python3.c +++ b/src/if_python3.c @@ -299,9 +299,6 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll # define PyNumber_Check (*py3_PyNumber_Check) # define PyNumber_Long (*py3_PyNumber_Long) # define PyBool_Type (*py3_PyBool_Type) -# if PY_VERSION_HEX >= 0x030c00b0 -# define PyLong_Type (*py3_PyLong_Type) -# endif # define PyErr_NewException py3_PyErr_NewException # ifdef Py_DEBUG # define _Py_NegativeRefcount py3__Py_NegativeRefcount @@ -501,9 +498,6 @@ static PyTypeObject* py3_PyStdPrinter_Type; static PyTypeObject* py3_PySlice_Type; static PyTypeObject* py3_PyFloat_Type; static PyTypeObject* py3_PyBool_Type; -# if PY_VERSION_HEX >= 0x030c00b0 -static PyTypeObject* py3_PyLong_Type; -# endif static int (*py3_PyNumber_Check)(PyObject *); static PyObject* (*py3_PyNumber_Long)(PyObject *); static PyObject* (*py3_PyErr_NewException)(char *name, PyObject *base, PyObject *dict); @@ -701,9 +695,6 @@ static struct {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type}, {"PyFloat_Type", (PYTHON_PROC*)&py3_PyFloat_Type}, {"PyBool_Type", (PYTHON_PROC*)&py3_PyBool_Type}, -# if PY_VERSION_HEX >= 0x030c00b0 - {"PyLong_Type", (PYTHON_PROC*)&py3_PyLong_Type}, -# endif {"PyNumber_Check", (PYTHON_PROC*)&py3_PyNumber_Check}, {"PyNumber_Long", (PYTHON_PROC*)&py3_PyNumber_Long}, {"PyErr_NewException", (PYTHON_PROC*)&py3_PyErr_NewException}, @@ -795,39 +786,14 @@ py3__PyObject_TypeCheck(PyObject *ob, PyTypeObject *type) # endif # if !defined(USE_LIMITED_API) && PY_VERSION_HEX >= 0x030c00b0 -// Py_SIZE() uses PyLong_Type and PyBool_Type starting from Python 3.12. -// We need to define our own Py_SIZE() to replace Py{Bool,Long}_Type with -// py3_Py{Bool,Long}_Type. -// We also need to redefine PyTuple_GET_SIZE() and PyList_GET_SIZE(), because -// they use Py_SIZE(). - static inline Py_ssize_t -py3_Py_SIZE(PyObject *ob) -{ - assert(ob->ob_type != &PyLong_Type); - assert(ob->ob_type != &PyBool_Type); - PyVarObject *var_ob = _PyVarObject_CAST(ob); - return var_ob->ob_size; -} -# undef Py_SIZE -# define Py_SIZE(ob) py3_Py_SIZE(_PyObject_CAST(ob)) - - static inline Py_ssize_t -py3_PyTuple_GET_SIZE(PyObject *op) -{ - PyTupleObject *tuple = _PyTuple_CAST(op); - return Py_SIZE(tuple); -} +// PyTuple_GET_SIZE/PyList_GET_SIZE are inlined functions that use Py_SIZE(), +// which started to introduce linkage dependency from Python 3.12. When we +// build Python in dynamic mode, we don't link against it in build time, and +// this would fail to build. Just use the non-inlined version instead. # undef PyTuple_GET_SIZE -# define PyTuple_GET_SIZE(op) py3_PyTuple_GET_SIZE(_PyObject_CAST(op)) - - static inline -Py_ssize_t py3_PyList_GET_SIZE(PyObject *op) -{ - PyListObject *list = _PyList_CAST(op); - return Py_SIZE(list); -} +# define PyTuple_GET_SIZE(o) PyTuple_Size(o) # undef PyList_GET_SIZE -# define PyList_GET_SIZE(op) py3_PyList_GET_SIZE(_PyObject_CAST(op)) +# define PyList_GET_SIZE(o) PyList_Size(o) # endif # ifdef MSWIN diff --git a/src/version.c b/src/version.c index 6f39f950f8..02441bceb2 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2036, /**/ 2035, /**/ From 209ec90b9b9bd948d76511c9cd2b17f47a97afe6 Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Tue, 17 Oct 2023 10:56:25 +0200 Subject: [PATCH 06/13] patch 9.0.2037: A few remaining cmdline completion issues with C-E/Y Problem: A few remaining cmdline completion issues with C-E/Y Solution: Fix cmdline completion fuzzy/Ctrl-E/Ctrl-Y/options when not used at the end Fix cmdline completion fuzzy/Ctrl-E/Ctrl-Y/options when not used at the end A few places in the cmdline completion code only works properly when the user hits Tab (or 'wildchar') at the end of the cmdline, even though it's supposed to work even in the middle of the line. For fuzzy search, `:e ++ff`, and `:set hl=`, fix completion code to make sure to use `xp_pattern_len` instead of assuming the entire `xp_pattern` is the search pattern (since it contains texts after the cursor). Fix Ctrl-E / Ctrl-Y to not jump to the end when canceling/accepting a wildmenu completion. Also, make them work even when not using `set wildoptions+=pum` as there is no drawback to doing so. (Related issue where this was brought up: #13331) closes: #13362 Signed-off-by: Christian Brabandt Co-authored-by: Yee Cheng Chin --- runtime/doc/index.txt | 4 +-- runtime/doc/options.txt | 8 +++--- src/cmdexpand.c | 2 +- src/ex_docmd.c | 3 +- src/ex_getln.c | 13 +++++++-- src/optionstr.c | 5 ++-- src/testdir/dumps/Test_wildmenu_pum_51.dump | 10 +++++++ src/testdir/dumps/Test_wildmenu_pum_52.dump | 10 +++++++ src/testdir/dumps/Test_wildmenu_pum_53.dump | 10 +++++++ src/testdir/test_cmdline.vim | 31 +++++++++++++++++++++ src/testdir/test_options.vim | 3 ++ src/version.c | 2 ++ 12 files changed, 88 insertions(+), 13 deletions(-) create mode 100644 src/testdir/dumps/Test_wildmenu_pum_51.dump create mode 100644 src/testdir/dumps/Test_wildmenu_pum_52.dump create mode 100644 src/testdir/dumps/Test_wildmenu_pum_53.dump diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index a9a8eec257..6f4b5d74db 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -1119,12 +1119,12 @@ commands in wildmenu mode (see 'wildmenu') select the previous match / move up to parent select the next match / move down to submenu move into submenu when doing menu completion + CTRL-E stop completion and go back to original text + CTRL-Y accept selected match and stop completion other stop completion and insert the typed character commands in wildmenu mode with 'wildoptions' set to "pum" - CTRL-E stop completion and go back to original text - CTRL-Y accept selected match and stop completion select a match several entries back select a match several entries forward diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 86a734f6e6..cdb4992a74 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -9323,6 +9323,10 @@ A jump table for the options with a short description can be found at |Q_op|. CTRL-N - go to the next entry - in menu completion, when the cursor is just after a dot: move into a submenu. + CTRL-E - end completion, go back to what was there before + selecting a match. + CTRL-Y - accept the currently selected match and stop + completion. When not using the popup menu for command line completion, the following keys have special meanings: @@ -9341,10 +9345,6 @@ A jump table for the options with a short description can be found at |Q_op|. parent directory or parent menu. - in filename/menu name completion: move into a subdirectory or submenu. - CTRL-E - end completion, go back to what was there before - selecting a match. - CTRL-Y - accept the currently selected match and stop - completion. This makes the menus accessible from the console |console-menus|. diff --git a/src/cmdexpand.c b/src/cmdexpand.c index d27e039443..8bccaa3bb0 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -260,7 +260,7 @@ nextwild( { if (cmdline_fuzzy_completion_supported(xp)) // If fuzzy matching, don't modify the search string - p1 = vim_strsave(xp->xp_pattern); + p1 = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len); else p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context); diff --git a/src/ex_docmd.c b/src/ex_docmd.c index f0c7aad7df..06837ac92c 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -5590,7 +5590,8 @@ expand_argopt( // Special handling of "ff" which acts as a short form of // "fileformat", as "ff" is not a substring of it. - if (STRCMP(xp->xp_pattern, "ff") == 0) + if (xp->xp_pattern_len == 2 + && STRNCMP(xp->xp_pattern, "ff", xp->xp_pattern_len) == 0) { *matches = ALLOC_MULT(char_u *, 1); if (*matches == NULL) diff --git a/src/ex_getln.c b/src/ex_getln.c index 711e08e886..9683e2ebd5 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -1599,7 +1599,7 @@ getcmdline_int( cmdline_info_T save_ccline; int did_save_ccline = FALSE; int cmdline_type; - int wild_type; + int wild_type = 0; // one recursion level deeper ++depth; @@ -1878,7 +1878,7 @@ getcmdline_int( c = wildmenu_translate_key(&ccline, c, &xpc, did_wild_list); int key_is_wc = (c == p_wc && KeyTyped) || c == p_wcm; - if (cmdline_pum_active() && !key_is_wc) + if ((cmdline_pum_active() || did_wild_list) && !key_is_wc) { // Ctrl-Y: Accept the current selection and close the popup menu. // Ctrl-E: cancel the cmdline popup menu and return the original @@ -1889,7 +1889,6 @@ getcmdline_int( if (nextwild(&xpc, wild_type, WILD_NO_BEEP, firstc != '@') == FAIL) break; - c = Ctrl_E; } } @@ -2016,6 +2015,14 @@ getcmdline_int( do_abbr = TRUE; // default: check for abbreviation + // If already used to cancel/accept wildmenu, don't process the key + // further. + if (wild_type == WILD_CANCEL || wild_type == WILD_APPLY) + { + wild_type = 0; + goto cmdline_not_changed; + } + /* * Big switch for a typed command line character. */ diff --git a/src/optionstr.c b/src/optionstr.c index 8458f2a4a4..b7cdcc4511 100644 --- a/src/optionstr.c +++ b/src/optionstr.c @@ -2582,12 +2582,13 @@ expand_set_highlight(optexpand_T *args, int *numMatches, char_u ***matches) if (*matches == NULL) return FAIL; - size_t pattern_len = STRLEN(xp->xp_pattern); + int pattern_len = xp->xp_pattern_len; for (i = 0; i < num_hl_modes; i++) { // Don't allow duplicates as these are unique flags - if (vim_strchr(xp->xp_pattern + 1, p_hl_mode_values[i]) != NULL) + char_u *dup = vim_strchr(xp->xp_pattern + 1, p_hl_mode_values[i]); + if (dup != NULL && (int)(dup - xp->xp_pattern) < pattern_len) continue; // ':' only works by itself, not with other flags. diff --git a/src/testdir/dumps/Test_wildmenu_pum_51.dump b/src/testdir/dumps/Test_wildmenu_pum_51.dump new file mode 100644 index 0000000000..d5ad45c14e --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_51.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @2| +0#0000001#e0e0e08|w|i|l|d|c|h|a|r| @6| +0#4040ff13#ffffff0@54 +|~| @2| +0#0000001#ffd7ff255|w|i|l|d|c|h|a|r|m| @5| +0#4040ff13#ffffff0@54 +|:+0#0000000&|s|e|t| |w|i|l|d|c|h|a|r>z@1| @59 diff --git a/src/testdir/dumps/Test_wildmenu_pum_52.dump b/src/testdir/dumps/Test_wildmenu_pum_52.dump new file mode 100644 index 0000000000..81e59b6e88 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_52.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|:+0#0000000&|s|e|t| |w|i|l|d|c|h|a>z@1| @60 diff --git a/src/testdir/dumps/Test_wildmenu_pum_53.dump b/src/testdir/dumps/Test_wildmenu_pum_53.dump new file mode 100644 index 0000000000..5f61cdd3ce --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_53.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|:+0#0000000&|s|e|t| |w|i|l|d|c|h|a|r>z@1| @59 diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index c285b087a4..33ff606424 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -158,6 +158,13 @@ func Test_complete_wildmenu() call feedkeys(":sign \\\\\\\"\", 'tx') call assert_equal('"TestWildMenu', @:) + " Test for Ctrl-E/Ctrl-Y being able to cancel / accept a match + call feedkeys(":sign un zz\\\\\ yy\\"\", 'tx') + call assert_equal('"sign un yy zz', @:) + + call feedkeys(":sign un zz\\\\\\ yy\\"\", 'tx') + call assert_equal('"sign unplace yy zz', @:) + " cleanup %bwipe set nowildmenu @@ -1105,6 +1112,9 @@ func Test_cmdline_complete_argopt() call assert_equal('edit', getcompletion('read ++bin ++edi', 'cmdline')[0]) call assert_equal(['fileformat='], getcompletion('edit ++ff', 'cmdline')) + " Test ++ff in the middle of the cmdline + call feedkeys(":edit ++ff zz\\\\\\"\", 'xt') + call assert_equal("\"edit ++fileformat= zz", @:) call assert_equal('dos', getcompletion('write ++ff=d', 'cmdline')[0]) call assert_equal('mac', getcompletion('args ++fileformat=m', 'cmdline')[0]) @@ -2585,6 +2595,16 @@ func Test_wildmenu_pum() call term_sendkeys(buf, "\") call VerifyScreenDump(buf, 'Test_wildmenu_pum_50', {}) + " pressing to end completion should work in middle of the line too + call term_sendkeys(buf, "\:set wildchazz\\\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_51', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_52', {}) + + " pressing should select the current match and end completion + call term_sendkeys(buf, "\:set wildchazz\\\\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_53', {}) + call term_sendkeys(buf, "\\") call StopVimInTerminal(buf) endfunc @@ -3293,6 +3313,17 @@ func Test_fuzzy_completion_custom_func() set wildoptions& endfunc +" Test for fuzzy completion in the middle of a cmdline instead of at the end +func Test_fuzzy_completion_in_middle() + set wildoptions=fuzzy + call feedkeys(":set ildar wrap\\\\\\\\"\", 'tx') + call assert_equal("\"set wildchar wildcharm wrap", @:) + + call feedkeys(":args ++odng zz\\\\\\"\", 'tx') + call assert_equal("\"args ++encoding= zz", @:) + set wildoptions& +endfunc + " Test for :breakadd argument completion func Test_cmdline_complete_breakadd() call feedkeys(":breakadd \\\"\", 'tx') diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim index 6b2b7482a7..ef2d3bd4da 100644 --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -616,6 +616,9 @@ func Test_set_completion_string_values() \ {idx, val -> val != ':'}), \ '') call assert_equal([], getcompletion('set hl+=8'..hl_display_modes, 'cmdline')) + " Test completion in middle of the line + call feedkeys(":set hl=8b i\\\\\"\", 'xt') + call assert_equal("\"set hl=8bi i", @:) " " Test flag lists diff --git a/src/version.c b/src/version.c index 02441bceb2..438e9a0454 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2037, /**/ 2036, /**/ From f3eac695bfe3453fe2a8b980601c55835406f14b Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Tue, 17 Oct 2023 11:00:45 +0200 Subject: [PATCH 07/13] patch 9.0.2038: Vim9: object method funcref not cleaned up after use Problem: Vim9: object method funcref not cleaned up after use Solution: Clean up type stack after using object method funcref, remove now longer used ISN_DEFEROBJ instrunction closes: #13360 Signed-off-by: Christian Brabandt Co-authored-by: Yegappan Lakshmanan --- src/proto/vim9instr.pro | 2 +- src/testdir/test_vim9_class.vim | 252 ++++++++++++++++++++++++++ src/testdir/test_vim9_disassemble.vim | 2 +- src/version.c | 2 + src/vim9.h | 1 - src/vim9cmds.c | 14 +- src/vim9execute.c | 28 +-- src/vim9expr.c | 12 +- src/vim9instr.c | 8 +- 9 files changed, 276 insertions(+), 45 deletions(-) diff --git a/src/proto/vim9instr.pro b/src/proto/vim9instr.pro index a236b75612..58786273d0 100644 --- a/src/proto/vim9instr.pro +++ b/src/proto/vim9instr.pro @@ -62,7 +62,7 @@ int generate_CALL(cctx_T *cctx, ufunc_T *ufunc, class_T *cl, int mi, int pushed_ 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); -int generate_DEFER(cctx_T *cctx, int var_idx, int obj_method, int argcount); +int generate_DEFER(cctx_T *cctx, int var_idx, int argcount); int generate_STRINGMEMBER(cctx_T *cctx, char_u *name, size_t len); int generate_ECHO(cctx_T *cctx, int with_white, int count); int generate_MULT_EXPR(cctx_T *cctx, isntype_T isn_type, int count); diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index b9f2910205..8b08dc1b2d 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -8022,4 +8022,256 @@ def Test_class_member_funcref() v9.CheckSourceSuccess(lines) enddef +" Test for using object methods as popup callback functions +def Test_objmethod_popup_callback() + # Use the popup from the script level + var lines =<< trim END + vim9script + + class A + this.selection: number = -1 + this.filterkeys: list = [] + + def PopupFilter(id: number, key: string): bool + add(this.filterkeys, key) + return popup_filter_yesno(id, key) + enddef + + def PopupCb(id: number, result: number) + this.selection = result ? 100 : 200 + enddef + endclass + + var a = A.new() + feedkeys('', 'xt') + var winid = popup_create('Y/N?', + {filter: a.PopupFilter, callback: a.PopupCb}) + feedkeys('y', 'xt') + popup_close(winid) + assert_equal(100, a.selection) + assert_equal(['y'], a.filterkeys) + feedkeys('', 'xt') + winid = popup_create('Y/N?', + {filter: a.PopupFilter, callback: a.PopupCb}) + feedkeys('n', 'xt') + popup_close(winid) + assert_equal(200, a.selection) + assert_equal(['y', 'n'], a.filterkeys) + END + v9.CheckSourceSuccess(lines) + + # Use the popup from a def function + lines =<< trim END + vim9script + + class A + this.selection: number = -1 + this.filterkeys: list = [] + + def PopupFilter(id: number, key: string): bool + add(this.filterkeys, key) + return popup_filter_yesno(id, key) + enddef + + def PopupCb(id: number, result: number) + this.selection = result ? 100 : 200 + enddef + endclass + + def Foo() + var a = A.new() + feedkeys('', 'xt') + var winid = popup_create('Y/N?', + {filter: a.PopupFilter, callback: a.PopupCb}) + feedkeys('y', 'xt') + popup_close(winid) + assert_equal(100, a.selection) + assert_equal(['y'], a.filterkeys) + feedkeys('', 'xt') + winid = popup_create('Y/N?', + {filter: a.PopupFilter, callback: a.PopupCb}) + feedkeys('n', 'xt') + popup_close(winid) + assert_equal(200, a.selection) + assert_equal(['y', 'n'], a.filterkeys) + enddef + Foo() + END + v9.CheckSourceSuccess(lines) +enddef + +" Test for using class methods as popup callback functions +def Test_classmethod_popup_callback() + # Use the popup from the script level + var lines =<< trim END + vim9script + + class A + static selection: number = -1 + static filterkeys: list = [] + + static def PopupFilter(id: number, key: string): bool + add(filterkeys, key) + return popup_filter_yesno(id, key) + enddef + + static def PopupCb(id: number, result: number) + selection = result ? 100 : 200 + enddef + endclass + + feedkeys('', 'xt') + var winid = popup_create('Y/N?', + {filter: A.PopupFilter, callback: A.PopupCb}) + feedkeys('y', 'xt') + popup_close(winid) + assert_equal(100, A.selection) + assert_equal(['y'], A.filterkeys) + feedkeys('', 'xt') + winid = popup_create('Y/N?', + {filter: A.PopupFilter, callback: A.PopupCb}) + feedkeys('n', 'xt') + popup_close(winid) + assert_equal(200, A.selection) + assert_equal(['y', 'n'], A.filterkeys) + END + v9.CheckSourceSuccess(lines) + + # Use the popup from a def function + lines =<< trim END + vim9script + + class A + static selection: number = -1 + static filterkeys: list = [] + + static def PopupFilter(id: number, key: string): bool + add(filterkeys, key) + return popup_filter_yesno(id, key) + enddef + + static def PopupCb(id: number, result: number) + selection = result ? 100 : 200 + enddef + endclass + + def Foo() + feedkeys('', 'xt') + var winid = popup_create('Y/N?', + {filter: A.PopupFilter, callback: A.PopupCb}) + feedkeys('y', 'xt') + popup_close(winid) + assert_equal(100, A.selection) + assert_equal(['y'], A.filterkeys) + feedkeys('', 'xt') + winid = popup_create('Y/N?', + {filter: A.PopupFilter, callback: A.PopupCb}) + feedkeys('n', 'xt') + popup_close(winid) + assert_equal(200, A.selection) + assert_equal(['y', 'n'], A.filterkeys) + enddef + Foo() + END + v9.CheckSourceSuccess(lines) +enddef + +" Test for using an object method as a timer callback function +def Test_objmethod_timer_callback() + # Use the timer callback from script level + var lines =<< trim END + vim9script + + class A + this.timerTick: number = -1 + def TimerCb(timerID: number) + this.timerTick = 6 + enddef + endclass + + var a = A.new() + timer_start(0, a.TimerCb) + var maxWait = 5 + while maxWait > 0 && a.timerTick == -1 + :sleep 10m + maxWait -= 1 + endwhile + assert_equal(6, a.timerTick) + END + v9.CheckSourceSuccess(lines) + + # Use the timer callback from a def function + lines =<< trim END + vim9script + + class A + this.timerTick: number = -1 + def TimerCb(timerID: number) + this.timerTick = 6 + enddef + endclass + + def Foo() + var a = A.new() + timer_start(0, a.TimerCb) + var maxWait = 5 + while maxWait > 0 && a.timerTick == -1 + :sleep 10m + maxWait -= 1 + endwhile + assert_equal(6, a.timerTick) + enddef + Foo() + END + v9.CheckSourceSuccess(lines) +enddef + +" Test for using a class method as a timer callback function +def Test_classmethod_timer_callback() + # Use the timer callback from script level + var lines =<< trim END + vim9script + + class A + static timerTick: number = -1 + static def TimerCb(timerID: number) + timerTick = 6 + enddef + endclass + + timer_start(0, A.TimerCb) + var maxWait = 5 + while maxWait > 0 && A.timerTick == -1 + :sleep 10m + maxWait -= 1 + endwhile + assert_equal(6, A.timerTick) + END + v9.CheckSourceSuccess(lines) + + # Use the timer callback from a def function + lines =<< trim END + vim9script + + class A + static timerTick: number = -1 + static def TimerCb(timerID: number) + timerTick = 6 + enddef + endclass + + def Foo() + timer_start(0, A.TimerCb) + var maxWait = 5 + while maxWait > 0 && A.timerTick == -1 + :sleep 10m + maxWait -= 1 + endwhile + assert_equal(6, A.timerTick) + enddef + Foo() + END + v9.CheckSourceSuccess(lines) +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 6e27dbdd00..521f75fb17 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -3276,7 +3276,7 @@ def Test_funcref_with_class() 'defer a.Foo()\_s*' .. '0 LOAD arg\[-1\]\_s*' .. '1 FUNCREF A.Foo\_s*' .. - '2 DEFEROBJ 0 args\_s*' .. + '2 DEFER 0 args\_s*' .. '3 RETURN void', g:instr) unlet g:instr enddef diff --git a/src/version.c b/src/version.c index 438e9a0454..a0ac2d0772 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2038, /**/ 2037, /**/ diff --git a/src/vim9.h b/src/vim9.h index 6bfbd9ee8f..63aec46298 100644 --- a/src/vim9.h +++ b/src/vim9.h @@ -125,7 +125,6 @@ typedef enum { ISN_NEWFUNC, // create a global function from a lambda function ISN_DEF, // list functions ISN_DEFER, // :defer argument count is isn_arg.number - ISN_DEFEROBJ, // idem, function is an object method // expression operations ISN_JUMP, // jump if condition is matched isn_arg.jump diff --git a/src/vim9cmds.c b/src/vim9cmds.c index 8b5b569808..92605cff32 100644 --- a/src/vim9cmds.c +++ b/src/vim9cmds.c @@ -2000,7 +2000,6 @@ compile_defer(char_u *arg_start, cctx_T *cctx) int defer_var_idx; type_T *type; int func_idx; - int obj_method = 0; // Get a funcref for the function name. // TODO: better way to find the "(". @@ -2016,15 +2015,8 @@ compile_defer(char_u *arg_start, cctx_T *cctx) // TODO: better type generate_PUSHFUNC(cctx, (char_u *)internal_func_name(func_idx), &t_func_any, FALSE); - else - { - int typecount = cctx->ctx_type_stack.ga_len; - if (compile_expr0(&arg, cctx) == FAIL) - return NULL; - if (cctx->ctx_type_stack.ga_len >= typecount + 2) - // must have seen "obj.Func", pushed an object and a function - obj_method = 1; - } + else if (compile_expr0(&arg, cctx) == FAIL) + return NULL; *paren = '('; // check for function type @@ -2056,7 +2048,7 @@ compile_defer(char_u *arg_start, cctx_T *cctx) defer_var_idx = get_defer_var_idx(cctx); if (defer_var_idx == 0) return NULL; - if (generate_DEFER(cctx, defer_var_idx - 1, obj_method, argcount) == FAIL) + if (generate_DEFER(cctx, defer_var_idx - 1, argcount) == FAIL) return NULL; return skipwhite(arg); diff --git a/src/vim9execute.c b/src/vim9execute.c index d8087bf08d..1fdff84da7 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -1029,10 +1029,9 @@ add_defer_item(int var_idx, int argcount, ectx_T *ectx) * Returns OK or FAIL. */ static int -defer_command(int var_idx, int has_obj, int argcount, ectx_T *ectx) +defer_command(int var_idx, int argcount, ectx_T *ectx) { - int obj_off = has_obj ? 1 : 0; - list_T *l = add_defer_item(var_idx, argcount + obj_off, ectx); + list_T *l = add_defer_item(var_idx, argcount, ectx); int i; typval_T *func_tv; @@ -1040,20 +1039,18 @@ defer_command(int var_idx, int has_obj, int argcount, ectx_T *ectx) return FAIL; func_tv = STACK_TV_BOT(-argcount - 1); - if (has_obj ? func_tv->v_type != VAR_PARTIAL : func_tv->v_type != VAR_FUNC) + if (func_tv->v_type != VAR_PARTIAL && func_tv->v_type != VAR_FUNC) { semsg(_(e_expected_str_but_got_str), - has_obj ? "partial" : "function", + "function or partial", vartype_name(func_tv->v_type)); return FAIL; } list_set_item(l, 0, func_tv); - if (has_obj) - list_set_item(l, 1, STACK_TV_BOT(-argcount - 2)); for (i = 0; i < argcount; ++i) - list_set_item(l, i + 1 + obj_off, STACK_TV_BOT(-argcount + i)); - ectx->ec_stack.ga_len -= argcount + 1 + obj_off; + list_set_item(l, i + 1, STACK_TV_BOT(-argcount + i)); + ectx->ec_stack.ga_len -= argcount + 1; return OK; } @@ -1116,15 +1113,12 @@ invoke_defer_funcs(ectx_T *ectx) int i; listitem_T *arg_li = l->lv_first; typval_T *functv = &l->lv_first->li_tv; - int obj_off = functv->v_type == VAR_PARTIAL ? 1 : 0; - int argcount = l->lv_len - 1 - obj_off; + int argcount = l->lv_len - 1; if (functv->vval.v_string == NULL) // already being called, can happen if function does ":qa" continue; - if (obj_off == 1) - arg_li = arg_li->li_next; // second list item is the object for (i = 0; i < argcount; ++i) { arg_li = arg_li->li_next; @@ -1138,7 +1132,7 @@ invoke_defer_funcs(ectx_T *ectx) if (functv->v_type == VAR_PARTIAL) { funcexe.fe_partial = functv->vval.v_partial; - funcexe.fe_object = l->lv_first->li_next->li_tv.vval.v_object; + funcexe.fe_object = functv->vval.v_partial->pt_obj; if (funcexe.fe_object != NULL) ++funcexe.fe_object->obj_refcount; } @@ -4401,9 +4395,7 @@ exec_instructions(ectx_T *ectx) // :defer func(arg) case ISN_DEFER: - case ISN_DEFEROBJ: if (defer_command(iptr->isn_arg.defer.defer_var_idx, - iptr->isn_type == ISN_DEFEROBJ, iptr->isn_arg.defer.defer_argcount, ectx) == FAIL) goto on_error; break; @@ -6933,9 +6925,7 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc) smsg("%s%4d PCALL end", pfx, current); break; case ISN_DEFER: - case ISN_DEFEROBJ: - smsg("%s%4d %s %d args", pfx, current, - iptr->isn_type == ISN_DEFER ? "DEFER" : "DEFEROBJ", + smsg("%s%4d DEFER %d args", pfx, current, (int)iptr->isn_arg.defer.defer_argcount); break; case ISN_RETURN: diff --git a/src/vim9expr.c b/src/vim9expr.c index c91ca9325b..85eb7afb90 100644 --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -450,9 +450,9 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type) return FAIL; } *arg = name_end; - if (type->tt_type == VAR_OBJECT) - return generate_FUNCREF(cctx, fp, cl, TRUE, m_idx, NULL); - return generate_FUNCREF(cctx, fp, NULL, FALSE, 0, NULL); + // Remove the object type from the stack + --cctx->ctx_type_stack.ga_len; + return generate_FUNCREF(cctx, fp, cl, TRUE, m_idx, NULL); } member_not_found_msg(cl, VAR_OBJECT, name, len); @@ -490,9 +490,9 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type) return FAIL; } *arg = name_end; - if (type->tt_type == VAR_CLASS) - return generate_FUNCREF(cctx, fp, cl, FALSE, m_idx, NULL); - return generate_FUNCREF(cctx, fp, NULL, FALSE, 0, NULL); + // Remove the class type from the stack + --cctx->ctx_type_stack.ga_len; + return generate_FUNCREF(cctx, fp, cl, FALSE, m_idx, NULL); } member_not_found_msg(cl, VAR_CLASS, name, len); diff --git a/src/vim9instr.c b/src/vim9instr.c index f7b074c79a..8ee9e7c6cd 100644 --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -2039,17 +2039,14 @@ generate_PCALL( /* * Generate an ISN_DEFER instruction. - * "obj_method" is one for "obj.Method()", zero otherwise. */ int -generate_DEFER(cctx_T *cctx, int var_idx, int obj_method, int argcount) +generate_DEFER(cctx_T *cctx, int var_idx, int argcount) { isn_T *isn; RETURN_OK_IF_SKIP(cctx); - if ((isn = generate_instr_drop(cctx, - obj_method == 0 ? ISN_DEFER : ISN_DEFEROBJ, - argcount + 1)) == NULL) + if ((isn = generate_instr_drop(cctx, ISN_DEFER, argcount + 1)) == NULL) return FAIL; isn->isn_arg.defer.defer_var_idx = var_idx; isn->isn_arg.defer.defer_argcount = argcount; @@ -2711,7 +2708,6 @@ delete_instr(isn_T *isn) case ISN_COND2BOOL: case ISN_DEBUG: case ISN_DEFER: - case ISN_DEFEROBJ: case ISN_DROP: case ISN_ECHO: case ISN_ECHOCONSOLE: From 2e3cd52fa02b1a208c97992b1bca3b04f7be66d4 Mon Sep 17 00:00:00 2001 From: nwounkn Date: Tue, 17 Oct 2023 11:05:38 +0200 Subject: [PATCH 08/13] patch 9.0.2039: completion shows current word after completion restart Problem: completion shows current word after completion restart Solution: remove the word being completed after completion restart The word being completed is shown in a completion list after completion restart, because it isn't removed from the current buffer before searching for matches. Also adjust `Test_complete_add_onechar` to match the new behavior. closes: #13349 Signed-off-by: Christian Brabandt Co-authored-by: nwounkn --- src/insexpand.c | 2 +- src/testdir/test_ins_complete.vim | 13 ++++++++++++- src/version.c | 2 ++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/insexpand.c b/src/insexpand.c index f225cd3844..ad4edc184e 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -4157,7 +4157,7 @@ ins_compl_next( ins_compl_update_shown_match(); if (allow_get_expansion && insert_match - && (!(compl_get_longest || compl_restarting) || compl_used_match)) + && (!compl_get_longest || compl_used_match)) // Delete old text to be replaced ins_compl_delete(); diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim index c7f9e9b28b..a4ac26e06c 100644 --- a/src/testdir/test_ins_complete.vim +++ b/src/testdir/test_ins_complete.vim @@ -818,7 +818,7 @@ func Test_complete_add_onechar() setlocal complete=. call setline(1, ['workhorse', 'workload']) normal Go - exe "normal aWOR\\\\\\\\r\\" + exe "normal aWOR\\\\\\\\\\" call assert_equal('workh', getline(3)) set ignorecase& backspace& close! @@ -2248,6 +2248,17 @@ func GetCompleteInfo() return '' endfunc +func Test_completion_restart() + new + set complete=. completeopt=menuone backspace=2 + call setline(1, 'workhorse workhorse') + exe "normal $a\\\\=GetCompleteInfo()\" + call assert_equal(1, len(g:compl_info['items'])) + call assert_equal('workhorse', g:compl_info['items'][0]['word']) + set complete& completeopt& backspace& + bwipe! +endfunc + func Test_complete_info_index() new call setline(1, ["aaa", "bbb", "ccc", "ddd", "eee", "fff"]) diff --git a/src/version.c b/src/version.c index a0ac2d0772..208d7a8819 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2039, /**/ 2038, /**/ From 6e6386716f9494ae86027c6d34f657fd03dfec42 Mon Sep 17 00:00:00 2001 From: Illia Bobyr Date: Tue, 17 Oct 2023 11:09:45 +0200 Subject: [PATCH 09/13] patch 9.0.2040: trim(): hard to use default mask Problem: trim(): hard to use default mask Solution: Use default 'mask' when it is v:none The default 'mask' value is pretty complex, as it includes many characters. Yet, if one needs to specify the trimming direction, the third argument, 'trim()' currently requires the 'mask' value to be provided explicitly. 'v:none' is already used to mean "use the default argument value" in user defined functions. See |none-function_argument| in help. closes: #13363 Signed-off-by: Christian Brabandt Co-authored-by: Illia Bobyr --- runtime/doc/builtin.txt | 7 ++++--- src/errors.h | 2 ++ src/proto/typval.pro | 1 + src/strings.c | 28 +++++++++++++--------------- src/testdir/test_functions.vim | 6 +++++- src/testdir/test_vim9_builtin.vim | 2 +- src/typval.c | 31 +++++++++++++++++++++++++++++++ src/version.c | 2 ++ 8 files changed, 59 insertions(+), 20 deletions(-) diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index a9bba86d8c..38c4b6f688 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -10119,9 +10119,10 @@ trim({text} [, {mask} [, {dir}]]) *trim()* Return {text} as a String where any character in {mask} is removed from the beginning and/or end of {text}. - If {mask} is not given, {mask} is all characters up to 0x20, - which includes Tab, space, NL and CR, plus the non-breaking - space character 0xa0. + If {mask} is not given, or is |v:none| (see + |none-function_argument|), {mask} is all characters up to + 0x20, which includes Tab, space, NL and CR, plus the + non-breaking space character 0xa0. The optional {dir} argument specifies where to remove the characters: diff --git a/src/errors.h b/src/errors.h index 7b1181ae94..d7ed81a16e 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3539,6 +3539,8 @@ EXTERN char e_cannot_lock_object_variable_str[] EXTERN char e_cannot_lock_class_variable_str[] INIT(= N_("E1392: Cannot (un)lock class variable \"%s\" in class \"%s\"")); #endif +EXTERN char e_string_or_none_required_for_argument_nr[] + INIT(= N_("E1393: String or v:none required for argument %d")); // E1393 - E1499 unused (reserved for Vim9 class support) EXTERN char e_cannot_mix_positional_and_non_positional_str[] INIT(= N_("E1500: Cannot mix positional and non-positional arguments: %s")); diff --git a/src/proto/typval.pro b/src/proto/typval.pro index db8f94ebb0..10f6e67111 100644 --- a/src/proto/typval.pro +++ b/src/proto/typval.pro @@ -14,6 +14,7 @@ int check_for_unknown_arg(typval_T *args, int idx); int check_for_string_arg(typval_T *args, int idx); int check_for_nonempty_string_arg(typval_T *args, int idx); int check_for_opt_string_arg(typval_T *args, int idx); +int check_for_opt_string_or_none_arg(typval_T *args, int idx, int *is_none); int check_for_number_arg(typval_T *args, int idx); int check_for_opt_number_arg(typval_T *args, int idx); int check_for_float_or_nr_arg(typval_T *args, int idx); diff --git a/src/strings.c b/src/strings.c index c04cbe84f6..f1c8af8f99 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1962,7 +1962,7 @@ f_trim(typval_T *argvars, typval_T *rettv) if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL - || check_for_opt_string_arg(argvars, 1) == FAIL + || check_for_opt_string_or_none_arg(argvars, 1, NULL) == FAIL || (argvars[1].v_type != VAR_UNKNOWN && check_for_opt_number_arg(argvars, 2) == FAIL))) return; @@ -1971,26 +1971,24 @@ f_trim(typval_T *argvars, typval_T *rettv) if (head == NULL) return; - if (check_for_opt_string_arg(argvars, 1) == FAIL) + if (check_for_opt_string_or_none_arg(argvars, 1, NULL) == FAIL) return; if (argvars[1].v_type == VAR_STRING) - { mask = tv_get_string_buf_chk(&argvars[1], buf2); - if (argvars[2].v_type != VAR_UNKNOWN) - { - int error = 0; + if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) + { + int error = 0; - // leading or trailing characters to trim - dir = (int)tv_get_number_chk(&argvars[2], &error); - if (error) - return; - if (dir < 0 || dir > 2) - { - semsg(_(e_invalid_argument_str), tv_get_string(&argvars[2])); - return; - } + // leading or trailing characters to trim + dir = (int)tv_get_number_chk(&argvars[2], &error); + if (error) + return; + if (dir < 0 || dir > 2) + { + semsg(_(e_invalid_argument_str), tv_get_string(&argvars[2])); + return; } } diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index d598966977..85d1d22ee6 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -2231,11 +2231,15 @@ func Test_trim() call assert_fails('eval trim(" vim ", " ", [])', 'E745:') call assert_fails('eval trim(" vim ", " ", -1)', 'E475:') call assert_fails('eval trim(" vim ", " ", 3)', 'E475:') - call assert_fails('eval trim(" vim ", 0)', 'E1174:') + call assert_fails('eval trim(" vim ", 0)', 'E1393:') let chars = join(map(range(1, 0x20) + [0xa0], {n -> n->nr2char()}), '') call assert_equal("x", trim(chars . "x" . chars)) + call assert_equal("x", trim(chars . "x" . chars, v:none, 0)) + call assert_equal("x" . chars, trim(chars . "x" . chars, v:none, 1)) + call assert_equal(chars . "x", trim(chars . "x" . chars, v:none, 2)) + call assert_fails('let c=trim([])', 'E730:') endfunc diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 1efc47a074..206f97f2e0 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -4786,7 +4786,7 @@ enddef def Test_trim() v9.CheckDefAndScriptFailure(['trim(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['trim("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected string but got list', 'E1174: String required for argument 2']) + v9.CheckDefAndScriptFailure(['trim("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected string but got list', 'E1393: String or v:none required for argument 2']) v9.CheckDefAndScriptFailure(['trim("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) trim('')->assert_equal('') trim('', '')->assert_equal('') diff --git a/src/typval.c b/src/typval.c index 08dd2313f2..b6371aaa43 100644 --- a/src/typval.c +++ b/src/typval.c @@ -450,6 +450,37 @@ check_for_opt_string_arg(typval_T *args, int idx) || check_for_string_arg(args, idx) != FAIL) ? OK : FAIL; } +/* + * Check for an optional string argument at 'idx', that can also be 'v:none' to + * use the default value. + * + * If 'is_none' is non-NULL it is set to 0 and updated to 1 when "args[idx]" is + * 'v:none'. + */ + int +check_for_opt_string_or_none_arg(typval_T *args, int idx, int *is_none) +{ + if (is_none != NULL) + *is_none = 0; + + if (args[idx].v_type == VAR_UNKNOWN) + return OK; + + if (args[idx].v_type == VAR_SPECIAL + && args[idx].vval.v_number == VVAL_NONE) + { + if (is_none != NULL) + *is_none = 1; + return OK; + } + + if (args[idx].v_type == VAR_STRING) + return OK; + + semsg(_(e_string_or_none_required_for_argument_nr), idx + 1); + return FAIL; +} + /* * Give an error and return FAIL unless "args[idx]" is a number. */ diff --git a/src/version.c b/src/version.c index 208d7a8819..0896c643f9 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2040, /**/ 2039, /**/ From 5a33ce2a661fb836d4c5c489f2a850172a23e0b0 Mon Sep 17 00:00:00 2001 From: Rolf Vidar Mazunki Hoksaas <32819373+mazunki@users.noreply.github.com> Date: Tue, 17 Oct 2023 11:13:06 +0200 Subject: [PATCH 10/13] runtime(json5): include syntax script for json5 (#13356) Merging syntax file from gutenye/json5.vim, modified to include proper vim header. See: https://github.com/vim/vim/issues/8499 Signed-off-by: Mazunki Hoksaas Co-authored-by: Guten Ye Signed-off-by: Christian Brabandt --- runtime/syntax/json5.vim | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 runtime/syntax/json5.vim diff --git a/runtime/syntax/json5.vim b/runtime/syntax/json5.vim new file mode 100644 index 0000000000..5b01d33aad --- /dev/null +++ b/runtime/syntax/json5.vim @@ -0,0 +1,73 @@ +" Vim syntax file +" Language: JSON5 +" Maintainer: Mazunki Hoksaas rolferen@gmail.com +" Previous Maintainer: Guten Ye +" Last Change: 2019 Apr 1 +" Version: vim9.0-1 +" URL: https://github.com/json5/json5 + +" Syntax setup +if exists('b:current_syntax') && b:current_syntax == 'json5' + finish +endif + +" Numbers +syn match json5Number "[-+]\=\%(0\|[1-9]\d*\)\%(\.\d*\)\=\%([eE][-+]\=\d\+\)\=" +syn match json5Number "[-+]\=\%(\.\d\+\)\%([eE][-+]\=\d\+\)\=" +syn match json5Number "[-+]\=0[xX]\x*" +syn match json5Number "[-+]\=Infinity\|NaN" + +" An integer part of 0 followed by other digits is not allowed +syn match json5NumError "[-+]\=0\d\(\d\|\.\)*" + +" A hexadecimal number cannot have a fractional part +syn match json5NumError "[-+]\=0x\x*\.\x*" + +" Strings +syn region json5String start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=json5Escape,@Spell +syn region json5String start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=json5Escape,@Spell + +" Escape sequences +syn match json5Escape "\\['\"\\bfnrtv]" contained +syn match json5Escape "\\u\x\{4}" contained + +" Boolean +syn keyword json5Boolean true false + +" Null +syn keyword json5Null null + +" Delimiters and Operators +syn match json5Delimiter "," +syn match json5Operator ":" + +" Braces +syn match json5Braces "[{}\[\]]" + +" Keys +syn match json5Key /@\?\%(\I\|\$\)\%(\i\|\$\)*\s*\ze::\@!/ contains=@Spell +syn match json5Key /"\([^"]\|\\"\)\{-}"\ze\s*:/ contains=json5Escape,@Spell + +" Comment +syn region json5LineComment start=+\/\/+ end=+$+ keepend contains=@Spell +syn region json5LineComment start=+^\s*\/\/+ skip=+\n\s*\/\/+ end=+$+ keepend fold contains=@Spell +syn region json5Comment start="/\*" end="\*/" fold contains=@Spell + +" Define the default highlighting +hi def link json5String String +hi def link json5Key Identifier +hi def link json5Escape Special +hi def link json5Number Number +hi def link json5Delimiter Delimiter +hi def link json5Operator Operator +hi def link json5Braces Delimiter +hi def link json5Null Keyword +hi def link json5Boolean Boolean +hi def link json5LineComment Comment +hi def link json5Comment Comment +hi def link json5NumError Error + +if !exists('b:current_syntax') + let b:current_syntax = 'json5' +endif + From 8079917447e7436dccc2e4cd4a4a56ae0a4712f2 Mon Sep 17 00:00:00 2001 From: Illia Bobyr Date: Tue, 17 Oct 2023 18:00:50 +0200 Subject: [PATCH 11/13] patch 9.0.2041: trim(): hard to use default mask Problem: trim(): hard to use default mask (partly revert v9.0.2040) Solution: use default mask when it is empty The default 'mask' value is pretty complex, as it includes many characters. Yet, if one needs to specify the trimming direction, the third argument, 'trim()' currently requires the 'mask' value to be provided explicitly. Currently, an empty 'mask' will make 'trim()' call return 'text' value that is passed in unmodified. It is unlikely that someone is using it, so the chances of scripts being broken by this change are low. Also, this reverts commit 9.0.2040 (which uses v:none for the default and requires to use an empty string instead). closes: #13358 Signed-off-by: Christian Brabandt Co-authored-by: Illia Bobyr --- runtime/doc/builtin.txt | 7 +++---- src/errors.h | 2 -- src/proto/typval.pro | 1 - src/strings.c | 30 +++++++++++++++++------------- src/testdir/test_functions.vim | 8 ++++---- src/testdir/test_vim9_builtin.vim | 2 +- src/typval.c | 31 ------------------------------- src/version.c | 2 ++ 8 files changed, 27 insertions(+), 56 deletions(-) diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 38c4b6f688..5f57fdb59d 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -10119,10 +10119,9 @@ trim({text} [, {mask} [, {dir}]]) *trim()* Return {text} as a String where any character in {mask} is removed from the beginning and/or end of {text}. - If {mask} is not given, or is |v:none| (see - |none-function_argument|), {mask} is all characters up to - 0x20, which includes Tab, space, NL and CR, plus the - non-breaking space character 0xa0. + If {mask} is not given, or is an empty string, {mask} is all + characters up to 0x20, which includes Tab, space, NL and CR, + plus the non-breaking space character 0xa0. The optional {dir} argument specifies where to remove the characters: diff --git a/src/errors.h b/src/errors.h index d7ed81a16e..7b1181ae94 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3539,8 +3539,6 @@ EXTERN char e_cannot_lock_object_variable_str[] EXTERN char e_cannot_lock_class_variable_str[] INIT(= N_("E1392: Cannot (un)lock class variable \"%s\" in class \"%s\"")); #endif -EXTERN char e_string_or_none_required_for_argument_nr[] - INIT(= N_("E1393: String or v:none required for argument %d")); // E1393 - E1499 unused (reserved for Vim9 class support) EXTERN char e_cannot_mix_positional_and_non_positional_str[] INIT(= N_("E1500: Cannot mix positional and non-positional arguments: %s")); diff --git a/src/proto/typval.pro b/src/proto/typval.pro index 10f6e67111..db8f94ebb0 100644 --- a/src/proto/typval.pro +++ b/src/proto/typval.pro @@ -14,7 +14,6 @@ int check_for_unknown_arg(typval_T *args, int idx); int check_for_string_arg(typval_T *args, int idx); int check_for_nonempty_string_arg(typval_T *args, int idx); int check_for_opt_string_arg(typval_T *args, int idx); -int check_for_opt_string_or_none_arg(typval_T *args, int idx, int *is_none); int check_for_number_arg(typval_T *args, int idx); int check_for_opt_number_arg(typval_T *args, int idx); int check_for_float_or_nr_arg(typval_T *args, int idx); diff --git a/src/strings.c b/src/strings.c index f1c8af8f99..0aeea4bce9 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1962,7 +1962,7 @@ f_trim(typval_T *argvars, typval_T *rettv) if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL - || check_for_opt_string_or_none_arg(argvars, 1, NULL) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL || (argvars[1].v_type != VAR_UNKNOWN && check_for_opt_number_arg(argvars, 2) == FAIL))) return; @@ -1971,24 +1971,28 @@ f_trim(typval_T *argvars, typval_T *rettv) if (head == NULL) return; - if (check_for_opt_string_or_none_arg(argvars, 1, NULL) == FAIL) + if (check_for_opt_string_arg(argvars, 1) == FAIL) return; if (argvars[1].v_type == VAR_STRING) - mask = tv_get_string_buf_chk(&argvars[1], buf2); - - if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) { - int error = 0; + mask = tv_get_string_buf_chk(&argvars[1], buf2); + if (*mask == NUL) + mask = NULL; - // leading or trailing characters to trim - dir = (int)tv_get_number_chk(&argvars[2], &error); - if (error) - return; - if (dir < 0 || dir > 2) + if (argvars[2].v_type != VAR_UNKNOWN) { - semsg(_(e_invalid_argument_str), tv_get_string(&argvars[2])); - return; + int error = 0; + + // leading or trailing characters to trim + dir = (int)tv_get_number_chk(&argvars[2], &error); + if (error) + return; + if (dir < 0 || dir > 2) + { + semsg(_(e_invalid_argument_str), tv_get_string(&argvars[2])); + return; + } } } diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index 85d1d22ee6..49b688c25f 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -2231,14 +2231,14 @@ func Test_trim() call assert_fails('eval trim(" vim ", " ", [])', 'E745:') call assert_fails('eval trim(" vim ", " ", -1)', 'E475:') call assert_fails('eval trim(" vim ", " ", 3)', 'E475:') - call assert_fails('eval trim(" vim ", 0)', 'E1393:') + call assert_fails('eval trim(" vim ", 0)', 'E1174:') let chars = join(map(range(1, 0x20) + [0xa0], {n -> n->nr2char()}), '') call assert_equal("x", trim(chars . "x" . chars)) - call assert_equal("x", trim(chars . "x" . chars, v:none, 0)) - call assert_equal("x" . chars, trim(chars . "x" . chars, v:none, 1)) - call assert_equal(chars . "x", trim(chars . "x" . chars, v:none, 2)) + call assert_equal("x", trim(chars . "x" . chars, '', 0)) + call assert_equal("x" . chars, trim(chars . "x" . chars, '', 1)) + call assert_equal(chars . "x", trim(chars . "x" . chars, '', 2)) call assert_fails('let c=trim([])', 'E730:') endfunc diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 206f97f2e0..1efc47a074 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -4786,7 +4786,7 @@ enddef def Test_trim() v9.CheckDefAndScriptFailure(['trim(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['trim("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected string but got list', 'E1393: String or v:none required for argument 2']) + v9.CheckDefAndScriptFailure(['trim("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected string but got list', 'E1174: String required for argument 2']) v9.CheckDefAndScriptFailure(['trim("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) trim('')->assert_equal('') trim('', '')->assert_equal('') diff --git a/src/typval.c b/src/typval.c index b6371aaa43..08dd2313f2 100644 --- a/src/typval.c +++ b/src/typval.c @@ -450,37 +450,6 @@ check_for_opt_string_arg(typval_T *args, int idx) || check_for_string_arg(args, idx) != FAIL) ? OK : FAIL; } -/* - * Check for an optional string argument at 'idx', that can also be 'v:none' to - * use the default value. - * - * If 'is_none' is non-NULL it is set to 0 and updated to 1 when "args[idx]" is - * 'v:none'. - */ - int -check_for_opt_string_or_none_arg(typval_T *args, int idx, int *is_none) -{ - if (is_none != NULL) - *is_none = 0; - - if (args[idx].v_type == VAR_UNKNOWN) - return OK; - - if (args[idx].v_type == VAR_SPECIAL - && args[idx].vval.v_number == VVAL_NONE) - { - if (is_none != NULL) - *is_none = 1; - return OK; - } - - if (args[idx].v_type == VAR_STRING) - return OK; - - semsg(_(e_string_or_none_required_for_argument_nr), idx + 1); - return FAIL; -} - /* * Give an error and return FAIL unless "args[idx]" is a number. */ diff --git a/src/version.c b/src/version.c index 0896c643f9..05b65c4b5d 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2041, /**/ 2040, /**/ From c290009e99405024a0d91ec7fab21ac7111c421b Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Tue, 17 Oct 2023 18:10:13 +0200 Subject: [PATCH 12/13] patch 9.0.2042: Test_cq_zero_exmode fails without channel feature Problem: Test_cq_zero_exmode fails without channel feature Solution: Make the test check the channel feature closes: #13365 Signed-off-by: Christian Brabandt --- runtime/doc/starting.txt | 4 ++-- src/testdir/test_startup.vim | 2 ++ src/version.c | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index 58b8edcd35..f7e98c7bef 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -1,4 +1,4 @@ -*starting.txt* For Vim version 9.0. Last change: 2023 May 30 +*starting.txt* For Vim version 9.0. Last change: 2023 Oct 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -348,7 +348,7 @@ a slash. Thus "-R" means recovery and "-/R" readonly. Start logging and write entries to {filename}. This works like calling `ch_logfile({filename}, 'ao')` very early during startup. - {only available with the |+eval| feature} + {only available with the |+eval| and |+channel| feature} *-D* -D Debugging. Go to debugging mode when executing the first diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 6780205a2d..1a81318f3f 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -1353,6 +1353,8 @@ endfunc " Test that -cq works as expected func Test_cq_zero_exmode() + CheckFeature channel + let logfile = 'Xcq_log.txt' let out = system(GetVimCommand() .. ' --clean --log ' .. logfile .. ' -es -X -c "argdelete foobar" -c"7cq"') call assert_equal(8, v:shell_error) diff --git a/src/version.c b/src/version.c index 05b65c4b5d..0b1bf3138e 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2042, /**/ 2041, /**/ From 96952b2e98cb5f05bc3b3adfb0029056f39cffef Mon Sep 17 00:00:00 2001 From: Ernie Rael Date: Tue, 17 Oct 2023 18:15:01 +0200 Subject: [PATCH 13/13] patch 9.0.2043: Vim9: issue with funcref assignmentand varargs Problem: Vim9: issue with funcref assignmentand varargs Solution: Fix funcref type checking closes: #13351 Signed-off-by: Christian Brabandt Co-authored-by: Ernie Rael --- src/testdir/test_vim9_assign.vim | 56 ++++++++++++++++++++++++++++ src/testdir/test_vim9_class.vim | 63 ++++++++++++++++++++++++++++++++ src/testdir/test_vim9_func.vim | 2 +- src/version.c | 2 + src/vim9type.c | 5 +++ 5 files changed, 127 insertions(+), 1 deletion(-) diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 3a187774ec..bff9c9f8f1 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -1863,6 +1863,62 @@ def Test_assign_lambda() v9.CheckDefAndScriptFailure(lines, 'E1051:') enddef +def Test_assign_funcref_args() + # unspecified arguments match everything, including varargs + var lines =<< trim END + vim9script + + var FuncUnknown: func: number + + FuncUnknown = (v): number => v + assert_equal(5, FuncUnknown(5)) + + FuncUnknown = (v1, v2): number => v1 + v2 + assert_equal(7, FuncUnknown(3, 4)) + + FuncUnknown = (...v1): number => v1[0] + v1[1] + len(v1) * 1000 + assert_equal(4007, FuncUnknown(3, 4, 5, 6)) + + FuncUnknown = (v: list): number => v[0] + v[1] + len(v) * 1000 + assert_equal(5009, FuncUnknown([4, 5, 6, 7, 8])) + END + v9.CheckScriptSuccess(lines) + + # varargs must match + lines =<< trim END + vim9script + var FuncAnyVA: func(...any): number + FuncAnyVA = (v): number => v + END + v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(...any): number but got func(any): number') + + # varargs must match + lines =<< trim END + vim9script + var FuncAnyVA: func(...any): number + FuncAnyVA = (v1, v2): number => v1 + v2 + END + v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(...any): number but got func(any, any): number') + + # varargs must match + lines =<< trim END + vim9script + var FuncAnyVA: func(...any): number + FuncAnyVA = (v1: list): number => 3 + END + v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(...any): number but got func(list): number') +enddef + +def Test_assign_funcref_arg_any() + var lines =<< trim END + vim9script + var FuncAnyVA: func(any): number + FuncAnyVA = (v): number => v + END + # TODO: Verify this should succeed. + v9.CheckScriptSuccess(lines) +enddef + def Test_heredoc() # simple heredoc var lines =<< trim END diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 8b08dc1b2d..01cf3e128f 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -6953,6 +6953,21 @@ def Test_extended_obj_method_type_check() endclass END v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object): object but got func(object): object', 20) + + # check varargs type mismatch + lines =<< trim END + vim9script + + class B + def F(...xxx: list) + enddef + endclass + class C extends B + def F(xxx: list) + enddef + endclass + END + v9.CheckSourceFailure(lines, 'E1383: Method "F": type mismatch, expected func(...list) but got func(list)', 10) enddef " Test type checking for class variable in assignments @@ -7431,6 +7446,54 @@ def Test_funcref_argtype_returntype_check() v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object): object but got func(object): object', 1) enddef +def Test_funcref_argtype_invariance_check() + var lines =<< trim END + vim9script + + class A + endclass + class B extends A + endclass + class C extends B + endclass + + var Func: func(B): number + Func = (o: B): number => 3 + assert_equal(3, Func(B.new())) + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + + class A + endclass + class B extends A + endclass + class C extends B + endclass + + var Func: func(B): number + Func = (o: A): number => 3 + END + v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object): number but got func(object): number', 11) + + lines =<< trim END + vim9script + + class A + endclass + class B extends A + endclass + class C extends B + endclass + + var Func: func(B): number + Func = (o: C): number => 3 + END + v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object): number but got func(object): number', 11) +enddef + " Test for using an operator (e.g. +) with an assignment def Test_op_and_assignment() # Using += with a class variable diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 597a10c581..701a2f085d 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -1995,7 +1995,7 @@ def Test_varargs_mismatch() var res = Map((v) => str2nr(v)) assert_equal(12, res) END - v9.CheckScriptSuccess(lines) + v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected func(...any): number but got func(any): number') enddef def Test_using_var_as_arg() diff --git a/src/version.c b/src/version.c index 0b1bf3138e..bad07e6446 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2043, /**/ 2042, /**/ diff --git a/src/vim9type.c b/src/vim9type.c index 00ee76b487..6a5848792b 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -884,6 +884,11 @@ check_type_maybe( else ret = MAYBE; } + if (ret != FAIL + && ((expected->tt_flags & TTFLAG_VARARGS) + != (actual->tt_flags & TTFLAG_VARARGS)) + && expected->tt_argcount != -1) + ret = FAIL; if (ret != FAIL && expected->tt_argcount != -1 && actual->tt_min_argcount != -1 && (actual->tt_argcount == -1