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/doc/builtin.txt b/runtime/doc/builtin.txt index e177447001..6b434d0b21 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -10143,9 +10143,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, {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/runtime/doc/index.txt b/runtime/doc/index.txt index f03a402c8a..7b436092ce 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 0637c9c3ef..5faabef6ce 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -9397,6 +9397,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 @@ -9465,6 +9467,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: @@ -9483,10 +9489,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/runtime/doc/starting.txt b/runtime/doc/starting.txt index 119ae99f05..fa58f0dc56 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/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/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 + 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 '|\@1xp_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/errors.h b/src/errors.h index a1d71fb12d..af179d6c01 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3564,4 +3564,4 @@ EXTERN char e_aptypes_is_null_nr_str[] EXTERN char e_xattr_e2big[] INIT(= N_("E1508: Size of the extended attribute value is larger than the maximum size allowed")); EXTERN char e_xattr_other[] - INIT(= N_("E1509: Error occured when reading or writing extended attribute")); + INIT(= N_("E1509: Error occurred when reading or writing extended attribute")); diff --git a/src/ex_docmd.c b/src/ex_docmd.c index a0cddc5d97..3812f87830 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -5596,7 +5596,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 4f247002f2..7d83573c94 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; @@ -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() || 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 @@ -1888,7 +1889,6 @@ getcmdline_int( if (nextwild(&xpc, wild_type, WILD_NO_BEEP, firstc != '@') == FAIL) break; - c = Ctrl_E; } } @@ -1897,7 +1897,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 @@ -2015,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. */ @@ -2513,6 +2521,15 @@ returncmd: 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/filepath.c b/src/filepath.c index a6bca11c67..3644bff788 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/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/insexpand.c b/src/insexpand.c index 145b13a0aa..108b1a67b8 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -4161,7 +4161,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/option.c b/src/option.c index c90963e42d..58a6ed22ba 100644 --- a/src/option.c +++ b/src/option.c @@ -4417,6 +4417,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. */ @@ -8152,7 +8167,7 @@ ExpandSettingSubtract( { // Don't suggest anything if cmdline is non-empty. Vim's set-= // behavior requires consecutive strings and it's usually - // unintuitive to users if ther try to subtract multiple flags at + // unintuitive to users if they try to subtract multiple flags at // once. return FAIL; } diff --git a/src/optiondefs.h b/src/optiondefs.h index d27d0c381d..3dd0a70bc7 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -2929,11 +2929,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/optionstr.c b/src/optionstr.c index 32932e03f5..268366a37b 100644 --- a/src/optionstr.c +++ b/src/optionstr.c @@ -2592,12 +2592,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/os_unix.c b/src/os_unix.c index c422e1af7c..a8bfea4c03 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3049,6 +3049,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/proto/option.pro b/src/proto/option.pro index 49646d2c4e..ae58e61a6a 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/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/strings.c b/src/strings.c index c04cbe84f6..0aeea4bce9 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1977,6 +1977,8 @@ f_trim(typval_T *argvars, typval_T *rettv) if (argvars[1].v_type == VAR_STRING) { mask = tv_get_string_buf_chk(&argvars[1], buf2); + if (*mask == NUL) + mask = NULL; if (argvars[2].v_type != VAR_UNKNOWN) { 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_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/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..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 @@ -171,6 +178,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 +189,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) @@ -1090,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]) @@ -2570,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 @@ -2636,10 +2671,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 +2683,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', {}) - set wildoptions& wildchar& + " 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', {}) + + " 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 (|) @@ -3252,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_functions.vim b/src/testdir/test_functions.vim index d598966977..49b688c25f 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -2236,6 +2236,10 @@ func Test_trim() 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, '', 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_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/testdir/test_options.vim b/src/testdir/test_options.vim index f2f06e07df..278babe776 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' @@ -611,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", @:) " " MacVim options diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 2b8edb77aa..58983248fc 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -1355,6 +1355,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/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 b9f2910205..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 @@ -8022,4 +8085,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/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 218e70ec62..edc9548eb7 100644 --- a/src/version.c +++ b/src/version.c @@ -719,6 +719,28 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2043, +/**/ + 2042, +/**/ + 2041, +/**/ + 2040, +/**/ + 2039, +/**/ + 2038, +/**/ + 2037, +/**/ + 2036, +/**/ + 2035, +/**/ + 2034, +/**/ + 2033, /**/ 2032, /**/ 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: 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