diff --git a/.cirrus.yml b/.cirrus.yml index cfe1d8e38c..7ea83f53ad 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -5,12 +5,12 @@ env: freebsd_task: name: FreeBSD matrix: - - name: FreeBSD 13.1 + - name: FreeBSD 14.0 + freebsd_instance: + image_family: freebsd-14-0 + - name: FreeBSD 13.1 freebsd_instance: image_family: freebsd-13-1 - - name: FreeBSD 12.4 - freebsd_instance: - image_family: freebsd-12-4 timeout_in: 20m install_script: - pkg install -y gettext diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index b370182b24..8a4e3c84d1 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -2209,7 +2209,7 @@ environ() *environ()* err_teapot([{expr}]) *err_teapot()* Produce an error with number 418, needed for implementation of - RFC 2325. + RFC 2324. If {expr} is present and it is TRUE error 503 is given, indicating that coffee is temporarily not available. If {expr} is present it must be a String. @@ -6788,7 +6788,7 @@ printf({fmt}, {expr1} ...) *printf()* *printf-$* In certain languages, error and informative messages are more readable when the order of words is different from the - corresponding message in English. To accomodate translations + corresponding message in English. To accommodate translations having a different word order, positional arguments may be used to indicate this. For instance: > diff --git a/runtime/doc/channel.txt b/runtime/doc/channel.txt index 535c17546f..a8cb196e1a 100644 --- a/runtime/doc/channel.txt +++ b/runtime/doc/channel.txt @@ -1,4 +1,4 @@ -*channel.txt* For Vim version 9.0. Last change: 2022 Dec 01 +*channel.txt* For Vim version 9.0. Last change: 2023 Aug 15 VIM REFERENCE MANUAL by Bram Moolenaar @@ -956,7 +956,7 @@ job_start({command} [, {options}]) *job_start()* to String. This works best on Unix. On MS-Windows, job_start() makes a GUI application hidden. If - want to show it, Use |:!start| instead. + you want to show it, use |:!start| instead. The command is executed directly, not through a shell, the 'shell' option is not used. To use the shell: > diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index 9c092673f6..987b0d89e9 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -1,4 +1,4 @@ -*filetype.txt* For Vim version 9.0. Last change: 2023 Sep 06 +*filetype.txt* For Vim version 9.0. Last change: 2023 Sep 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -138,35 +138,38 @@ what kind of file it is. This doesn't always work. A number of global variables can be used to overrule the filetype used for certain extensions: file name variable ~ - *.asa g:filetype_asa |ft-aspvbs-syntax| |ft-aspperl-syntax| - *.asm g:asmsyntax |ft-asm-syntax| - *.asp g:filetype_asp |ft-aspvbs-syntax| |ft-aspperl-syntax| - *.bas g:filetype_bas |ft-basic-syntax| + *.asa g:filetype_asa |ft-aspperl-syntax| + |ft-aspvbs-syntax| + *.asm g:asmsyntax |ft-asm-syntax| + *.asp g:filetype_asp |ft-aspperl-syntax| + |ft-aspvbs-syntax| + *.bas g:filetype_bas |ft-basic-syntax| *.cfg g:filetype_cfg *.cls g:filetype_cls - *.csh g:filetype_csh |ft-csh-syntax| + *.csh g:filetype_csh |ft-csh-syntax| *.dat g:filetype_dat - *.f g:filetype_f |ft-forth-syntax| - *.frm g:filetype_frm |ft-form-syntax| - *.fs g:filetype_fs |ft-forth-syntax| - *.i g:filetype_i |ft-progress-syntax| + *.f g:filetype_f |ft-forth-syntax| + *.frm g:filetype_frm |ft-form-syntax| + *.fs g:filetype_fs |ft-forth-syntax| + *.h g:c_syntax_for_h |ft-c-syntax| + *.i g:filetype_i |ft-progress-syntax| *.inc g:filetype_inc *.lsl g:filetype_lsl - *.m g:filetype_m |ft-mathematica-syntax| + *.m g:filetype_m |ft-mathematica-syntax| *.mod g:filetype_mod - *.p g:filetype_p |ft-pascal-syntax| + *.p g:filetype_p |ft-pascal-syntax| *.pl g:filetype_pl - *.pp g:filetype_pp |ft-pascal-syntax| + *.pp g:filetype_pp |ft-pascal-syntax| *.prg g:filetype_prg *.r g:filetype_r *.sig g:filetype_sig - *.sql g:filetype_sql |ft-sql-syntax| + *.sql g:filetype_sql |ft-sql-syntax| *.src g:filetype_src *.sys g:filetype_sys - *.sh g:bash_is_sh |ft-sh-syntax| - *.tex g:tex_flavor |ft-tex-plugin| + *.sh g:bash_is_sh |ft-sh-syntax| + *.tex g:tex_flavor |ft-tex-plugin| *.typ g:filetype_typ - *.w g:filetype_w |ft-cweb-syntax| + *.w g:filetype_w |ft-cweb-syntax| For a few filetypes the global variable is used only when the filetype could not be detected: diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt index 6248f742f7..8696e912f3 100644 --- a/runtime/doc/insert.txt +++ b/runtime/doc/insert.txt @@ -127,7 +127,7 @@ CTRL-R {register} *i_CTRL-R* '/' the last search pattern ':' the last command-line '.' the last inserted text - *i_CTRL-R_-* + *i_CTRL-R_-* '-' the last small (less than a line) delete register. This is repeatable using |.| since it remembers the register to put instead of diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt index 7b66303d3d..b19c3067cb 100644 --- a/runtime/doc/intro.txt +++ b/runtime/doc/intro.txt @@ -1,4 +1,4 @@ -*intro.txt* For Vim version 9.0. Last change: 2023 Aug 09 +*intro.txt* For Vim version 9.0. Last change: 2023 Aug 15 VIM REFERENCE MANUAL by Bram Moolenaar @@ -215,7 +215,7 @@ Vim would never have become what it is now, without the help of these people! Eric Fischer Mac port, 'cindent', and other improvements Benji Fisher Answering lots of user questions Bill Foster Athena GUI port (later removed) - Google Lets me work on Vim one day a week + Google Let Bram work on Vim one day a week Loic Grenie xvim (ideas for multi windows version) Sven Guckes Vim promoter and previous WWW page maintainer |Sven-Guckes| Darren Hiebert Exuberant ctags diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 10aebb58d8..406f1232f2 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 9.0. Last change: 2023 Jun 02 +*options.txt* For Vim version 9.0. Last change: 2023 Aug 15 VIM REFERENCE MANUAL by Bram Moolenaar @@ -303,7 +303,7 @@ The options local to a window are remembered for each buffer. This also happens when the buffer is not loaded, but they are lost when the buffer is wiped out |:bwipe|. -Special local window options *special-local-window-option* +Special local window options *local-noglobal* The following local window options won't be copied over when new windows are created, thus they behave slightly differently: @@ -314,7 +314,7 @@ created, thus they behave slightly differently: 'winfixheight' specific to existing window 'winfixwidth' specific to existing window -Special local buffer options *special-local-buffer-option* +Special local buffer options The following local buffer options won't be copied over when new buffers are created, thus they behave slightly differently: @@ -1479,7 +1479,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'bufhidden'* *'bh'* 'bufhidden' 'bh' string (default: "") - local to buffer |special-local-buffer-option| + local to buffer |local-noglobal| This option specifies what happens when a buffer is no longer displayed in a window: follow the global 'hidden' option @@ -1511,7 +1511,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'buftype'* *'bt'* *E382* 'buftype' 'bt' string (default: "") - local to buffer |special-local-buffer-option| + local to buffer |local-noglobal| The value of this option specifies the type of a buffer: normal buffer nofile buffer which is not related to a file and will not be @@ -3448,7 +3448,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'filetype'* *'ft'* 'filetype' 'ft' string (default: "") - local to buffer |special-local-buffer-option| + local to buffer |local-noglobal| When this option is set, the FileType autocommand event is triggered. All autocommands that match with the value of this option will be executed. Thus the value of 'filetype' is used in place of the file @@ -5719,7 +5719,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'modified'* *'mod'* *'nomodified'* *'nomod'* 'modified' 'mod' boolean (default off) - local to buffer |special-local-buffer-option| + local to buffer |local-noglobal| When on, the buffer is considered to be modified. This option is set when: 1. A change was made to the text since it was last written. Using the @@ -6290,7 +6290,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'previewwindow'* *'nopreviewwindow'* *'pvw'* *'nopvw'* *E590* 'previewwindow' 'pvw' boolean (default off) - local to window |special-local-window-option| + local to window |local-noglobal| {not available when compiled without the |+quickfix| feature} Identifies the preview window. Only one window can have this option @@ -6485,7 +6485,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'readonly'* *'ro'* *'noreadonly'* *'noro'* 'readonly' 'ro' boolean (default off) - local to buffer |special-local-buffer-option| + local to buffer |local-noglobal| If on, writes fail unless you use a '!'. Protects you from accidentally overwriting a file. Default on when Vim is started in read-only mode ("vim -R") or when the executable is called "view". @@ -6864,7 +6864,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'scroll'* *'scr'* 'scroll' 'scr' number (default: half the window height) - local to window |special-local-window-option| + local to window |local-noglobal| Number of lines to scroll with CTRL-U and CTRL-D commands. Will be set to half the number of lines in the window when the window size changes. This may happen when enabling the |status-line| or @@ -8126,7 +8126,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'syntax'* *'syn'* 'syntax' 'syn' string (default empty) - local to buffer |special-local-buffer-option| + local to buffer |local-noglobal| {not available when compiled without the |+syntax| feature} When this option is set, the syntax with this name is loaded, unless @@ -9587,7 +9587,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'winfixheight'* *'wfh'* *'nowinfixheight'* *'nowfh'* 'winfixheight' 'wfh' boolean (default off) - local to window |special-local-window-option| + local to window |local-noglobal| Keep the window height when windows are opened or closed and 'equalalways' is set. Also for |CTRL-W_=|. Set by default for the |preview-window| and |quickfix-window|. @@ -9595,7 +9595,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'winfixwidth'* *'wfw'* *'nowinfixwidth'* *'nowfw'* 'winfixwidth' 'wfw' boolean (default off) - local to window |special-local-window-option| + local to window |local-noglobal| Keep the window width when windows are opened or closed and 'equalalways' is set. Also for |CTRL-W_=|. The width may be changed anyway when running out of room. diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 7a36369479..001c395a36 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -2160,11 +2160,11 @@ should set a variable in your .vimrc file: > :let lpc_syntax_for_c = 1 If it doesn't work properly for some particular C or LPC files, use a -modeline. For a LPC file: +modeline. For a LPC file: > // vim:set ft=lpc: -For a C file that is recognized as LPC: +For a C file that is recognized as LPC: > // vim:set ft=c: @@ -2196,7 +2196,7 @@ LUA *lua.vim* *ft-lua-syntax* The Lua syntax file can be used for versions 4.0, 5.0, 5.1 and 5.2 (5.2 is the default). You can select one of these versions using the global variables lua_version and lua_subversion. For example, to activate Lua -5.1 syntax highlighting, set the variables like this: +5.1 syntax highlighting, set the variables like this: > :let lua_version = 5 :let lua_subversion = 1 diff --git a/runtime/doc/tags b/runtime/doc/tags index 9af7a93c09..8aa43ad5fe 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -8449,6 +8449,7 @@ load-plugins starting.txt /*load-plugins* load-vim-script repeat.txt /*load-vim-script* local-additions help.txt /*local-additions* local-function userfunc.txt /*local-function* +local-noglobal options.txt /*local-noglobal* local-options options.txt /*local-options* local-variable eval.txt /*local-variable* local-variables userfunc.txt /*local-variables* @@ -9897,8 +9898,6 @@ spec_chglog_format pi_spec.txt /*spec_chglog_format* spec_chglog_prepend pi_spec.txt /*spec_chglog_prepend* spec_chglog_release_info pi_spec.txt /*spec_chglog_release_info* special-buffers windows.txt /*special-buffers* -special-local-buffer-option options.txt /*special-local-buffer-option* -special-local-window-option options.txt /*special-local-window-option* specifies vim9class.txt /*specifies* speed-up tips.txt /*speed-up* spell spell.txt /*spell* diff --git a/runtime/doc/tips.txt b/runtime/doc/tips.txt index 79b1574e22..0dfddb2551 100644 --- a/runtime/doc/tips.txt +++ b/runtime/doc/tips.txt @@ -1,4 +1,4 @@ -*tips.txt* For Vim version 9.0. Last change: 2021 Nov 06 +*tips.txt* For Vim version 9.0. Last change: 2023 Aug 10 VIM REFERENCE MANUAL by Bram Moolenaar diff --git a/runtime/doc/usr_05.txt b/runtime/doc/usr_05.txt index f43b239564..0ab0301991 100644 --- a/runtime/doc/usr_05.txt +++ b/runtime/doc/usr_05.txt @@ -1,4 +1,4 @@ -*usr_05.txt* For Vim version 9.0. Last change: 2019 May 23 +*usr_05.txt* For Vim version 9.0. Last change: 2023 Aug 10 VIM USER MANUAL - by Bram Moolenaar diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt index e9549285ff..95b766d6c8 100644 --- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -44,12 +44,12 @@ He registered the vim.org domain and created the first Vim website. We will remember him! *Bram* *Moolenaar* *Bram-Moolenaar* -Vim version 9.1 is dedicated to Bram Moolenaar, who passed away on August 3rd 2023 -while still working full-time on Vim. The Vim project would not exist without -his ongoing passion to lead and develop Vim and the community for more than 30 -years. Bram was also passionate about his |ICCF| foundation to help children -in Uganda. If you enjoy using Vim, please consider donating! -We will miss his guidance, passion and leadership. +Vim version 9.1 is dedicated to Bram Moolenaar, who passed away on August 3rd +2023 while still working full-time on Vim. The Vim project would not exist +without his ongoing passion to lead and develop Vim and the community for more +than 30 years. Bram was also passionate about his |ICCF| foundation to help +children in Uganda. If you enjoy using Vim, please consider donating! We will +miss his guidance, passion and leadership. Obituary Articles: https://github.com/vim/vim/discussions/12742 Say Farewell: https://github.com/vim/vim/discussions/12737 diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index 924a932507..74cec42303 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -189,7 +189,7 @@ CTRL-W v *CTRL-W_v* it doesn't! CTRL-W n *CTRL-W_n* -CTRL-W CTRL_N *CTRL-W_CTRL-N* +CTRL-W CTRL-N *CTRL-W_CTRL-N* :[N]new [++opt] [+cmd] *:new* Create a new window and start editing an empty file in it. Make new window N high (default is to use half the existing diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 81764c1b59..9b7e698c21 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1368,6 +1368,10 @@ au BufNewFile,BufRead *.rc,*.rch \ setf rc | \ endif +" Mojo +" Mojo files use either .mojo or .🔥 as extension +au BufNewFile,BufRead *.mojo,*.🔥 setf mojo + " MuPAD source au BufRead,BufNewFile *.mu setf mupad diff --git a/runtime/ftplugin/zig.vim b/runtime/ftplugin/zig.vim index 2a081980cc..cfd7102b8d 100644 --- a/runtime/ftplugin/zig.vim +++ b/runtime/ftplugin/zig.vim @@ -39,7 +39,7 @@ endif let &l:define='\v(|||^\s*\#\s*define)' -" Safety check: don't execute zip from current directory +" Safety check: don't execute zig from current directory if !exists('g:zig_std_dir') && exists('*json_decode') && \ executable('zig') && get(g:, 'zig_exec', get(g:, 'plugin_exec', 0)) \ && (fnamemodify(exepath("zig"), ":p:h") != s:tmp_cwd diff --git a/runtime/syntax/i3config.vim b/runtime/syntax/i3config.vim index caef244ce5..1eddd60f7c 100644 --- a/runtime/syntax/i3config.vim +++ b/runtime/syntax/i3config.vim @@ -2,8 +2,9 @@ " Language: i3 config file " Original Author: Mohamed Boughaba " Maintainer: Quentin Hibon (github user hiqua) -" Version: 0.4 -" Last Change: 2022 Jun 05 +" Version: 0.4.22 +" Reference version (JosefLitos/i3config.vim): 4.22 +" Last Change: 2023-09-09 " References: " http://i3wm.org/docs/userguide.html#configuring @@ -18,7 +19,7 @@ endif scriptencoding utf-8 " Error -syn match i3ConfigError /.*/ +syn match i3ConfigError /.\+/ " Todo syn keyword i3ConfigTodo TODO FIXME XXX contained @@ -27,238 +28,280 @@ syn keyword i3ConfigTodo TODO FIXME XXX contained " Comments are started with a # and can only be used at the beginning of a line syn match i3ConfigComment /^\s*#.*$/ contains=i3ConfigTodo +syn match i3ConfigOperator /[,;:]/ contained +syn match i3ConfigParen /[{}]/ contained + " Font " A FreeType font description is composed by: " a font family, a style, a weight, a variant, a stretch and a size. -syn match i3ConfigFontSeparator /,/ contained -syn match i3ConfigFontSeparator /:/ contained syn keyword i3ConfigFontKeyword font contained -syn match i3ConfigFontNamespace /\w\+:/ contained contains=i3ConfigFontSeparator -syn match i3ConfigFontContent /-\?\w\+\(-\+\|\s\+\|,\)/ contained contains=i3ConfigFontNamespace,i3ConfigFontSeparator,i3ConfigFontKeyword +syn match i3ConfigFontNamespace /\w\+:/ contained contains=i3ConfigOperator +syn match i3ConfigFontContent /-\?\w\+\(-\+\|\s\+\|,\)/ contained contains=i3ConfigFontNamespace,i3ConfigFontKeyword,i3ConfigOperator syn match i3ConfigFontSize /\s\=\d\+\(px\)\?\s\?$/ contained -syn match i3ConfigFont /^\s*font\s\+.*$/ contains=i3ConfigFontContent,i3ConfigFontSeparator,i3ConfigFontSize,i3ConfigFontNamespace -syn match i3ConfigFont /^\s*font\s\+.*\(\\\_.*\)\?$/ contains=i3ConfigFontContent,i3ConfigFontSeparator,i3ConfigFontSize,i3ConfigFontNamespace -syn match i3ConfigFont /^\s*font\s\+.*\(\\\_.*\)\?[^\\]\+$/ contains=i3ConfigFontContent,i3ConfigFontSeparator,i3ConfigFontSize,i3ConfigFontNamespace -syn match i3ConfigFont /^\s*font\s\+\(\(.*\\\_.*\)\|\(.*[^\\]\+$\)\)/ contains=i3ConfigFontContent,i3ConfigFontSeparator,i3ConfigFontSize,i3ConfigFontNamespace +syn match i3ConfigFont /^\s*font\s\+.*$/ contains=i3ConfigFontContent,i3ConfigFontSize,i3ConfigFontNamespace +syn match i3ConfigFont /^\s*font\s\+.*\(\\\_.*\)\?$/ contains=i3ConfigFontContent,i3ConfigFontSize,i3ConfigFontNamespace +syn match i3ConfigFont /^\s*font\s\+.*\(\\\_.*\)\?[^\\]\+$/ contains=i3ConfigFontContent,i3ConfigFontSize,i3ConfigFontNamespace +syn match i3ConfigFont /^\s*font\s\+\(\(.*\\\_.*\)\|\(.*[^\\]\+$\)\)/ contains=i3ConfigFontContent,i3ConfigFontSize,i3ConfigFontNamespace -" variables -syn match i3ConfigString /\(['"]\)\(.\{-}\)\1/ contained -syn match i3ConfigColor /#\w\{6}/ contained -syn match i3ConfigVariableModifier /+/ contained -syn match i3ConfigVariableAndModifier /+\w\+/ contained contains=i3ConfigVariableModifier -syn match i3ConfigVariable /\$\w\+\(\(-\w\+\)\+\)\?\(\s\|+\)\?/ contains=i3ConfigVariableModifier,i3ConfigVariableAndModifier -syn keyword i3ConfigInitializeKeyword set contained -syn match i3ConfigInitialize /^\s*set\s\+.*$/ contains=i3ConfigVariable,i3ConfigInitializeKeyword,i3ConfigColor,i3ConfigString +" Common value types +syn keyword i3ConfigBoolean yes no enabled disabled on off true false contained +syn region i3ConfigString start=/"/ skip=/\\"/ end=/"/ contained contains=i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigVariable keepend extend +syn region i3ConfigString start=/'/ end=/'/ contained contains=i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigVariable keepend extend +syn match i3ConfigColor /#\w\{3,8}/ contained +syn match i3ConfigNumber /\([a-zA-Z0-9_$]\)\@&|+=~^*!.?]\+/ contained +syn match i3ConfigShParam /\<-[a-zA-Z0-9_-]\+\>/ contained containedin=i3ConfigVar +syn region i3ConfigExec start=/exec\(_always\)\?\( --no-startup-id\)\? [^{]/ skip=/\\$/ end=/\([,;]\|$\)/ contains=i3ConfigExecKeyword,i3ConfigExecAlwaysKeyword,i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigString,i3ConfigVariable,i3ConfigOperator keepend extend " Automatically putting workspaces on specific screens syn keyword i3ConfigWorkspaceKeyword workspace contained syn keyword i3ConfigOutput output contained -syn match i3ConfigWorkspace /^\s*workspace\s\+.*$/ contains=i3ConfigWorkspaceKeyword,i3ConfigNumber,i3ConfigString,i3ConfigOutput +syn match i3ConfigWorkspace /^\s*workspace\s\+.*$/ contains=i3ConfigWorkspaceKeyword,i3ConfigNumber,i3ConfigString,i3ConfigOutput,i3ConfigVariable,i3ConfigBoolean " Changing colors syn keyword i3ConfigClientColorKeyword client focused focused_inactive unfocused urgent placeholder background contained syn match i3ConfigClientColor /^\s*client.\w\+\s\+.*$/ contains=i3ConfigClientColorKeyword,i3ConfigColor,i3ConfigVariable syn keyword i3ConfigTitleAlignKeyword left center right contained -syn match i3ConfigTitleAlign /^\s*title_align\s\+.*$/ contains=i3ConfigTitleAlignKeyword +syn match i3ConfigTitleAlign /^title_align .*$/ contains=i3ConfigTitleAlignKeyword " Interprocess communication syn match i3ConfigInterprocessKeyword /ipc-socket/ contained -syn match i3ConfigInterprocess /^\s*ipc-socket\s\+.*$/ contains=i3ConfigInterprocessKeyword +syn match i3ConfigInterprocess /^ipc-socket .*$/ contains=i3ConfigInterprocessKeyword " Mouse warping syn keyword i3ConfigMouseWarpingKeyword mouse_warping contained -syn keyword i3ConfigMouseWarpingType output none contained -syn match i3ConfigMouseWarping /^\s*mouse_warping\s\+\(output\|none\)\s\?$/ contains=i3ConfigMouseWarpingKeyword,i3ConfigMouseWarpingType +syn keyword i3ConfigMouseWarpingType output container none contained +syn match i3ConfigMouseWarping /^mouse_warping \(output\|container\|none\)$/ contains=i3ConfigMouseWarpingKeyword,i3ConfigMouseWarpingType " Focus follows mouse syn keyword i3ConfigFocusFollowsMouseKeyword focus_follows_mouse contained -syn keyword i3ConfigFocusFollowsMouseType yes no contained -syn match i3ConfigFocusFollowsMouse /^\s*focus_follows_mouse\s\+\(yes\|no\)\s\?$/ contains=i3ConfigFocusFollowsMouseKeyword,i3ConfigFocusFollowsMouseType - -" Popups during fullscreen mode -syn keyword i3ConfigPopupOnFullscreenKeyword popup_during_fullscreen contained -syn keyword i3ConfigPopuponFullscreenType smart ignore leave_fullscreen contained -syn match i3ConfigPopupOnFullscreen /^\s*popup_during_fullscreen\s\+\w\+\s\?$/ contains=i3ConfigPopupOnFullscreenKeyword,i3ConfigPopupOnFullscreenType +syn keyword i3ConfigFocusFollowsMouseType always contained +syn match i3ConfigFocusFollowsMouse /^focus_follows_mouse \(yes\|no\|always\)$/ contains=i3ConfigFocusFollowsMouseKeyword,i3ConfigBoolean,i3ConfigFocusFollowsMouseType " Focus wrapping syn keyword i3ConfigFocusWrappingKeyword force_focus_wrapping focus_wrapping contained -syn keyword i3ConfigFocusWrappingType yes no contained -syn match i3ConfigFocusWrapping /^\s*\(force_\)\?focus_wrapping\s\+\(yes\|no\)\s\?$/ contains=i3ConfigFocusWrappingType,i3ConfigFocusWrappingKeyword +syn keyword i3ConfigFocusWrappingType force workspace contained +syn match i3ConfigFocusWrapping /^focus_wrapping \(yes\|no\|force\|workspace\)$/ contains=i3ConfigBoolean,i3ConfigFocusWrappingKeyword,i3ConfigFocusWrappingType + +" Popups during fullscreen mode +syn keyword i3ConfigPopupOnFullscreenKeyword popup_during_fullscreen contained +syn keyword i3ConfigPopupOnFullscreenType smart ignore leave_fullscreen contained +syn match i3ConfigPopupOnFullscreen /^popup_during_fullscreen \w\+$/ contains=i3ConfigPopupOnFullscreenKeyword,i3ConfigPopupOnFullscreenType " Forcing Xinerama syn keyword i3ConfigForceXineramaKeyword force_xinerama contained -syn match i3ConfigForceXinerama /^\s*force_xinerama\s\+\(yes\|no\)\s\?$/ contains=i3ConfigFocusWrappingType,i3ConfigForceXineramaKeyword +syn match i3ConfigForceXinerama /^force_xinerama \(yes\|no\)$/ contains=i3ConfigBoolean,i3ConfigForceXineramaKeyword " Automatic back-and-forth when switching to the current workspace syn keyword i3ConfigAutomaticSwitchKeyword workspace_auto_back_and_forth contained -syn match i3ConfigAutomaticSwitch /^\s*workspace_auto_back_and_forth\s\+\(yes\|no\)\s\?$/ contains=i3ConfigFocusWrappingType,i3ConfigAutomaticSwitchKeyword +syn match i3ConfigAutomaticSwitch /^workspace_auto_back_and_forth \(yes\|no\)$/ contains=i3ConfigBoolean,i3ConfigAutomaticSwitchKeyword " Delay urgency hint syn keyword i3ConfigTimeUnit ms contained syn keyword i3ConfigDelayUrgencyKeyword force_display_urgency_hint contained -syn match i3ConfigDelayUrgency /^\s*force_display_urgency_hint\s\+\d\+\s\+ms\s\?$/ contains=i3ConfigFocusWrappingType,i3ConfigDelayUrgencyKeyword,i3ConfigNumber,i3ConfigTimeUnit +syn match i3ConfigDelayUrgency /^force_display_urgency_hint \d\+ ms$/ contains=i3ConfigBoolean,i3ConfigDelayUrgencyKeyword,i3ConfigNumber,i3ConfigTimeUnit " Focus on window activation syn keyword i3ConfigFocusOnActivationKeyword focus_on_window_activation contained syn keyword i3ConfigFocusOnActivationType smart urgent focus none contained -syn match i3ConfigFocusOnActivation /^\s*focus_on_window_activation\s\+\(smart\|urgent\|focus\|none\)\s\?$/ contains=i3ConfigFocusOnActivationKeyword,i3ConfigFocusOnActivationType +syn match i3ConfigFocusOnActivation /^focus_on_window_activation \(smart\|urgent\|focus\|none\)$/ contains=i3ConfigFocusOnActivationKeyword,i3ConfigFocusOnActivationType -" Automatic back-and-forth when switching to the current workspace -syn keyword i3ConfigDrawingMarksKeyword show_marks contained -syn match i3ConfigDrawingMarks /^\s*show_marks\s\+\(yes\|no\)\s\?$/ contains=i3ConfigFocusWrappingType,i3ConfigDrawingMarksKeyword +" Show window marks in their window title +syn keyword i3ConfigShowMarksKeyword show_marks contained +syn match i3ConfigShowMarks /^show_marks \(yes\|no\)$/ contains=i3ConfigBoolean,i3ConfigShowMarksKeyword -" Group mode/bar -syn keyword i3ConfigBlockKeyword mode bar colors i3bar_command status_command position exec mode hidden_state modifier id position output background statusline tray_output tray_padding separator separator_symbol workspace_min_width workspace_buttons strip_workspace_numbers binding_mode_indicator focused_workspace active_workspace inactive_workspace urgent_workspace binding_mode contained -syn region i3ConfigBlock start=+^\s*[^#]*s\?{$+ end=+^\s*[^#]*}$+ contains=i3ConfigBlockKeyword,i3ConfigString,i3ConfigBind,i3ConfigComment,i3ConfigFont,i3ConfigFocusWrappingType,i3ConfigColor,i3ConfigVariable transparent keepend extend +" Mode block +syn match i3ConfigModeKeyword /^mode/ contained +syn region i3ConfigModeBlock start=/^mode\( --pango_markup\)\? \([^'" {]\+\|'[^']\+'\|".\+"\)\s\+{$/ end=/^\s*}$/ contains=i3ConfigModeKeyword,i3ConfigString,i3ConfigBind,i3ConfigComment,i3ConfigNumber,i3ConfigParen,i3ConfigVariable fold keepend extend -" Line continuation -syn region i3ConfigLineCont start=/^.*\\$/ end=/^.*$/ contains=i3ConfigBlockKeyword,i3ConfigString,i3ConfigBind,i3ConfigComment,i3ConfigFont,i3ConfigFocusWrappingType,i3ConfigColor,i3ConfigVariable transparent keepend extend +" Color block +syn keyword i3ConfigColorsKeyword colors contained +syn match i3ConfigColorsCategory /\(focused_\)\?\(background\|statusline\|separator\)\|\(focused\|active\|inactive\|urgent\)_workspace\|binding_mode/ contained +syn region i3ConfigColorsBlock start=/^\s\+colors {$/ end=/^\s\+}$/ contained contains=i3ConfigColorsKeyword,i3ConfigColorsCategory,i3ConfigColor,i3ConfigVariable,i3ConfigComment,i3ConfigParen fold keepend extend + +" Bar block +syn keyword i3ConfigBarBlockKeyword bar i3bar_command status_command mode hidden_state id position output tray_output tray_padding font separator_symbol workspace_buttons workspace_min_width strip_workspace_numbers strip_workspace_name binding_mode_indicator padding contained +syn keyword i3ConfigBarModifierKeyword modifier contained +syn match i3ConfigBarModifierLine /^\s\+modifier [^ ]\+$/ contained contains=i3ConfigBarModifierKeyword,i3ConfigBindModifier,i3ConfigVariable,i3ConfigBindModkey +syn region i3ConfigBarBlock start=/^bar {$/ end=/^}$/ contains=i3ConfigBarBlockKeyword,i3ConfigBarModifierLine,i3ConfigBind,i3ConfigString,i3ConfigComment,i3ConfigFont,i3ConfigBoolean,i3ConfigNumber,i3ConfigOperator,i3ConfigParen,i3ConfigColor,i3ConfigVariable,i3ConfigColorsBlock fold keepend extend " Define the highlighting. +hi def link i3ConfigKeyword Keyword +hi def link i3ConfigCommand Statement hi def link i3ConfigError Error hi def link i3ConfigTodo Todo hi def link i3ConfigComment Comment -hi def link i3ConfigFontContent Type -hi def link i3ConfigFocusOnActivationType Type -hi def link i3ConfigPopupOnFullscreenType Type -hi def link i3ConfigOrientationKeyword Type -hi def link i3ConfigMouseWarpingType Type -hi def link i3ConfigFocusFollowsMouseType Type -hi def link i3ConfigGapStyleKeyword Type -hi def link i3ConfigTitleAlignKeyword Type -hi def link i3ConfigSmartGapKeyword Type -hi def link i3ConfigSmartBorderKeyword Type -hi def link i3ConfigLayoutKeyword Type -hi def link i3ConfigBorderStyleKeyword Type -hi def link i3ConfigEdgeKeyword Type -hi def link i3ConfigAction Type -hi def link i3ConfigCommand Type -hi def link i3ConfigOutput Type -hi def link i3ConfigWindowCommandSpecial Type -hi def link i3ConfigFocusWrappingType Type -hi def link i3ConfigUnitOr Type -hi def link i3ConfigFontSize Constant +hi def link i3ConfigOperator Operator +hi def link i3ConfigParen Delimiter +hi def link i3ConfigFontKeyword i3ConfigKeyword +hi def link i3ConfigFontNamespace i3ConfigOption +hi def link i3ConfigFontContent String +hi def link i3ConfigFontSize Number +hi def link i3ConfigString String +hi def link i3ConfigNumber Number +hi def link i3ConfigBoolean Boolean hi def link i3ConfigColor Constant -hi def link i3ConfigNumber Constant -hi def link i3ConfigUnit Constant -hi def link i3ConfigVariableAndModifier Constant -hi def link i3ConfigTimeUnit Constant -hi def link i3ConfigModifier Constant -hi def link i3ConfigString Constant -hi def link i3ConfigNegativeSize Constant -hi def link i3ConfigInclude Constant -hi def link i3ConfigFontSeparator Special -hi def link i3ConfigVariableModifier Special -hi def link i3ConfigSizeSpecial Special -hi def link i3ConfigWindowSpecial Special -hi def link i3ConfigAssignSpecial Special -hi def link i3ConfigFontNamespace PreProc -hi def link i3ConfigBindArgument PreProc -hi def link i3ConfigNoStartupId PreProc -hi def link i3ConfigIncludeKeyword Identifier -hi def link i3ConfigFontKeyword Identifier -hi def link i3ConfigBindKeyword Identifier -hi def link i3ConfigOrientation Identifier -hi def link i3ConfigGapStyle Identifier -hi def link i3ConfigTitleAlign Identifier -hi def link i3ConfigSmartGap Identifier -hi def link i3ConfigSmartBorder Identifier -hi def link i3ConfigLayout Identifier -hi def link i3ConfigBorderStyle Identifier -hi def link i3ConfigEdge Identifier -hi def link i3ConfigFloating Identifier -hi def link i3ConfigFloatingModifier Identifier -hi def link i3ConfigCommandKeyword Identifier -hi def link i3ConfigNoFocusKeyword Identifier -hi def link i3ConfigInitializeKeyword Identifier -hi def link i3ConfigAssignKeyword Identifier -hi def link i3ConfigResourceKeyword Identifier -hi def link i3ConfigExecKeyword Identifier -hi def link i3ConfigWorkspaceKeyword Identifier -hi def link i3ConfigClientColorKeyword Identifier -hi def link i3ConfigInterprocessKeyword Identifier -hi def link i3ConfigMouseWarpingKeyword Identifier -hi def link i3ConfigFocusFollowsMouseKeyword Identifier -hi def link i3ConfigPopupOnFullscreenKeyword Identifier -hi def link i3ConfigFocusWrappingKeyword Identifier -hi def link i3ConfigForceXineramaKeyword Identifier -hi def link i3ConfigAutomaticSwitchKeyword Identifier -hi def link i3ConfigDelayUrgencyKeyword Identifier -hi def link i3ConfigFocusOnActivationKeyword Identifier -hi def link i3ConfigDrawingMarksKeyword Identifier -hi def link i3ConfigBlockKeyword Identifier -hi def link i3ConfigVariable Statement -hi def link i3ConfigArbitraryCommand Type +hi def link i3ConfigVariable Variable +hi def link i3ConfigSetKeyword i3ConfigKeyword +hi def link i3ConfigIncludeKeyword i3ConfigKeyword +hi def link i3ConfigCommandSubstitutionDelimiter Delimiter +hi def link i3ConfigIncludePath String +hi def link i3ConfigGapStyleKeyword i3ConfigOption +hi def link i3ConfigGapStyle i3ConfigCommand +hi def link i3ConfigSmartGapKeyword i3ConfigOption +hi def link i3ConfigSmartGap i3ConfigKeyword +hi def link i3ConfigSmartBorderKeyword i3ConfigOption +hi def link i3ConfigSmartBorder i3ConfigKeyword +hi def link i3ConfigAction i3ConfigCommand +hi def link i3ConfigOption Type +hi def link i3ConfigUnit i3ConfigNumber +hi def link i3ConfigUnitOr i3ConfigOperator +hi def link i3ConfigBindKeyword i3ConfigKeyword +hi def link i3ConfigBindModkey Special +hi def link i3ConfigBindCombo SpecialChar +hi def link i3ConfigBindModifier i3ConfigOperator +hi def link i3ConfigBindArgument i3ConfigShParam +hi def link i3ConfigFloatingModifierKeyword i3ConfigKeyword +hi def link i3ConfigSizeSpecial i3ConfigOperator +hi def link i3ConfigFloatingSizeKeyword i3ConfigKeyword +hi def link i3ConfigOrientationKeyword i3ConfigOption +hi def link i3ConfigOrientation i3ConfigKeyword +hi def link i3ConfigLayoutKeyword i3ConfigOption +hi def link i3ConfigLayout i3ConfigKeyword +hi def link i3ConfigBorderStyleKeyword i3ConfigOption +hi def link i3ConfigBorderStyle i3ConfigKeyword +hi def link i3ConfigEdgeKeyword i3ConfigOption +hi def link i3ConfigEdge i3ConfigKeyword +hi def link i3ConfigCommandKeyword i3ConfigKeyword +hi def link i3ConfigEqualsOperator i3ConfigOperator +hi def link i3ConfigConditionalText Conditional +hi def link i3ConfigConditional Delimiter +hi def link i3ConfigNoFocusKeyword i3ConfigKeyword +hi def link i3ConfigAssignKeyword i3ConfigKeyword +hi def link i3ConfigAssignSpecial i3ConfigOption +hi def link i3ConfigResourceKeyword i3ConfigKeyword +hi def link i3ConfigShParam PreProc +hi def link i3ConfigShDelim Delimiter +hi def link i3ConfigShOper Operator +hi def link i3ConfigShCmdDelim i3ConfigShDelim +hi def link i3ConfigShCommand Normal +hi def link i3ConfigExecKeyword i3ConfigCommand +hi def link i3ConfigExecAlwaysKeyword i3ConfigKeyword +hi def link i3ConfigWorkspaceKeyword i3ConfigCommand +hi def link i3ConfigOutput i3ConfigOption +hi def link i3ConfigClientColorKeyword i3ConfigKeyword +hi def link i3ConfigClientColor Operator +hi def link i3ConfigTitleAlignKeyword i3ConfigOption +hi def link i3ConfigTitleAlign i3ConfigKeyword +hi def link i3ConfigInterprocessKeyword i3ConfigKeyword +hi def link i3ConfigMouseWarpingKeyword i3ConfigKeyword +hi def link i3ConfigMouseWarpingType i3ConfigOption +hi def link i3ConfigFocusFollowsMouseKeyword i3ConfigKeyword +hi def link i3ConfigFocusFollowsMouseType i3ConfigOption +hi def link i3ConfigFocusWrappingKeyword i3ConfigKeyword +hi def link i3ConfigFocusWrappingType i3ConfigOption +hi def link i3ConfigPopupOnFullscreenKeyword i3ConfigKeyword +hi def link i3ConfigPopupOnFullscreenType i3ConfigOption +hi def link i3ConfigForceXineramaKeyword i3ConfigKeyword +hi def link i3ConfigAutomaticSwitchKeyword i3ConfigKeyword +hi def link i3ConfigTimeUnit i3ConfigNumber +hi def link i3ConfigDelayUrgencyKeyword i3ConfigKeyword +hi def link i3ConfigFocusOnActivationKeyword i3ConfigKeyword +hi def link i3ConfigFocusOnActivationType i3ConfigOption +hi def link i3ConfigShowMarksKeyword i3ConfigKeyword +hi def link i3ConfigModeKeyword i3ConfigKeyword +hi def link i3ConfigColorsKeyword i3ConfigKeyword +hi def link i3ConfigColorsCategory Type +hi def link i3ConfigBarModifierKeyword i3ConfigKeyword +hi def link i3ConfigBarBlockKeyword i3ConfigKeyword let b:current_syntax = "i3config" diff --git a/runtime/syntax/masm.vim b/runtime/syntax/masm.vim index 3be0fd45d1..85e457106d 100644 --- a/runtime/syntax/masm.vim +++ b/runtime/syntax/masm.vim @@ -2,7 +2,7 @@ " Language: Microsoft Macro Assembler (80x86) " Orig Author: Rob Brady " Maintainer: Wu Yongwei -" Last Change: 2022-04-24 20:07:04 +0800 +" Last Change: 2023-09-09 20:48:26 +0800 " Quit when a syntax file was already loaded if exists("b:current_syntax") @@ -194,8 +194,8 @@ syn keyword masmRegister R8W R9W R10W R11W R12W R13W R14W R15W syn keyword masmRegister R8B R9B R10B R11B R12B R13B R14B R15B " SSE/AVX registers -syn match masmRegister "\(X\|Y\)MM[0-9]\>" -syn match masmRegister "\(X\|Y\)MM1[0-5]\>" +syn match masmRegister "\(X\|Y\|Z\)MM[12]\?[0-9]\>" +syn match masmRegister "\(X\|Y\|Z\)MM3[01]\>" " Instruction prefixes syn keyword masmOpcode LOCK REP REPE REPNE REPNZ REPZ @@ -338,11 +338,192 @@ syn keyword masmOpcode VINSERTF128 VEXTRACTF128 VMASKMOVPS VMASKMOVPD syn keyword masmOpcode VPERMILPS VPERMILPD VPERM2F128 syn keyword masmOpcode VZEROALL VZEROUPPER +" AVX-2 (Haswell and later) +syn keyword masmOpcode VPBROADCASTB VPBROADCASTW VPBROADCASTD +syn keyword masmOpcode VPBROADCASTQ VBROADCASTI128 +syn keyword masmOpcode VINSERTI128 VEXTRACTI128 +syn keyword masmOpcode VGATHERDPD VGATHERQPD VGATHERDPS VGATHERQPS +syn keyword masmOpcode VPGATHERDD VPGATHERDQ VPGATHERQD VPGATHERQQ +syn keyword masmOpcode VPMASKMOVD VPMASKMOVQ +syn keyword masmOpcode PERMPS VPERMD VPERMPD VPERMQ VPERM2I128 +syn keyword masmOpcode VPBLENDD VPSLLVD VPSLLVQ VPSRLVD VPSRLVQ +syn keyword masmOpcode VPSRAVD + +" AVX-512 (Knights Landing/Skylake-X and later) +syn keyword masmOpcode KAND KANDN KMOV KUNPCK KNOT KOR KORTEST +syn keyword masmOpcode KSHIFTL KSHIFTR KXNOR KXOR KADD KTEST +syn keyword masmOpcode VBLENDMPD VBLENDMPS +syn keyword masmOpcode VPBLENDMD VPBLENDMQ VPBLENDMB VPBLENDMW +syn keyword masmOpcode VPCMPD VPCMPUD VPCMPQ VPCMPUQ +syn keyword masmOpcode VPCMPB VPCMPUB VPCMPW VPCMPUW +syn keyword masmOpcode VPTESTMD VPTESTMQ VPTESTNMD VPTESTNMQ +syn keyword masmOpcode VPTESTMB VPTESTMW VPTESTNMB VPTESTNMW +syn keyword masmOpcode VCOMPRESSPD VCOMPRESSPS VPCOMPRESSD VPCOMPRESSQ +syn keyword masmOpcode VEXPANDPD VEXPANDPS VPEXPANDD VPEXPANDQ +syn keyword masmOpcode VPERMB VPERMW VPERMT2B VPERMT2W VPERMI2PD +syn keyword masmOpcode VPERMI2PS VPERMI2D VPERMI2Q VPERMI2B VPERMI2W +syn keyword masmOpcode VPERMT2PS VPERMT2PD VPERMT2D VPERMT2Q +syn keyword masmOpcode VSHUFF32x4 VSHUFF64x2 VSHUFI32x4 VSHUFI64x2 +syn keyword masmOpcode VPMULTISHIFTQB VPTERNLOGD VPTERNLOGQ +syn keyword masmOpcode VPMOVQD VPMOVSQD VPMOVUSQD VPMOVQW VPMOVSQW +syn keyword masmOpcode VPMOVUSQW VPMOVQB VPMOVSQB VPMOVUSQB VPMOVDW +syn keyword masmOpcode VPMOVSDW VPMOVUSDW VPMOVDB VPMOVSDB VPMOVUSDB +syn keyword masmOpcode VPMOVWB VPMOVSWB VPMOVUSWB +syn keyword masmOpcode VCVTPS2UDQ VCVTPD2UDQ VCVTTPS2UDQ VCVTTPD2UDQ +syn keyword masmOpcode VCVTSS2USI VCVTSD2USI VCVTTSS2USI VCVTTSD2USI +syn keyword masmOpcode VCVTPS2QQ VCVTPD2QQ VCVTPS2UQQ VCVTPD2UQQ +syn keyword masmOpcode VCVTTPS2QQ VCVTTPD2QQ VCVTTPS2UQQ VCVTTPD2UQQ +syn keyword masmOpcode VCVTUDQ2PS VCVTUDQ2PD VCVTUSI2PS VCVTUSI2PD +syn keyword masmOpcode VCVTUSI2SD VCVTUSI2SS VCVTUQQ2PS VCVTUQQ2PD +syn keyword masmOpcode VCVTQQ2PD VCVTQQ2PS VGETEXPPD +syn keyword masmOpcode VGETEXPPS VGETEXPSD VGETEXPSS +syn keyword masmOpcode VGETMANTPD VGETMANTPS VGETMANTSD VGETMANTSS +syn keyword masmOpcode VFIXUPIMMPD VFIXUPIMMPS VFIXUPIMMSD VFIXUPIMMSS +syn keyword masmOpcode VRCP14PD VRCP14PS VRCP14SD VRCP14SS +syn keyword masmOpcode VRNDSCALEPS VRNDSCALEPD VRNDSCALESS VRNDSCALESD +syn keyword masmOpcode VRSQRT14PD VRSQRT14PS VRSQRT14SD VRSQRT14SS +syn keyword masmOpcode VSCALEFPS VSCALEFPD VSCALEFSS VSCALEFSD +syn keyword masmOpcode VBROADCASTI32X2 VBROADCASTI32X4 VBROADCASTI32X8 +syn keyword masmOpcode VBROADCASTI64X2 VBROADCASTI64X4 +syn keyword masmOpcode VALIGND VALIGNQ VDBPSADBW VPABSQ VPMAXSQ +syn keyword masmOpcode VPMAXUQ VPMINSQ VPMINUQ VPROLD VPROLVD VPROLQ +syn keyword masmOpcode VPROLVQ VPRORD VPRORVD VPRORQ VPRORVQ +syn keyword masmOpcode VPSCATTERDD VPSCATTERDQ VPSCATTERQD VPSCATTERQQ +syn keyword masmOpcode VSCATTERDPS VSCATTERDPD VSCATTERQPS VSCATTERQPD +syn keyword masmOpcode VPCONFLICTD VPCONFLICTQ VPLZCNTD VPLZCNTQ +syn keyword masmOpcode VPBROADCASTMB2Q VPBROADCASTMW2D +syn keyword masmOpcode VEXP2PD VEXP2PS +syn keyword masmOpcode VRCP28PD VRCP28PS VRCP28SD VRCP28SS +syn keyword masmOpcode VRSQRT28PD VRSQRT28PS VRSQRT28SD VRSQRT28SS +syn keyword masmOpcode VGATHERPF0DPS VGATHERPF0QPS VGATHERPF0DPD +syn keyword masmOpcode VGATHERPF0QPD VGATHERPF1DPS VGATHERPF1QPS +syn keyword masmOpcode VGATHERPF1DPD VGATHERPF1QPD VSCATTERPF0DPS +syn keyword masmOpcode VSCATTERPF0QPS VSCATTERPF0DPD VSCATTERPF0QPD +syn keyword masmOpcode VSCATTERPF1DPS VSCATTERPF1QPS VSCATTERPF1DPD +syn keyword masmOpcode VSCATTERPF1QPD +syn keyword masmOpcode V4FMADDPS V4FMADDSS V4FNMADDPS V4FNMADDSS +syn keyword masmOpcode VP4DPWSSD VP4DPWSSDS +syn keyword masmOpcode VFPCLASSPS VFPCLASSPD VFPCLASSSS VFPCLASSSD +syn keyword masmOpcode VRANGEPS VRANGEPD VRANGESS VRANGESD +syn keyword masmOpcode VREDUCEPS VREDUCEPD VREDUCESS VREDUCESD +syn keyword masmOpcode VPMOVM2D VPMOVM2Q VPMOVM2B VPMOVM2W VPMOVD2M +syn keyword masmOpcode VPMOVQ2M VPMOVB2M VPMOVW2M VPMULLQ +syn keyword masmOpcode VPCOMPRESSB VPCOMPRESSW VPEXPANDB VPEXPANDW +syn keyword masmOpcode VPSHLD VPSHLDV VPSHRD VPSHRDV +syn keyword masmOpcode VPDPBUSD VPDPBUSDS VPDPWSSD VPDPWSSDS +syn keyword masmOpcode VPMADD52LUQ VPMADD52HUQ +syn keyword masmOpcode VPOPCNTD VPOPCNTQ VPOPCNTB VPOPCNTW +syn keyword masmOpcode VPSHUFBITQMB VP2INTERSECTD VP2INTERSECTQ +syn keyword masmOpcode VGF2P8AFFINEINVQB VGF2P8AFFINEQB +syn keyword masmOpcode VGF2P8MULB VPCLMULQDQ +syn keyword masmOpcode VAESDEC VAESDECLAST VAESENC VAESENCLAST +syn keyword masmOpcode VCVTNE2PS2BF16 VCVTNEPS2BF16 VDPBF16PS +syn keyword masmOpcode VADDPH VADDSH VSUBPH VSUBSH VMULPH VMULSH +syn keyword masmOpcode VDIVPH VDIVSH VSQRTPH VSQRTSH +syn keyword masmOpcode VFMADD132PH VFMADD213PH VFMADD231PH +syn keyword masmOpcode VFMADD132SH VFMADD213SH VFMADD231SH +syn keyword masmOpcode VFNMADD132PH VFNMADD213PH VFNMADD231PH +syn keyword masmOpcode VFNMADD132SH VFNMADD213SH VFNMADD231SH +syn keyword masmOpcode VFMSUB132PH VFMSUB213PH VFMSUB231PH +syn keyword masmOpcode VFMSUB132SH VFMSUB213SH VFMSUB231SH +syn keyword masmOpcode VFNMSUB132PH VFNMSUB213PH VFNMSUB231PH +syn keyword masmOpcode VFNMSUB132SH VFNMSUB213SH VFNMSUB231SH +syn keyword masmOpcode VFMADDSUB132PH VFMADDSUB213PH VFMADDSUB231PH +syn keyword masmOpcode VFMSUBADD132PH VFMSUBADD213PH VFMSUBADD231PH +syn keyword masmOpcode VREDUCEPH VREDUCESH VRNDSCALEPH VRNDSCALESH +syn keyword masmOpcode VSCALEFPH VSCALEFSH VFMULCPH VFMULCSH VFCMULCPH +syn keyword masmOpcode VFCMULCSH VFMADDCPH VFMADDCSH VFCMADDCPH +syn keyword masmOpcode VFCMADDCSH VRCPPH VRCPSH VRSQRTPH VRSQRTSH +syn keyword masmOpcode VCMPPH VCMPSH VCOMISH VUCOMISH VMAXPH VMAXSH +syn keyword masmOpcode VMINPH VMINSH VFPCLASSPH VFPCLASSSH +syn keyword masmOpcode VCVTW2PH VCVTUW2PH VCVTDQ2PH VCVTUDQ2PH +syn keyword masmOpcode VCVTQQ2PH VCVTUQQ2PH VCVTPS2PHX VCVTPD2PH +syn keyword masmOpcode VCVTSI2SH VCVTUSI2SH VCVTSS2SH VCVTSD2SH +syn keyword masmOpcode VCVTPH2W VCVTTPH2W VCVTPH2UW VCVTTPH2UW +syn keyword masmOpcode VCVTPH2DQ VCVTTPH2DQ VCVTPH2UDQ VCVTTPH2UDQ +syn keyword masmOpcode VCVTPH2QQ VCVTTPH2QQ VCVTPH2UQQ VCVTTPH2UQQ +syn keyword masmOpcode VCVTPH2PSX VCVTPH2PD VCVTSH2SI VCVTTSH2SI +syn keyword masmOpcode VCVTSH2USI VCVTTSH2USI VCVTSH2SS VCVTSH2SD +syn keyword masmOpcode VGETEXPPH VGETEXPSH VGETMANTPH VGETMANTSH +syn keyword masmOpcode VMOVSH VMOVW VADDPD VADDPS VADDSD VADDSS +syn keyword masmOpcode VANDPD VANDPS VANDNPD VANDNPS +syn keyword masmOpcode VCMPPD VCMPPS VCMPSD VCMPSS +syn keyword masmOpcode VCOMISD VCOMISS VDIVPD VDIVPS VDIVSD VDIVSS +syn keyword masmOpcode VCVTDQ2PD VCVTDQ2PS VCVTPD2DQ VCVTPD2PS +syn keyword masmOpcode VCVTPH2PS VCVTPS2PH VCVTPS2DQ VCVTPS2PD +syn keyword masmOpcode VCVTSD2SI VCVTSD2SS VCVTSI2SD VCVTSI2SS +syn keyword masmOpcode VCVTSS2SD VCVTSS2SI VCVTTPD2DQ VCVTTPS2DQ +syn keyword masmOpcode VCVTTSD2SI VCVTTSS2SI VMAXPD VMAXPS +syn keyword masmOpcode VMAXSD VMAXSS VMINPD VMINPS VMINSD VMINSS +syn keyword masmOpcode VMOVAPD VMOVAPS VMOVD VMOVQ VMOVDDUP +syn keyword masmOpcode VMOVHLPS VMOVHPD VMOVHPS VMOVLHPS VMOVLPD +syn keyword masmOpcode VMOVLPS VMOVNTDQA VMOVNTDQ VMOVNTPD VMOVNTPS +syn keyword masmOpcode VMOVSD VMOVSHDUP VMOVSLDUP VMOVSS VMOVUPD +syn keyword masmOpcode VMOVUPS VMOVDQA32 VMOVDQA64 VMOVDQU8 +syn keyword masmOpcode VMOVDQU16 VMOVDQU32 VMOVDQU64 VMULPD VMULPS +syn keyword masmOpcode VMULSD VMULSS VORPD VORPS VSQRTPD VSQRTPS +syn keyword masmOpcode VSQRTSD VSQRTSS VSUBPD VSUBPS VSUBSD VSUBSS +syn keyword masmOpcode VUCOMISD VUCOMISS VUNPCKHPD VUNPCKHPS VUNPCKLPD +syn keyword masmOpcode VUNPCKLPS VXORPD VXORPS VEXTRACTPS VINSERTPS +syn keyword masmOpcode VPEXTRB VPEXTRW VPEXTRD VPEXTRQ VPINSRB VPINSRW +syn keyword masmOpcode VPINSRD VPINSRQ VPACKSSWB VPACKSSDW VPACKUSDW +syn keyword masmOpcode VPACKUSWB VPADDB VPADDW VPADDD VPADDQ VPADDSB +syn keyword masmOpcode VPADDSW VPADDUSB VPADDUSW VPANDD VPANDQ VPANDND +syn keyword masmOpcode VPANDNQ VPAVGB VPAVGW VPCMPEQB VPCMPEQW +syn keyword masmOpcode VPCMPEQD VPCMPEQQ VPCMPGTB VPCMPGTW VPCMPGTD +syn keyword masmOpcode VPCMPGTQ VPMAXSB VPMAXSW VPMAXSD VPMAXSQ +syn keyword masmOpcode VPMAXUB VPMAXUW VPMAXUD VPMAXUQ VPMINSB VPMINSW +syn keyword masmOpcode VPMINSD VPMINSQ VPMINUB VPMINUW VPMINUD VPMINUQ +syn keyword masmOpcode VPMOVSXBW VPMOVSXBD VPMOVSXBQ VPMOVSXWD +syn keyword masmOpcode VPMOVSXWQ VPMOVSXDQ VPMOVZXBW VPMOVZXBD +syn keyword masmOpcode VPMOVZXBQ VPMOVZXWD VPMOVZXWQ VPMOVZXDQ VPMULDQ +syn keyword masmOpcode VPMULUDQ VPMULHRSW VPMULHUW VPMULHW VPMULLD +syn keyword masmOpcode VPMULLQ VPMULLW VPORD VPORQ VPSUBB VPSUBW +syn keyword masmOpcode VPSUBD VPSUBQ VPSUBSB VPSUBSW VPSUBUSB VPSUBUSW +syn keyword masmOpcode VPUNPCKHBW VPUNPCKHWD VPUNPCKHDQ VPUNPCKHQDQ +syn keyword masmOpcode VPUNPCKLBW VPUNPCKLWD VPUNPCKLDQ VPUNPCKLQDQ +syn keyword masmOpcode VPXORD VPXORQ VPSADBW VPSHUFB VPSHUFHW VPSHUFLW +syn keyword masmOpcode VPSHUFD VPSLLDQ VPSLLW VPSLLD VPSLLQ VPSRAW +syn keyword masmOpcode VPSRAD VPSRAQ VPSRLDQ VPSRLW VPSRLD VPSRLQ +syn keyword masmOpcode VPSLLVW VPSRLVW VPSHUFPD VPSHUFPS VEXTRACTF32X4 +syn keyword masmOpcode VEXTRACTF64X2 VEXTRACTF32X8 VEXTRACTF64X4 +syn keyword masmOpcode VEXTRACTI32X4 VEXTRACTI64X2 VEXTRACTI32X8 +syn keyword masmOpcode VEXTRACTI64X4 VINSERTF32x4 VINSERTF64X2 +syn keyword masmOpcode VINSERTF32X8 VINSERTF64x4 VINSERTI32X4 +syn keyword masmOpcode VINSERTI64X2 VINSERTI32X8 VINSERTI64X4 +syn keyword masmOpcode VPABSB VPABSW VPABSD VPABSQ VPALIGNR +syn keyword masmOpcode VPMADDUBSW VPMADDWD +syn keyword masmOpcode VFMADD132PD VFMADD213PD VFMADD231PD +syn keyword masmOpcode VFMADD132PS VFMADD213PS VFMADD231PS +syn keyword masmOpcode VFMADD132SD VFMADD213SD VFMADD231SD +syn keyword masmOpcode VFMADD132SS VFMADD213SS VFMADD231SS +syn keyword masmOpcode VFMADDSUB132PD VFMADDSUB213PD VFMADDSUB231PD +syn keyword masmOpcode VFMADDSUB132PS VFMADDSUB213PS VFMADDSUB231PS +syn keyword masmOpcode VFMSUBADD132PD VFMSUBADD213PD VFMSUBADD231PD +syn keyword masmOpcode VFMSUBADD132PS VFMSUBADD213PS VFMSUBADD231PS +syn keyword masmOpcode VFMSUB132PD VFMSUB213PD VFMSUB231PD +syn keyword masmOpcode VFMSUB132PS VFMSUB213PS VFMSUB231PS +syn keyword masmOpcode VFMSUB132SD VFMSUB213SD VFMSUB231SD +syn keyword masmOpcode VFMSUB132SS VFMSUB213SS VFMSUB231SS +syn keyword masmOpcode VFNMADD132PD VFNMADD213PD VFNMADD231PD +syn keyword masmOpcode VFNMADD132PS VFNMADD213PS VFNMADD231PS +syn keyword masmOpcode VFNMADD132SD VFNMADD213SD VFNMADD231SD +syn keyword masmOpcode VFNMADD132SS VFNMADD213SS VFNMADD231SS +syn keyword masmOpcode VFNMSUB132PD VFNMSUB213PD VFNMSUB231PD +syn keyword masmOpcode VFNMSUB132PS VFNMSUB213PS VFNMSUB231PS +syn keyword masmOpcode VFNMSUB132SD VFNMSUB213SD VFNMSUB231SD +syn keyword masmOpcode VFNMSUB132SS VFNMSUB213SS VFNMSUB231SS +syn keyword masmOpcode VPSRAVW VPSRAVQ + " Other opcodes in Pentium and later processors syn keyword masmOpcode CMPXCHG8B CPUID UD2 syn keyword masmOpcode RSM RDMSR WRMSR RDPMC RDTSC SYSENTER SYSEXIT syn match masmOpcode "CMOV\(P[EO]\|\(N\?\([ABGL]E\?\|[CEOPSZ]\)\)\)\>" +" Not really used by MASM, but useful for viewing GCC-generated assembly code +" in Intel syntax +syn match masmHexadecimal "[-+]\?0[Xx]\x*" +syn keyword masmOpcode MOVABS " The default highlighting hi def link masmLabel PreProc diff --git a/runtime/syntax/mojo.vim b/runtime/syntax/mojo.vim new file mode 100644 index 0000000000..b7dae24a15 --- /dev/null +++ b/runtime/syntax/mojo.vim @@ -0,0 +1,316 @@ +" Vim syntax file +" Language: Mojo +" Maintainer: Mahmoud Abduljawad +" Last Change: 2023 Sep 09 +" Credits: Mahmoud Abduljawad +" Neil Schemenauer +" Dmitry Vasiliev +" +" This is based on Vim Python highlighting +" +" - introduced highlighting of doctests +" - updated keywords, built-ins, and exceptions +" - corrected regular expressions for +" +" * functions +" * decorators +" * strings +" * escapes +" * numbers +" * space error +" +" - corrected synchronization +" - more highlighting is ON by default, except +" - space error highlighting is OFF by default +" +" Optional highlighting can be controlled using these variables. +" +" let mojo_no_builtin_highlight = 1 +" let mojo_no_doctest_code_highlight = 1 +" let mojo_no_doctest_highlight = 1 +" let mojo_no_exception_highlight = 1 +" let mojo_no_number_highlight = 1 +" let mojo_space_error_highlight = 1 +" +" All the options above can be switched on together. +" +" let mojo_highlight_all = 1 +" +" The use of Python 2 compatible syntax highlighting can be enforced. +" The straddling code (Python 2 and 3 compatible), up to Python 3.5, +" will be also supported. +" +" let mojo_use_python2_syntax = 1 +" +" This option will exclude all modern Python 3.6 or higher features. +" + +" quit when a syntax file was already loaded. +if exists("b:current_syntax") + finish +endif + +" We need nocompatible mode in order to continue lines with backslashes. +" Original setting will be restored. +let s:cpo_save = &cpo +set cpo&vim + +if exists("mojo_no_doctest_highlight") + let mojo_no_doctest_code_highlight = 1 +endif + +if exists("mojo_highlight_all") + if exists("mojo_no_builtin_highlight") + unlet mojo_no_builtin_highlight + endif + if exists("mojo_no_doctest_code_highlight") + unlet mojo_no_doctest_code_highlight + endif + if exists("mojo_no_doctest_highlight") + unlet mojo_no_doctest_highlight + endif + if exists("mojo_no_exception_highlight") + unlet mojo_no_exception_highlight + endif + if exists("mojo_no_number_highlight") + unlet mojo_no_number_highlight + endif + let mojo_space_error_highlight = 1 +endif + +" These keywords are based on Python syntax highlight, and adds to it struct, +" fn, alias, var, let +" +syn keyword mojoStatement False None True +syn keyword mojoStatement as assert break continue del global +syn keyword mojoStatement lambda nonlocal pass return with yield +syn keyword mojoStatement class def nextgroup=mojoFunction skipwhite +syn keyword mojoStatement struct fn nextgroup=mojoFunction skipwhite +syn keyword mojoStatement alias var let +syn keyword mojoConditional elif else if +syn keyword mojoRepeat for while +syn keyword mojoOperator and in is not or +syn keyword mojoException except finally raise try +syn keyword mojoInclude from import +syn keyword mojoAsync async await + +" Soft keywords +" These keywords do not mean anything unless used in the right context. +" See https://docs.python.org/3/reference/lexical_analysis.html#soft-keywords +" for more on this. +syn match mojoConditional "^\s*\zscase\%(\s\+.*:.*$\)\@=" +syn match mojoConditional "^\s*\zsmatch\%(\s\+.*:\s*\%(#.*\)\=$\)\@=" + +" Decorators +" A dot must be allowed because of @MyClass.myfunc decorators. +syn match mojoDecorator "@" display contained +syn match mojoDecoratorName "@\s*\h\%(\w\|\.\)*" display contains=pythonDecorator + +" Python 3.5 introduced the use of the same symbol for matrix multiplication: +" https://www.python.org/dev/peps/pep-0465/. We now have to exclude the +" symbol from highlighting when used in that context. +" Single line multiplication. +syn match mojoMatrixMultiply + \ "\%(\w\|[])]\)\s*@" + \ contains=ALLBUT,mojoDecoratorName,mojoDecorator,mojoFunction,mojoDoctestValue + \ transparent +" Multiplication continued on the next line after backslash. +syn match mojoMatrixMultiply + \ "[^\\]\\\s*\n\%(\s*\.\.\.\s\)\=\s\+@" + \ contains=ALLBUT,mojoDecoratorName,mojoDecorator,mojoFunction,mojoDoctestValue + \ transparent +" Multiplication in a parenthesized expression over multiple lines with @ at +" the start of each continued line; very similar to decorators and complex. +syn match mojoMatrixMultiply + \ "^\s*\%(\%(>>>\|\.\.\.\)\s\+\)\=\zs\%(\h\|\%(\h\|[[(]\).\{-}\%(\w\|[])]\)\)\s*\n\%(\s*\.\.\.\s\)\=\s\+@\%(.\{-}\n\%(\s*\.\.\.\s\)\=\s\+@\)*" + \ contains=ALLBUT,mojoDecoratorName,mojoDecorator,mojoFunction,mojoDoctestValue + \ transparent + +syn match mojoFunction "\h\w*" display contained + +syn match mojoComment "#.*$" contains=mojoTodo,@Spell +syn keyword mojoTodo FIXME NOTE NOTES TODO XXX contained + +" Triple-quoted strings can contain doctests. +syn region mojoString matchgroup=mojoQuotes + \ start=+[uU]\=\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1" + \ contains=mojoEscape,@Spell +syn region mojoString matchgroup=mojoTripleQuotes + \ start=+[uU]\=\z('''\|"""\)+ end="\z1" keepend + \ contains=mojoEscape,mojoSpaceError,mojoDoctest,@Spell +syn region mojoRawString matchgroup=mojoQuotes + \ start=+[uU]\=[rR]\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1" + \ contains=@Spell +syn region mojoRawString matchgroup=pythonTripleQuotes + \ start=+[uU]\=[rR]\z('''\|"""\)+ end="\z1" keepend + \ contains=pythonSpaceError,mojoDoctest,@Spell + +syn match mojoEscape +\\[abfnrtv'"\\]+ contained +syn match mojoEscape "\\\o\{1,3}" contained +syn match mojoEscape "\\x\x\{2}" contained +syn match mojoEscape "\%(\\u\x\{4}\|\\U\x\{8}\)" contained +" Python allows case-insensitive Unicode IDs: http://www.unicode.org/charts/ +syn match mojoEscape "\\N{\a\+\%(\s\a\+\)*}" contained +syn match mojoEscape "\\$" + +" It is very important to understand all details before changing the +" regular expressions below or their order. +" The word boundaries are *not* the floating-point number boundaries +" because of a possible leading or trailing decimal point. +" The expressions below ensure that all valid number literals are +" highlighted, and invalid number literals are not. For example, +" +" - a decimal point in '4.' at the end of a line is highlighted, +" - a second dot in 1.0.0 is not highlighted, +" - 08 is not highlighted, +" - 08e0 or 08j are highlighted, +" +" and so on, as specified in the 'Python Language Reference'. +" https://docs.python.org/reference/lexical_analysis.html#numeric-literals +if !exists("mojo_no_number_highlight") + " numbers (including complex) + syn match mojoNumber "\<0[oO]\%(_\=\o\)\+\>" + syn match mojoNumber "\<0[xX]\%(_\=\x\)\+\>" + syn match mojoNumber "\<0[bB]\%(_\=[01]\)\+\>" + syn match mojoNumber "\<\%([1-9]\%(_\=\d\)*\|0\+\%(_\=0\)*\)\>" + syn match mojoNumber "\<\d\%(_\=\d\)*[jJ]\>" + syn match mojoNumber "\<\d\%(_\=\d\)*[eE][+-]\=\d\%(_\=\d\)*[jJ]\=\>" + syn match mojoNumber + \ "\<\d\%(_\=\d\)*\.\%([eE][+-]\=\d\%(_\=\d\)*\)\=[jJ]\=\%(\W\|$\)\@=" + syn match mojoNumber + \ "\%(^\|\W\)\zs\%(\d\%(_\=\d\)*\)\=\.\d\%(_\=\d\)*\%([eE][+-]\=\d\%(_\=\d\)*\)\=[jJ]\=\>" +endif + +" The built-ins are added in the same order of appearance in Mojo stdlib docs +" https://docs.modular.com/mojo/lib.html +" +if !exists("mojo_no_builtin_highlight") + " Built-in functions + syn keyword mojoBuiltin slice constrained debug_assert put_new_line print + syn keyword mojoBuiltin print_no_newline len range rebind element_type + syn keyword mojoBuiltin ord chr atol isdigit index address string + " Built-in types + syn keyword mojoType Byte ListLiteral CoroutineContext Coroutine DType + syn keyword mojoType dtype type invalid bool int8 si8 unit8 ui8 int16 + syn keyword mojoType si16 unit16 ui16 int32 si32 uint32 ui32 int64 + syn keyword mojoType si64 uint64 ui64 bfloat16 bf16 float16 f16 float32 + syn keyword mojoType f32 float64 f64 Error FloatLiteral Int Attr SIMD + syn keyword mojoType Int8 UInt8 Int16 UInt16 Int32 UInt32 Int64 UInt64 + syn keyword mojoType Float16 Float32 Float64 element_type _65x13_type + syn keyword mojoType String StringLiteral StringRef Tuple AnyType + syn keyword mojoType NoneType None Lifetime + " avoid highlighting attributes as builtins + syn match mojoAttribute /\.\h\w*/hs=s+1 + \ contains=ALLBUT,mojoBuiltin,mojoFunction,mojoAsync + \ transparent +endif + +" From the 'Python Library Reference' class hierarchy at the bottom. +" http://docs.python.org/library/exceptions.html +if !exists("mojo_no_exception_highlight") + " builtin base exceptions (used mostly as base classes for other exceptions) + syn keyword mojoExceptions BaseException Exception + syn keyword mojoExceptions ArithmeticError BufferError LookupError + " builtin exceptions (actually raised) + syn keyword mojoExceptions AssertionError AttributeError EOFError + syn keyword mojoExceptions FloatingPointError GeneratorExit ImportError + syn keyword mojoExceptions IndentationError IndexError KeyError + syn keyword mojoExceptions KeyboardInterrupt MemoryError + syn keyword mojoExceptions ModuleNotFoundError NameError + syn keyword mojoExceptions NotImplementedError OSError OverflowError + syn keyword mojoExceptions RecursionError ReferenceError RuntimeError + syn keyword mojoExceptions StopAsyncIteration StopIteration SyntaxError + syn keyword mojoExceptions SystemError SystemExit TabError TypeError + syn keyword mojoExceptions UnboundLocalError UnicodeDecodeError + syn keyword mojoExceptions UnicodeEncodeError UnicodeError + syn keyword mojoExceptions UnicodeTranslateError ValueError + syn keyword mojoExceptions ZeroDivisionError + " builtin exception aliases for OSError + syn keyword mojoExceptions EnvironmentError IOError WindowsError + " builtin OS exceptions in Python 3 + syn keyword mojoExceptions BlockingIOError BrokenPipeError + syn keyword mojoExceptions ChildProcessError ConnectionAbortedError + syn keyword mojoExceptions ConnectionError ConnectionRefusedError + syn keyword mojoExceptions ConnectionResetError FileExistsError + syn keyword mojoExceptions FileNotFoundError InterruptedError + syn keyword mojoExceptions IsADirectoryError NotADirectoryError + syn keyword mojoExceptions PermissionError ProcessLookupError TimeoutError + " builtin warnings + syn keyword mojoExceptions BytesWarning DeprecationWarning FutureWarning + syn keyword mojoExceptions ImportWarning PendingDeprecationWarning + syn keyword mojoExceptions ResourceWarning RuntimeWarning + syn keyword mojoExceptions SyntaxWarning UnicodeWarning + syn keyword mojoExceptions UserWarning Warning +endif + +if exists("mojo_space_error_highlight") + " trailing whitespace + syn match mojoSpaceError display excludenl "\s\+$" + " mixed tabs and spaces + syn match mojoSpaceError display " \+\t" + syn match mojoSpaceError display "\t\+ " +endif + +" Do not spell doctests inside strings. +" Notice that the end of a string, either ''', or """, will end the contained +" doctest too. Thus, we do *not* need to have it as an end pattern. +if !exists("mojo_no_doctest_highlight") + if !exists("mojo_no_doctest_code_highlight") + syn region mojoDoctest + \ start="^\s*>>>\s" end="^\s*$" + \ contained contains=ALLBUT,mojoDoctest,mojoFunction,@Spell + syn region mojoDoctestValue + \ start=+^\s*\%(>>>\s\|\.\.\.\s\|"""\|'''\)\@!\S\++ end="$" + \ contained + else + syn region mojoDoctest + \ start="^\s*>>>" end="^\s*$" + \ contained contains=@NoSpell + endif +endif + +" Sync at the beginning of class, function, or method definition. +syn sync match mojoSync grouphere NONE "^\%(def\|class\)\s\+\h\w*\s*[(:]" + +" The default highlight links. Can be overridden later. +hi def link mojoStatement Statement +hi def link mojoConditional Conditional +hi def link mojoRepeat Repeat +hi def link mojoOperator Operator +hi def link mojoException Exception +hi def link mojoInclude Include +hi def link mojoAsync Statement +hi def link mojoDecorator Define +hi def link mojoDecoratorName Function +hi def link mojoFunction Function +hi def link mojoComment Comment +hi def link mojoTodo Todo +hi def link mojoString String +hi def link mojoRawString String +hi def link mojoQuotes String +hi def link mojoTripleQuotes mojoQuotes +hi def link mojoEscape Special +if !exists("mojo_no_number_highlight") + hi def link mojoNumber Number +endif +if !exists("mojo_no_builtin_highlight") + hi def link mojoBuiltin Function + hi def link mojoType Type +endif +if !exists("mojo_no_exception_highlight") + hi def link mojoExceptions Structure +endif +if exists("mojo_space_error_highlight") + hi def link mojoSpaceError Error +endif +if !exists("mojo_no_doctest_highlight") + hi def link mojoDoctest Special + hi def link mojoDoctestValue Define +endif + +let b:current_syntax = "mojo" + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim:set sw=2 sts=2 ts=8 noet: diff --git a/runtime/syntax/nasm.vim b/runtime/syntax/nasm.vim index 0eb82fad10..e1dfc1db12 100644 --- a/runtime/syntax/nasm.vim +++ b/runtime/syntax/nasm.vim @@ -8,7 +8,7 @@ " Peter Stanhope (Add missing 64-bit mode registers) " Frédéric Hamel (F16c support, partial AVX " support, other) -" Last Change: 2022 May 3 +" Last Change: 2023 Sep 7 " NASM Home: http://www.nasm.us/ @@ -250,12 +250,12 @@ syn match nasmSegRegister "\<[C-GS]S\>" syn match nasmSpcRegister "\" syn match nasmFpuRegister "\" syn match nasmMmxRegister "\" -syn match nasmSseRegister "\" +syn match nasmAvxRegister "\<[XYZ]MM\d\{1,2}\>" syn match nasmCtrlRegister "\" syn match nasmDebugRegister "\" syn match nasmTestRegister "\" syn match nasmRegisterError "\<\(CR[15-9]\|DR[4-58-9]\|TR[0-28-9]\)\>" -syn match nasmRegisterError "\" +syn match nasmRegisterError "\<[XYZ]MM\(3[2-9]\|[04-9]\d\)\>" syn match nasmRegisterError "\\)" syn match nasmRegisterError "\" " Memory reference operand (address): diff --git a/runtime/syntax/scala.vim b/runtime/syntax/scala.vim index c08e60e55a..cc098ce017 100644 --- a/runtime/syntax/scala.vim +++ b/runtime/syntax/scala.vim @@ -180,7 +180,7 @@ hi def link scalaNumber Number syn region scalaRoundBrackets start="(" end=")" skipwhite contained contains=scalaTypeDeclaration,scalaSquareBrackets,scalaRoundBrackets -syn region scalaSquareBrackets matchgroup=scalaSquareBracketsBrackets start="\[" end="\]" skipwhite nextgroup=scalaTypeExtension contains=scalaTypeDeclaration,scalaSquareBrackets,scalaTypeOperator,scalaTypeAnnotationParameter +syn region scalaSquareBrackets matchgroup=scalaSquareBracketsBrackets start="\[" end="\]" skipwhite nextgroup=scalaTypeExtension contains=scalaTypeDeclaration,scalaSquareBrackets,scalaTypeOperator,scalaTypeAnnotationParameter,scalaString syn match scalaTypeOperator /[-+=:<>]\+/ contained syn match scalaTypeAnnotationParameter /@\<[`_A-Za-z0-9$]\+\>/ contained hi def link scalaSquareBracketsBrackets Type diff --git a/src/Makefile b/src/Makefile index a44b06f75a..5b4cdff5fb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -345,7 +345,7 @@ CClink = $(CC) # --enable-gui=gtk or leave out --enable-gnome-check. # # GNOME makes sense only for GTK+ 2. Avoid use of --enable-gnome-check with -# GTK+ 3 build, as the functionality of GNOME is already incooperated into +# GTK+ 3 build, as the functionality of GNOME is already incorporated into # GTK+ 3. # # If the selected GUI isn't found, the GUI is disabled automatically diff --git a/src/drawline.c b/src/drawline.c index 6129daac1a..29feb03174 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -2011,10 +2011,8 @@ win_line( if (wlv.n_extra == 0 || (!wlv.extra_for_textprop -#ifdef FEAT_PROP_POPUP && !(text_prop_type != NULL && text_prop_flags & PT_FLAG_OVERRIDE) -#endif )) { text_prop_attr = 0; @@ -2134,7 +2132,7 @@ win_line( if (*ptr == NUL) // don't combine char attr after EOL text_prop_flags &= ~PT_FLAG_COMBINE; -#ifdef FEAT_LINEBREAK +# ifdef FEAT_LINEBREAK if (above || below || right || !wrap) { // no 'showbreak' before "below" text property @@ -2142,7 +2140,7 @@ win_line( wlv.need_showbreak = FALSE; wlv.dont_use_showbreak = TRUE; } -#endif +# endif if ((right || above || below || !wrap || padding > 0) && wp->w_width > 2) { @@ -2155,6 +2153,11 @@ win_line( // exactly the same. start_line = text_prop_position(wp, tp, wlv.vcol, +# ifdef FEAT_RIGHTLEFT + wp->w_p_rl + ? wp->w_width - wlv.col - 1 + : +# endif wlv.col, &wlv.n_extra, &wlv.p_extra, &n_attr, &wlv.n_attr_skip, diff --git a/src/errors.h b/src/errors.h index f730182900..54ca126c9a 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3521,7 +3521,7 @@ EXTERN char e_invalid_format_specifier_str[] EXTERN char e_member_str_type_mismatch_expected_str_but_got_str[] INIT(= N_("E1406: Member \"%s\": type mismatch, expected %s but got %s")); EXTERN char e_method_str_type_mismatch_expected_str_but_got_str[] - INIT(= N_("E1407: Member \"%s\": type mismatch, expected %s but got %s")); + INIT(= N_("E1407: Method \"%s\": type mismatch, expected %s but got %s")); EXTERN char e_aptypes_is_null_nr_str[] INIT(= "E1408: Internal error: ap_types or ap_types[idx] is NULL: %d: %s"); EXTERN char e_interface_static_direct_access_str[] diff --git a/src/eval.c b/src/eval.c index ec8d3baf9c..dd7b8d8f33 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1540,71 +1540,57 @@ get_lval( // round 1: class functions (skipped for an object) // round 2: object methods for (int round = v_type == VAR_OBJECT ? 2 : 1; - round <= 2; ++round) + round <= 2; ++round) { - int count = round == 1 - ? cl->class_class_function_count - : cl->class_obj_method_count; - ufunc_T **funcs = round == 1 - ? cl->class_class_functions - : cl->class_obj_methods; - for (int i = 0; i < count; ++i) + int m_idx; + ufunc_T *fp; + + fp = method_lookup(cl, + round == 1 ? VAR_CLASS : VAR_OBJECT, + key, p - key, &m_idx); + if (fp != NULL) { - ufunc_T *fp = funcs[i]; - char_u *ufname = (char_u *)fp->uf_name; - if (STRNCMP(ufname, key, p - key) == 0 - && ufname[p - key] == NUL) - { - lp->ll_ufunc = fp; - lp->ll_valtype = fp->uf_func_type; - round = 3; - break; - } + lp->ll_ufunc = fp; + lp->ll_valtype = fp->uf_func_type; + break; } } } if (lp->ll_valtype == NULL) { - int count = v_type == VAR_OBJECT - ? cl->class_obj_member_count - : cl->class_class_member_count; - ocmember_T *members = v_type == VAR_OBJECT - ? cl->class_obj_members - : cl->class_class_members; - for (int i = 0; i < count; ++i) + int m_idx; + ocmember_T *om; + + om = member_lookup(cl, v_type, key, p - key, &m_idx); + if (om != NULL) { - ocmember_T *om = members + i; - if (STRNCMP(om->ocm_name, key, p - key) == 0 - && om->ocm_name[p - key] == NUL) + switch (om->ocm_access) { - switch (om->ocm_access) - { - case VIM_ACCESS_PRIVATE: - semsg(_(e_cannot_access_private_member_str), - om->ocm_name); - return NULL; - case VIM_ACCESS_READ: - if ((flags & GLV_READ_ONLY) == 0) - { - semsg(_(e_member_is_not_writable_str), - om->ocm_name); - return NULL; - } - break; - case VIM_ACCESS_ALL: - break; - } - - lp->ll_valtype = om->ocm_type; - - if (v_type == VAR_OBJECT) - lp->ll_tv = ((typval_T *)( - lp->ll_tv->vval.v_object + 1)) + i; - else - lp->ll_tv = &cl->class_members_tv[i]; - break; + case VIM_ACCESS_PRIVATE: + semsg(_(e_cannot_access_private_member_str), + om->ocm_name); + return NULL; + case VIM_ACCESS_READ: + if ((flags & GLV_READ_ONLY) == 0) + { + semsg(_(e_member_is_not_writable_str), + om->ocm_name); + return NULL; + } + break; + case VIM_ACCESS_ALL: + break; } + + lp->ll_valtype = om->ocm_type; + + if (v_type == VAR_OBJECT) + lp->ll_tv = ((typval_T *)( + lp->ll_tv->vval.v_object + 1)) + m_idx; + else + lp->ll_tv = &cl->class_members_tv[m_idx]; + break; } } diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 566ed7dad3..3544092d65 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -2647,9 +2647,9 @@ do_ecmd( } - // End Visual mode before switching to another buffer, so the text can be - // copied into the GUI selection buffer. - // Careful: may trigger ModeChanged() autocommand + // End Visual mode before switching to another buffer, so the text can be + // copied into the GUI selection buffer. + // Careful: may trigger ModeChanged() autocommand // Should we block autocommands here? reset_VIsual(); diff --git a/src/findfile.c b/src/findfile.c index 7287b10d73..246a81898a 100644 --- a/src/findfile.c +++ b/src/findfile.c @@ -48,8 +48,8 @@ * * ATTENTION: * ========== - * Also we use an allocated search context here, this functions are NOT - * thread-safe!!!!! + * Also we use an allocated search context here, these functions are NOT + * thread-safe! * * To minimize parameter passing (or because I'm to lazy), only the * external visible functions get a search context as a parameter. This is diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index 3f0cf8c5aa..3fd6f3a904 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -4002,8 +4002,8 @@ gui_mch_init(void) } // Real windows can get focus ... GtkPlug, being a mere container can't, - // only its widgets. Arguably, this could be common code and we not use - // the window focus at all, but let's be safe. + // only its widgets. Arguably, this could be common code and we do not + // use the window focus at all, but let's be safe. if (gtk_socket_id == 0) { g_signal_connect(G_OBJECT(gui.mainwin), "focus-out-event", diff --git a/src/insexpand.c b/src/insexpand.c index 5510171034..0a0e03c8ab 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -3793,7 +3793,7 @@ ins_compl_get_exp(pos_T *ini) st.found_all = FALSE; st.ins_buf = curbuf; vim_free(st.e_cpt_copy); - // Make a copy of 'complete', if case the buffer is wiped out. + // Make a copy of 'complete', in case the buffer is wiped out. st.e_cpt_copy = vim_strsave((compl_cont_status & CONT_LOCAL) ? (char_u *)"." : curbuf->b_p_cpt); st.e_cpt = st.e_cpt_copy == NULL ? (char_u *)"" : st.e_cpt_copy; diff --git a/src/main.c b/src/main.c index cca9f31519..16a5aec924 100644 --- a/src/main.c +++ b/src/main.c @@ -1618,7 +1618,7 @@ main_loop( && !skip_term_loop) { // If terminal_loop() returns OK we got a key that is handled - // in Normal model. With FAIL we first need to position the + // in Normal mode. With FAIL we first need to position the // cursor and the screen needs to be redrawn. if (terminal_loop(TRUE) == OK) normal_cmd(&oa, TRUE); diff --git a/src/mbyte.c b/src/mbyte.c index a9603cbf2a..c4d1ddb3b8 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -4050,7 +4050,7 @@ utf_allow_break_before(int cc) 0x2021, // ‡ double dagger 0x2026, // … horizontal ellipsis 0x2030, // ‰ per mille sign - 0x2031, // ‱ per then thousand sign + 0x2031, // ‱ per ten thousand sign 0x203c, // ‼ double exclamation mark 0x2047, // ⁇ double question mark 0x2048, // ⁈ question exclamation mark diff --git a/src/mouse.c b/src/mouse.c index 056f3ea606..fd9eb87bae 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -2182,7 +2182,7 @@ retnomove: do_mousescroll_horiz(long_u leftcol) { if (curwin->w_p_wrap) - return FALSE; // no wrapping, no scrolling + return FALSE; // no horizontal scrolling when wrapping if (curwin->w_leftcol == (colnr_T)leftcol) return FALSE; // already there diff --git a/src/po/README.txt b/src/po/README.txt index 8ec1b59465..039038be71 100644 --- a/src/po/README.txt +++ b/src/po/README.txt @@ -41,7 +41,7 @@ You might have to do the commands manually. Example: WHEN THERE IS A MISTAKE If you find there is a mistake in one of the translations, please report this -to the maintainer of the translation. His/her E-mail address is in the +to the maintainer of the translation. His/her e-mail address is in the comments at the start of the file. You can also see this with the ":messages" command in Vim when the translation is being used. diff --git a/src/po/README_mingw.txt b/src/po/README_mingw.txt index a98af578ac..abb5cd7cbb 100644 --- a/src/po/README_mingw.txt +++ b/src/po/README_mingw.txt @@ -60,7 +60,7 @@ the same as in the Unix case, only the commands change): There is one special message: msgid "Messages maintainer: The Vim Project" - You should include your name and E-mail address instead, for example: + You should include your name and e-mail address instead, for example: msgstr "Berichten bersetzt bei: John Doe " (3) Clean up diff --git a/src/proto/vim9class.pro b/src/proto/vim9class.pro index 0f8aa7f1fe..a61c40f239 100644 --- a/src/proto/vim9class.pro +++ b/src/proto/vim9class.pro @@ -6,7 +6,16 @@ void ex_enum(exarg_T *eap); void ex_type(exarg_T *eap); int class_object_index(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int verbose); ufunc_T *find_class_func(char_u **arg); -int class_member_index(char_u *name, size_t len, class_T **cl_ret, cctx_T *cctx); +int class_member_idx(class_T *cl, char_u *name, size_t namelen); +ocmember_T *class_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx); +int class_method_idx(class_T *cl, char_u *name, size_t namelen); +ufunc_T *class_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx); +int object_member_idx(class_T *cl, char_u *name, size_t namelen); +ocmember_T *object_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx); +int object_method_idx(class_T *cl, char_u *name, size_t namelen); +ufunc_T *object_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx); +ocmember_T *member_lookup(class_T *cl, vartype_T v_type, char_u *name, size_t namelen, int *idx); +ufunc_T *method_lookup(class_T *cl, vartype_T v_type, char_u *name, size_t namelen, int *idx); int inside_class(cctx_T *cctx_arg, class_T *cl); void copy_object(typval_T *from, typval_T *to); void object_unref(object_T *obj); diff --git a/src/proto/vim9compile.pro b/src/proto/vim9compile.pro index 9f2263a6e9..080a2ffaaf 100644 --- a/src/proto/vim9compile.pro +++ b/src/proto/vim9compile.pro @@ -4,6 +4,8 @@ int arg_exists(char_u *name, size_t len, int *idxp, type_T **type, int *gen_load void update_script_var_block_id(char_u *name, int block_id); int script_is_vim9(void); int script_var_exists(char_u *name, size_t len, cctx_T *cctx, cstack_T *cstack); +int cctx_class_method_idx(cctx_T *cctx, char_u *name, size_t len, class_T **cl_ret); +int cctx_class_member_idx(cctx_T *cctx, char_u *name, size_t len, class_T **cl_ret); int check_defined(char_u *p, size_t len, cctx_T *cctx, cstack_T *cstack, int is_arg); int need_type_where(type_T *actual, type_T *expected, int number_ok, int offset, where_T where, cctx_T *cctx, int silent, int actual_is_const); int need_type(type_T *actual, type_T *expected, int number_ok, int offset, int arg_idx, cctx_T *cctx, int silent, int actual_is_const); diff --git a/src/sound.c b/src/sound.c index a968ecd2e0..6e949e85bc 100644 --- a/src/sound.c +++ b/src/sound.c @@ -17,7 +17,7 @@ static long sound_id = 0; -// soundcb_T is typdef'ed in proto/sound.pro +// soundcb_T is typedef'ed in proto/sound.pro struct soundcb_S { callback_T snd_callback; diff --git a/src/term.c b/src/term.c index 6a9a45daa5..8005e94759 100644 --- a/src/term.c +++ b/src/term.c @@ -6661,7 +6661,7 @@ replace_termcodes( #ifdef FEAT_EVAL /* * Change Func to K_SNR _Func. This name is used - * for script-locla user functions. + * for script-local user functions. * (room: 5 * 6 = 30 bytes; needed: 3 + + 1 <= 14) * Also change name.Func to K_SNR _Func. * Only if "name" is recognized as an import. diff --git a/src/testdir/dumps/Test_prop_below_rightleft_1.dump b/src/testdir/dumps/Test_prop_below_rightleft_1.dump new file mode 100644 index 0000000000..8718b46cf7 --- /dev/null +++ b/src/testdir/dumps/Test_prop_below_rightleft_1.dump @@ -0,0 +1,6 @@ +| +0&#ffffff0@50|e|d|c|b>a| +0#af5f00255&|1| @1 +| +0#0000000&@50|5+0#e000e06&|4|3|2|1| +0#af5f00255&@3 +| +0#4040ff13&@58|~ +| @58|~ +| @58|~ +| +0#0000000&@41|1|,|1| @10|A|l@1| diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 973ed16204..a679db4af3 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -2025,8 +2025,8 @@ endfunc " Test for BufUnload autocommand that unloads all the other buffers func Test_bufunload_all() let g:test_is_flaky = 1 - call writefile(['Test file Xxx1'], 'Xxx1', 'D')" - call writefile(['Test file Xxx2'], 'Xxx2', 'D')" + call writefile(['Test file Xxx1'], 'Xxx1', 'D') + call writefile(['Test file Xxx2'], 'Xxx2', 'D') let content =<< trim [CODE] func UnloadAllBufs() diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 6be2137c36..5a35083248 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -524,7 +524,7 @@ func Test_connect_waittime() let start = reltime() let handle = ch_open('localhost:9876', s:chopt) if ch_status(handle) != "fail" - " Oops, port does exists. + " Oops, port exists. call ch_close(handle) else let elapsed = reltime(start) @@ -538,7 +538,7 @@ func Test_connect_waittime() try let handle = ch_open('localhost:9867', {'waittime': 500}) if ch_status(handle) != "fail" - " Oops, port does exists. + " Oops, port exists. call ch_close(handle) else " Failed connection should wait about 500 msec. Can be longer if the diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim index a450684d88..b9b2c3e6c5 100644 --- a/src/testdir/test_edit.vim +++ b/src/testdir/test_edit.vim @@ -1219,7 +1219,7 @@ func Test_edit_LEFT_RIGHT() endfunc func Test_edit_MOUSE() - " This is a simple test, since we not really using the mouse here + " This is a simple test, since we're not really using the mouse here if has("gui_macvim") CheckNotGui endif @@ -1800,7 +1800,7 @@ func Test_edit_charconvert() close! set charconvert& - " 'charconvert' function doesn't create a output file + " 'charconvert' function doesn't create an output file func Cconv1() endfunc set charconvert=Cconv1() diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index 8285fa1e86..9e13777b7b 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -456,6 +456,7 @@ def s:GetFilenameChecks(): dict> mrxvtrc: ['mrxvtrc', '.mrxvtrc'], msidl: ['file.odl', 'file.mof'], msql: ['file.msql'], + mojo: ['file.mojo', 'file.🔥'], mupad: ['file.mu'], mush: ['file.mush'], muttrc: ['Muttngrc', 'Muttrc', '.muttngrc', '.muttngrc-file', '.muttrc', diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index 654d9125bf..2cc57163dd 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -300,6 +300,7 @@ endfunc func Test_strptime() CheckFunction strptime + CheckNotBSD if exists('$TZ') let tz = $TZ @@ -314,6 +315,8 @@ func Test_strptime() call assert_fails('call strptime()', 'E119:') call assert_fails('call strptime("xxx")', 'E119:') + " This fails on BSD 14 and returns + " -2209078800 instead of 0 call assert_equal(0, strptime("%Y", '')) call assert_equal(0, strptime("%Y", "xxx")) @@ -2911,7 +2914,7 @@ func Test_state() call term_sendkeys(buf, getstate) call WaitForAssert({-> assert_match('state: mSc; mode: n', term_getline(buf, 6))}, 1000) - " A operator is pending + " An operator is pending call term_sendkeys(buf, ":call RunTimer()\y") call TermWait(buf, 25) call term_sendkeys(buf, "y") diff --git a/src/testdir/test_highlight.vim b/src/testdir/test_highlight.vim index 6e39d4e3e0..af60503132 100644 --- a/src/testdir/test_highlight.vim +++ b/src/testdir/test_highlight.vim @@ -878,7 +878,7 @@ func Test_highlight_default() hi clear endfunc -" Test for 'ctermul in a highlight group +" Test for 'ctermul' in a highlight group func Test_highlight_ctermul() CheckNotGui call assert_notmatch('ctermul=', HighlightArgs('Normal')) diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim index 3ff20973a2..b7c8ad7346 100644 --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -373,7 +373,7 @@ func Test_dict_big() endtry call assert_equal('Vim(let):E716: "1500"', str) - " lookup each items + " lookup each item for i in range(1500) call assert_equal(3000 - i, d[i]) endfor diff --git a/src/testdir/test_mksession.vim b/src/testdir/test_mksession.vim index 5485e144fb..78d301f415 100644 --- a/src/testdir/test_mksession.vim +++ b/src/testdir/test_mksession.vim @@ -568,7 +568,7 @@ endfunc func Test_mkview_terminal_windows() CheckFeature terminal - " create two window on the same terminal to check this is handled OK + " create two windows on the same terminal to check this is handled OK terminal let term_buf = bufnr() exe 'sbuf ' .. term_buf diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim index efda142d1d..9111eb84a1 100644 --- a/src/testdir/test_normal.vim +++ b/src/testdir/test_normal.vim @@ -380,7 +380,7 @@ func Test_normal06_formatprg() endfunc func Test_normal07_internalfmt() - " basic test for internal formmatter to textwidth of 12 + " basic test for internal formatter to textwidth of 12 let list=range(1,11) call map(list, 'v:val." "') 10new @@ -2582,7 +2582,7 @@ func Test_normal33_g_cmd2() exe "norm! G0\4k4ly" exe "norm! gvood" call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$')) - " gv cannot be used in operator pending mode + " gv cannot be used in operator pending mode call assert_beeps('normal! cgv') " gv should beep without a previously selected visual area new diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim index 920473ddbc..b99d0e0058 100644 --- a/src/testdir/test_substitute.vim +++ b/src/testdir/test_substitute.vim @@ -1448,7 +1448,7 @@ func Test_substitute_expr_switch_win() let bufnr = bufnr('%') put ="abcdef" silent! s/\%')/\=R() - call assert_fails(':%s/./\=R()/g', 'E565') + call assert_fails(':%s/./\=R()/g', 'E565:') delfunc R exe bufnr .. "bw!" endfunc diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index 106e2e56c2..086d12c7f6 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -3087,6 +3087,23 @@ func Test_prop_with_multibyte_below() call StopVimInTerminal(buf) endfunc +func Test_prop_with_text_below_rightleft() + CheckRunVimInTerminal + CheckFeature rightleft + + let lines =<< trim END + setlocal number rightleft + call setline(1, 'abcde') + call prop_type_add('theprop', #{highlight: 'Special'}) + call prop_add(1, 0, #{type: 'theprop', text: '12345', text_align: 'below'}) + END + call writefile(lines, 'XscriptPropBelowRightleft', 'D') + let buf = RunVimInTerminal('-S XscriptPropBelowRightleft', #{rows: 6, cols: 60}) + call VerifyScreenDump(buf, 'Test_prop_below_rightleft_1', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_prop_with_text_above_empty() CheckRunVimInTerminal diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index dc5f3362b3..c793da6b48 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -4343,10 +4343,13 @@ enddef def Test_strptime() CheckFunction strptime + CheckNotBSD if exists_compiled('*strptime') v9.CheckDefAndScriptFailure(['strptime(10, "2021")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) v9.CheckDefAndScriptFailure(['strptime("%Y", 2021)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) assert_notequal(0, strptime('%Y', '2021')) + # This fails on BSD 14 and returns + # -2209078800 instead of 0 assert_equal(0, strptime('%Y', '')) endif enddef diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 9f1e91d86c..be4eb2eb8a 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -1884,7 +1884,7 @@ def Test_class_implements_interface() enddef endclass END - v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(number): string') + v9.CheckScriptFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string') lines =<< trim END vim9script @@ -1897,7 +1897,7 @@ def Test_class_implements_interface() enddef endclass END - v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(bool): bool') + v9.CheckScriptFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool') lines =<< trim END vim9script @@ -1910,7 +1910,7 @@ def Test_class_implements_interface() enddef endclass END - v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(number, ...list): bool') + v9.CheckScriptFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list): bool') # access superclass interface members from subclass, mix variable order lines =<< trim END @@ -1955,10 +1955,6 @@ def Test_class_implements_interface() enddef endclass - def F1(i: I1): list - return [ i.svar1, i.svar2 ] - enddef - def F2(i: I1): list return [ i.mvar1, i.mvar2 ] enddef @@ -1967,10 +1963,6 @@ def Test_class_implements_interface() var ob = B.new() var oc = C.new() - assert_equal([11, 12], F1(oa)) - assert_equal([21, 22], F1(ob)) - assert_equal([31, 32], F1(oc)) - assert_equal([111, 112], F2(oa)) assert_equal([121, 122], F2(ob)) assert_equal([131, 132], F2(oc)) @@ -2041,39 +2033,21 @@ def Test_class_implements_interface() enddef endclass - def F1(i: I1): list - return [ i.svar1, i.svar2 ] - enddef - def F2(i: I1): list return [ i.mvar1, i.mvar2 ] enddef - def F3(i: I2): list - return [ i.svar3, i.svar4 ] - enddef - def F4(i: I2): list return [ i.mvar3, i.mvar4 ] enddef - def F5(o: C): number - return o.svar5 - enddef - var oa = A.new() var ob = B.new() var oc = C.new() - assert_equal([[11, 12]], [F1(oa)]) - assert_equal([[21, 22], [23, 24]], [F1(ob), F3(ob)]) - assert_equal([[31, 32], [33, 34]], [F1(oc), F3(oc)]) - assert_equal([[111, 112]], [F2(oa)]) assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)]) assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)]) - - assert_equal(1001, F5(oc)) END v9.CheckScriptSuccess(lines) enddef @@ -4182,25 +4156,7 @@ def Test_static_member_access_outside_class() return 11 enddef - # access the class static through an interface argument - def F2(i: I): number - assert_equal(1, i.s_var1) - assert_equal(2, i.s_var2) - return 22 - enddef - - # access the class static through an object interface - def F3(o: C): number - assert_equal(1, o.s_var1) - assert_equal(2, o.s_var2) - assert_equal(7, o.x_static) - return 33 - enddef - assert_equal(11, F1()) - var c = C.new() - assert_equal(22, F2(c)) - assert_equal(33, F3(c)) END v9.CheckScriptSuccess(lines) enddef @@ -4250,7 +4206,7 @@ def Test_private_member_access_outside_class() enddef T() END - v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val') + v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": _val') # private static member variable lines =<< trim END @@ -4292,8 +4248,6 @@ def Test_private_member_access_outside_class() T() END v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val') - - enddef " Test for changing the member access of an interface in a implementation class @@ -4362,7 +4316,7 @@ def Test_modify_class_member_from_def_function() enddef " Test for accessing a class member variable using an object -def Test_class_member_access_using_object() +def Test_class_variable_access_using_object() var lines =<< trim END vim9script class A @@ -4374,26 +4328,74 @@ def Test_class_member_access_using_object() A.svar2->add(4) assert_equal([1, 3], A.svar1) assert_equal([2, 4], A.svar2) - var a1 = A.new() - a1.svar1->add(5) - a1.svar2->add(6) - assert_equal([1, 3, 5], a1.svar1) - assert_equal([2, 4, 6], a1.svar2) def Foo() A.svar1->add(7) A.svar2->add(8) - assert_equal([1, 3, 5, 7], A.svar1) - assert_equal([2, 4, 6, 8], A.svar2) - var a2 = A.new() - a2.svar1->add(9) - a2.svar2->add(10) - assert_equal([1, 3, 5, 7, 9], a2.svar1) - assert_equal([2, 4, 6, 8, 10], a2.svar2) + assert_equal([1, 3, 7], A.svar1) + assert_equal([2, 4, 8], A.svar2) enddef Foo() END v9.CheckScriptSuccess(lines) + + # Cannot read from a class variable using an object in script context + lines =<< trim END + vim9script + class A + public this.var1: number + public static svar2: list = [1] + endclass + + var a = A.new() + echo a.svar2 + END + v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": svar2') + + # Cannot write to a class variable using an object in script context + lines =<< trim END + vim9script + class A + public this.var1: number + public static svar2: list = [1] + endclass + + var a = A.new() + a.svar2 = [2] + END + v9.CheckScriptFailure(lines, 'E1334: Object member not found: svar2 = [2]') + + # Cannot read from a class variable using an object in def method context + lines =<< trim END + vim9script + class A + public this.var1: number + public static svar2: list = [1] + endclass + + def T() + var a = A.new() + echo a.svar2 + enddef + T() + END + v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": svar2') + + # Cannot write to a class variable using an object in def method context + lines =<< trim END + vim9script + class A + public this.var1: number + public static svar2: list = [1] + endclass + + def T() + var a = A.new() + a.svar2 = [2] + enddef + T() + END + v9.CheckScriptFailure(lines, 'E1089: Unknown variable: svar2 = [2]') enddef " Test for using a interface method using a child object @@ -4576,7 +4578,7 @@ def Test_abstract_method() enddef endclass END - v9.CheckScriptFailure(lines, 'E1407: Member "Foo": type mismatch, expected func(string, number): list but got func(number, string): list') + v9.CheckScriptFailure(lines, 'E1407: Method "Foo": type mismatch, expected func(string, number): list but got func(number, string): list') # Use an abstract class to invoke an abstract method # FIXME: This should fail @@ -4609,4 +4611,65 @@ def Test_abstract_method() v9.CheckScriptSuccess(lines) enddef +" Test for calling a class method using an object in a def function context and +" script context. +def Test_class_method_call_using_object() + # script context + var lines =<< trim END + vim9script + class A + static def Foo(): list + return ['a', 'b'] + enddef + def Bar() + assert_equal(['a', 'b'], A.Foo()) + assert_equal(['a', 'b'], Foo()) + enddef + endclass + + def T() + assert_equal(['a', 'b'], A.Foo()) + var t_a = A.new() + t_a.Bar() + enddef + + assert_equal(['a', 'b'], A.Foo()) + var a = A.new() + a.Bar() + T() + END + v9.CheckScriptSuccess(lines) + + # script context + lines =<< trim END + vim9script + class A + static def Foo(): string + return 'foo' + enddef + endclass + + var a = A.new() + assert_equal('foo', a.Foo()) + END + v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": Foo()') + + # def function context + lines =<< trim END + vim9script + class A + static def Foo(): string + return 'foo' + enddef + endclass + + def T() + var a = A.new() + assert_equal('foo', a.Foo()) + enddef + T() + END + v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": Foo()') +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim index 0fe6e7ca01..a9e10e797c 100644 --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -79,6 +79,25 @@ def Test_vim9cmd() legacy echo version END v9.CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + def Func() + var d: dict + d.k .= '' + enddef + defcompile + END + v9.CheckScriptFailure(lines, 'E985:') + lines =<< trim END + vim9script + def Func() + var d: dict + d.k ,= '' + enddef + defcompile + END + v9.CheckScriptFailure(lines, 'E1017:') enddef def Test_defcompile_fails() diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index c918bf6b12..540fd55fad 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -3067,17 +3067,13 @@ def Test_disassemble_interface_static_member() def F1(i: I) var x: number - x = i.s_var x = i.o_var - x = i.s_var2 x = i.o_var2 enddef def F2(o: C) var x: number - x = o.s_var x = o.o_var - x = o.s_var2 x = o.o_var2 enddef @@ -3087,43 +3083,27 @@ def Test_disassemble_interface_static_member() v9.CheckScriptSuccess(lines) assert_match('\d*_F1\_s*' .. 'var x: number\_s*' .. - 'x = i.s_var\_s*' .. - '0 LOAD arg\[-1\]\_s*' .. - '1 ITF_MEMBER 0 on I \[STATIC\]\_s*' .. - '2 STORE $0\_s*' .. 'x = i.o_var\_s*' .. - '3 LOAD arg\[-1\]\_s*' .. - '4 ITF_MEMBER 0 on I\_s*' .. - '5 STORE $0\_s*' .. - 'x = i.s_var2\_s*' .. - '6 LOAD arg\[-1\]\_s*' .. - '7 ITF_MEMBER 1 on I \[STATIC\]\_s*' .. - '8 STORE $0\_s*' .. + '0 LOAD arg\[-1\]\_s*' .. + '1 ITF_MEMBER 0 on I\_s*' .. + '2 STORE $0\_s*' .. 'x = i.o_var2\_s*' .. - '9 LOAD arg\[-1\]\_s*' .. - '10 ITF_MEMBER 1 on I\_s*' .. - '11 STORE $0\_s*' .. - '12 RETURN void\_s*', + '3 LOAD arg\[-1\]\_s*' .. + '4 ITF_MEMBER 1 on I\_s*' .. + '5 STORE $0\_s*' .. + '6 RETURN void\_s*', g:instr1) assert_match('\d*_F2\_s*' .. 'var x: number\_s*' .. - 'x = o.s_var\_s*' .. - '0 LOAD arg\[-1\]\_s*' .. - '1 OBJ_MEMBER 0 \[STATIC\]\_s*' .. - '2 STORE $0\_s*' .. 'x = o.o_var\_s*' .. - '3 LOAD arg\[-1\]\_s*' .. - '4 OBJ_MEMBER 0\_s*' .. - '5 STORE $0\_s*' .. - 'x = o.s_var2\_s*' .. - '6 LOAD arg\[-1\]\_s*' .. - '7 OBJ_MEMBER 1 \[STATIC\]\_s*' .. - ' 8 STORE $0\_s*' .. + '0 LOAD arg\[-1\]\_s*' .. + '1 OBJ_MEMBER 0\_s*' .. + '2 STORE $0\_s*' .. 'x = o.o_var2\_s*' .. - '9 LOAD arg\[-1\]\_s*' .. - '10 OBJ_MEMBER 1\_s*' .. - '11 STORE $0\_s*' .. - '12 RETURN void', + '3 LOAD arg\[-1\]\_s*' .. + '4 OBJ_MEMBER 1\_s*' .. + '5 STORE $0\_s*' .. + '6 RETURN void', g:instr2) unlet g:instr1 diff --git a/src/testdir/test_vimscript.vim b/src/testdir/test_vimscript.vim index 002d1153e4..0c4aedb3c6 100644 --- a/src/testdir/test_vimscript.vim +++ b/src/testdir/test_vimscript.vim @@ -3105,7 +3105,7 @@ endfunc " should be given. " " This test reuses the function MESSAGES() from the previous test. -" This functions checks the messages in g:msgfile. +" This function checks the messages in g:msgfile. "------------------------------------------------------------------------------- func Test_nested_while_error() @@ -3230,7 +3230,7 @@ endfunc " error messages should be given. " " This test reuses the function MESSAGES() from the previous test. -" This functions checks the messages in g:msgfile. +" This function checks the messages in g:msgfile. "------------------------------------------------------------------------------- func Test_nested_cont_break_error() @@ -3336,7 +3336,7 @@ endfunc " should be given. " " This test reuses the function MESSAGES() from the previous test. -" This functions checks the messages in g:msgfile. +" This function check the messages in g:msgfile. "------------------------------------------------------------------------------- func Test_nested_endtry_error() diff --git a/src/testdir/test_virtualedit.vim b/src/testdir/test_virtualedit.vim index da5f6f5c38..44c5ec8962 100644 --- a/src/testdir/test_virtualedit.vim +++ b/src/testdir/test_virtualedit.vim @@ -236,7 +236,7 @@ func Test_ve_completion() set virtualedit= endfunc -" Using "C" then then moves the last remaining character to the next +" Using "C" then moves the last remaining character to the next " line. (Mary Ellen Foster) func Test_ve_del_to_eol() new diff --git a/src/typval.c b/src/typval.c index f9f6bd6916..08dd2313f2 100644 --- a/src/typval.c +++ b/src/typval.c @@ -292,7 +292,7 @@ tv_get_number(typval_T *varp) } /* - * Like tv_get_numbe() but in Vim9 script do convert a number in a string to a + * Like tv_get_number() but in Vim9 script do convert a number in a string to a * number without giving an error. */ varnumber_T diff --git a/src/version.c b/src/version.c index e109b48de0..0ecdb7024c 100644 --- a/src/version.c +++ b/src/version.c @@ -714,6 +714,30 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1897, +/**/ + 1896, +/**/ + 1895, +/**/ + 1894, +/**/ + 1893, +/**/ + 1892, +/**/ + 1891, +/**/ + 1890, +/**/ + 1889, +/**/ + 1888, +/**/ + 1887, +/**/ + 1886, /**/ 1885, /**/ diff --git a/src/vim9.h b/src/vim9.h index e30ebda5c8..bafff94fde 100644 --- a/src/vim9.h +++ b/src/vim9.h @@ -32,7 +32,7 @@ typedef enum { ISN_SOURCE, // source autoload script, isn_arg.number is the script ID ISN_INSTR, // instructions compiled from expression - ISN_CONSTRUCT, // construct an object, using contstruct_T + ISN_CONSTRUCT, // construct an object, using construct_T ISN_GET_OBJ_MEMBER, // object member, index is isn_arg.number ISN_GET_ITF_MEMBER, // interface member, index is isn_arg.classmember ISN_STORE_THIS, // store value in "this" object member, index is diff --git a/src/vim9class.c b/src/vim9class.c index 8e2c88b14d..ccc3818385 100644 --- a/src/vim9class.c +++ b/src/vim9class.c @@ -269,14 +269,10 @@ object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl, { // TODO: Need a table for fast lookup? char_u *name = itf->class_class_members[idx].ocm_name; - for (int i = 0; i < i2c->i2c_class->class_class_member_count; ++i) - { - ocmember_T *m = &i2c->i2c_class->class_class_members[i]; - if (STRCMP(name, m->ocm_name) == 0) - { - return i; - } - } + int m_idx = class_member_idx(i2c->i2c_class, name, 0); + if (m_idx >= 0) + return m_idx; + siemsg("class %s, interface %s, static %s not found", cl->class_name, itf->class_name, name); return 0; @@ -1751,27 +1747,23 @@ class_member_type( int *member_idx, ocmember_T **p_m) { - *member_idx = -1; // not found (yet) size_t len = name_end - name; - int member_count = is_object ? cl->class_obj_member_count - : cl->class_class_member_count; - ocmember_T *members = is_object ? cl->class_obj_members - : cl->class_class_members; + ocmember_T *m; - for (int i = 0; i < member_count; ++i) + *member_idx = -1; // not found (yet) + + m = member_lookup(cl, is_object ? VAR_OBJECT : VAR_CLASS, name, len, + member_idx); + if (m == NULL) { - ocmember_T *m = members + i; - if (STRNCMP(m->ocm_name, name, len) == 0 && m->ocm_name[len] == NUL) - { - *member_idx = i; - if (p_m != NULL) - *p_m = m; - return m->ocm_type; - } + semsg(_(e_unknown_variable_str), name); + return &t_any; } - semsg(_(e_unknown_variable_str), name); - return &t_any; + if (p_m != NULL) + *p_m = m; + + return m->ocm_type; } /* @@ -1806,41 +1798,34 @@ get_member_tv( size_t namelen, typval_T *rettv) { - int member_count = is_object ? cl->class_obj_member_count - : cl->class_class_member_count; - ocmember_T *members = is_object ? cl->class_obj_members - : cl->class_class_members; + ocmember_T *m; + int m_idx; - for (int i = 0; i < member_count; ++i) + m = member_lookup(cl, is_object ? VAR_OBJECT : VAR_CLASS, name, namelen, + &m_idx); + if (m == NULL) + return FAIL; + + if (*name == '_') { - ocmember_T *m = &members[i]; - if (STRNCMP(name, m->ocm_name, namelen) == 0 - && m->ocm_name[namelen] == NUL) - { - if (*name == '_') - { - semsg(_(e_cannot_access_private_member_str), m->ocm_name); - return FAIL; - } - - // The object only contains a pointer to the class, the member - // values array follows right after that. - object_T *obj = rettv->vval.v_object; - if (is_object) - { - typval_T *tv = (typval_T *)(obj + 1) + i; - copy_tv(tv, rettv); - } - else - copy_tv(&cl->class_members_tv[i], rettv); - - object_unref(obj); - - return OK; - } + semsg(_(e_cannot_access_private_member_str), m->ocm_name); + return FAIL; } - return FAIL; + // The object only contains a pointer to the class, the member + // values array follows right after that. + object_T *obj = rettv->vval.v_object; + if (is_object) + { + typval_T *tv = (typval_T *)(obj + 1) + m_idx; + copy_tv(tv, rettv); + } + else + copy_tv(&cl->class_members_tv[m_idx], rettv); + + object_unref(obj); + + return OK; } /* @@ -1897,77 +1882,70 @@ class_object_index( if (*name_end == '(') { - int on_class = rettv->v_type == VAR_CLASS; - int count = on_class ? cl->class_class_function_count - : cl->class_obj_method_count; - for (int i = 0; i < count; ++i) + ufunc_T *fp; + + fp = method_lookup(cl, rettv->v_type, name, len, NULL); + if (fp == NULL) { - ufunc_T *fp = on_class ? cl->class_class_functions[i] - : cl->class_obj_methods[i]; - // Use a separate pointer to avoid that ASAN complains about - // uf_name[] only being 4 characters. - char_u *ufname = (char_u *)fp->uf_name; - if (STRNCMP(name, ufname, len) == 0 && ufname[len] == NUL) - { - typval_T argvars[MAX_FUNC_ARGS + 1]; - int argcount = 0; - - if (*ufname == '_') - { - // Cannot access a private method outside of a class - semsg(_(e_cannot_access_private_method_str), name); - return FAIL; - } - - char_u *argp = name_end; - int ret = get_func_arguments(&argp, evalarg, 0, - argvars, &argcount); - if (ret == FAIL) - return FAIL; - - funcexe_T funcexe; - CLEAR_FIELD(funcexe); - funcexe.fe_evaluate = TRUE; - if (rettv->v_type == VAR_OBJECT) - { - funcexe.fe_object = rettv->vval.v_object; - ++funcexe.fe_object->obj_refcount; - } - - // Clear the class or object after calling the function, in - // case the refcount is one. - typval_T tv_tofree = *rettv; - rettv->v_type = VAR_UNKNOWN; - - // Call the user function. Result goes into rettv; - int error = call_user_func_check(fp, argcount, argvars, - rettv, &funcexe, NULL); - - // Clear the previous rettv and the arguments. - clear_tv(&tv_tofree); - for (int idx = 0; idx < argcount; ++idx) - clear_tv(&argvars[idx]); - - if (error != FCERR_NONE) - { - user_func_error(error, printable_func_name(fp), - funcexe.fe_found_var); - return FAIL; - } - *arg = argp; - return OK; - } + semsg(_(e_method_not_found_on_class_str_str), cl->class_name, + name); + return FAIL; } - semsg(_(e_method_not_found_on_class_str_str), cl->class_name, name); + typval_T argvars[MAX_FUNC_ARGS + 1]; + int argcount = 0; + + if (*fp->uf_name == '_') + { + // Cannot access a private method outside of a class + semsg(_(e_cannot_access_private_method_str), name); + return FAIL; + } + + char_u *argp = name_end; + int ret = get_func_arguments(&argp, evalarg, 0, + argvars, &argcount); + if (ret == FAIL) + return FAIL; + + funcexe_T funcexe; + CLEAR_FIELD(funcexe); + funcexe.fe_evaluate = TRUE; + if (rettv->v_type == VAR_OBJECT) + { + funcexe.fe_object = rettv->vval.v_object; + ++funcexe.fe_object->obj_refcount; + } + + // Clear the class or object after calling the function, in + // case the refcount is one. + typval_T tv_tofree = *rettv; + rettv->v_type = VAR_UNKNOWN; + + // Call the user function. Result goes into rettv; + int error = call_user_func_check(fp, argcount, argvars, + rettv, &funcexe, NULL); + + // Clear the previous rettv and the arguments. + clear_tv(&tv_tofree); + for (int idx = 0; idx < argcount; ++idx) + clear_tv(&argvars[idx]); + + if (error != FCERR_NONE) + { + user_func_error(error, printable_func_name(fp), + funcexe.fe_found_var); + return FAIL; + } + *arg = argp; + return OK; } else if (rettv->v_type == VAR_OBJECT) { // Search in the object member variable table and the class member // variable table. - if (get_member_tv(cl, TRUE, name, len, rettv) == OK - || get_member_tv(cl, FALSE, name, len, rettv) == OK) + if (get_member_tv(cl, TRUE, name, len, rettv) == OK) { *arg = name_end; return OK; @@ -1978,34 +1956,34 @@ class_object_index( else if (rettv->v_type == VAR_CLASS) { + int m_idx; + // class member - for (int i = 0; i < cl->class_class_member_count; ++i) + ocmember_T *m = class_member_lookup(cl, name, len, &m_idx); + if (m == NULL) { - ocmember_T *m = &cl->class_class_members[i]; - if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL) - { - if (*name == '_') - { - semsg(_(e_cannot_access_private_member_str), m->ocm_name); - return FAIL; - } - if ((cl->class_flags & CLASS_INTERFACE) != 0) - { - semsg(_(e_interface_static_direct_access_str), - cl->class_name, m->ocm_name); - return FAIL; - } - - typval_T *tv = &cl->class_members_tv[i]; - copy_tv(tv, rettv); - class_unref(cl); - - *arg = name_end; - return OK; - } + semsg(_(e_member_not_found_on_class_str_str), cl->class_name, name); + return FAIL; } - semsg(_(e_member_not_found_on_class_str_str), cl->class_name, name); + if (*name == '_') + { + semsg(_(e_cannot_access_private_member_str), m->ocm_name); + return FAIL; + } + if ((cl->class_flags & CLASS_INTERFACE) != 0) + { + semsg(_(e_interface_static_direct_access_str), + cl->class_name, m->ocm_name); + return FAIL; + } + + typval_T *tv = &cl->class_members_tv[m_idx]; + copy_tv(tv, rettv); + class_unref(cl); + + *arg = name_end; + return OK; } return FAIL; @@ -2023,6 +2001,7 @@ find_class_func(char_u **arg) if (name_end == name || *name_end != '.') return NULL; + ufunc_T *fp = NULL; size_t len = name_end - name; typval_T tv; tv.v_type = VAR_UNKNOWN; @@ -2042,53 +2021,228 @@ find_class_func(char_u **arg) goto fail_after_eval; len = fname_end - fname; - int count = tv.v_type == VAR_CLASS ? cl->class_class_function_count - : cl->class_obj_method_count; - ufunc_T **funcs = tv.v_type == VAR_CLASS ? cl->class_class_functions - : cl->class_obj_methods; - for (int i = 0; i < count; ++i) - { - ufunc_T *fp = funcs[i]; - // Use a separate pointer to avoid that ASAN complains about - // uf_name[] only being 4 characters. - char_u *ufname = (char_u *)fp->uf_name; - if (STRNCMP(fname, ufname, len) == 0 && ufname[len] == NUL) - { - clear_tv(&tv); - return fp; - } - } + fp = method_lookup(cl, tv.v_type, fname, len, NULL); fail_after_eval: clear_tv(&tv); - return NULL; + return fp; } /* - * If "name[len]" is a class member in cctx->ctx_ufunc->uf_class return the - * index in class.class_class_members[]. - * If "cl_ret" is not NULL set it to the class. - * Otherwise return -1; + * Returns the index of class member variable "name" in the class "cl". + * Returns -1, if the variable is not found. + * If "namelen" is zero, then it is assumed that "name" is NUL terminated. */ int -class_member_index(char_u *name, size_t len, class_T **cl_ret, cctx_T *cctx) +class_member_idx(class_T *cl, char_u *name, size_t namelen) { - if (cctx == NULL || cctx->ctx_ufunc == NULL - || cctx->ctx_ufunc->uf_class == NULL) - return -1; - class_T *cl = cctx->ctx_ufunc->uf_class; + int idx; + class_member_lookup(cl, name, namelen, &idx); + return idx; +} +/* + * Returns a pointer to the class member variable "name" in the class "cl". + * Returns NULL if the variable is not found. + * The member variable index is set in "idx". + */ + ocmember_T * +class_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx) +{ + ocmember_T *ret_m = NULL; + int ret_idx = -1; for (int i = 0; i < cl->class_class_member_count; ++i) { ocmember_T *m = &cl->class_class_members[i]; - if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL) + if (namelen) { - if (cl_ret != NULL) - *cl_ret = cl; - return i; + if (STRNCMP(name, m->ocm_name, namelen) == 0 + && m->ocm_name[namelen] == NUL) + { + ret_m = m; + ret_idx = i; + break; + } + } + else if (STRCMP(name, m->ocm_name) == 0) + { + ret_m = m; + ret_idx = i; + break; } } - return -1; + if (idx != NULL) + *idx = ret_idx; + return ret_m; +} + +/* + * Returns the index of class method "name" in the class "cl". + * Returns -1, if the method is not found. + */ + int +class_method_idx(class_T *cl, char_u *name, size_t namelen) +{ + int idx; + class_method_lookup(cl, name, namelen, &idx); + return idx; +} + +/* + * Returns a pointer to the class method "name" in class "cl". + * Returns NULL if the method is not found. + * The method index is set in "idx". + */ + ufunc_T * +class_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx) +{ + ufunc_T *ret_fp = NULL; + int ret_idx = -1; + for (int i = 0; i < cl->class_class_function_count; ++i) + { + ufunc_T *fp = cl->class_class_functions[i]; + char_u *ufname = (char_u *)fp->uf_name; + if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL) + { + ret_fp = fp; + ret_idx = i; + break; + } + } + if (idx != NULL) + *idx = ret_idx; + return ret_fp; +} + +/* + * Returns the index of object member variable "name" in the class "cl". + * Returns -1, if the variable is not found. + * If "namelen" is zero, then it is assumed that "name" is NUL terminated. + */ + int +object_member_idx(class_T *cl, char_u *name, size_t namelen) +{ + int idx; + object_member_lookup(cl, name, namelen, &idx); + return idx; +} + +/* + * Returns a pointer to the object member variable "name" in the class "cl". + * Returns NULL if the variable is not found. + * The object member variable index is set in "idx". + */ + ocmember_T * +object_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx) +{ + ocmember_T *ret_m = NULL; + int ret_idx = -1; + for (int i = 0; i < cl->class_obj_member_count; ++i) + { + ocmember_T *m = &cl->class_obj_members[i]; + if (namelen) + { + if (STRNCMP(name, m->ocm_name, namelen) == 0 + && m->ocm_name[namelen] == NUL) + { + ret_m = m; + ret_idx = i; + break; + } + } + else if (STRCMP(name, m->ocm_name) == 0) + { + ret_m = m; + ret_idx = i; + break; + } + } + if (idx != NULL) + *idx = ret_idx; + return ret_m; +} + +/* + * Returns the index of object method "name" in the class "cl". + * Returns -1, if the method is not found. + */ + int +object_method_idx(class_T *cl, char_u *name, size_t namelen) +{ + int idx; + object_method_lookup(cl, name, namelen, &idx); + return idx; +} + +/* + * Returns a pointer to the object method "name" in class "cl". + * Returns NULL if the method is not found. + * The object method index is set in "idx". + */ + ufunc_T * +object_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx) +{ + ufunc_T *ret_fp = NULL; + int ret_idx = -1; + for (int i = 0; i < cl->class_obj_method_count; ++i) + { + ufunc_T *fp = cl->class_obj_methods[i]; + // Use a separate pointer to avoid that ASAN complains about + // uf_name[] only being 4 characters. + char_u *ufname = (char_u *)fp->uf_name; + if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL) + { + ret_fp = fp; + ret_idx = i; + break; + } + } + if (idx != NULL) + *idx = ret_idx; + return ret_fp; +} + +/* + * Lookup a class or object member variable by name. If v_type is VAR_CLASS, + * then lookup a class member variable and if it is VAR_OBJECT, then lookup a + * object member variable. + * + * Returns a pointer to the member variable structure if variable is found. + * Otherwise returns NULL. The member variable index is set in "*idx". + */ + ocmember_T * +member_lookup( + class_T *cl, + vartype_T v_type, + char_u *name, + size_t namelen, + int *idx) +{ + if (v_type == VAR_CLASS) + return class_member_lookup(cl, name, namelen, idx); + else + return object_member_lookup(cl, name, namelen, idx); +} + +/* + * Lookup a class or object method by name. If v_type is VAR_CLASS, then + * lookup a class method and if it is VAR_OBJECT, then lookup a object method. + * + * Returns a pointer to the method structure if variable is found. + * Otherwise returns NULL. The method variable index is set in "*idx". + */ + ufunc_T * +method_lookup( + class_T *cl, + vartype_T v_type, + char_u *name, + size_t namelen, + int *idx) +{ + if (v_type == VAR_CLASS) + return class_method_lookup(cl, name, namelen, idx); + else + return object_method_lookup(cl, name, namelen, idx); } /* diff --git a/src/vim9compile.c b/src/vim9compile.c index 5778be6e27..cc4aa46386 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -331,6 +331,62 @@ script_var_exists(char_u *name, size_t len, cctx_T *cctx, cstack_T *cstack) return FAIL; } +/* + * If "name[len]" is a class method in cctx->ctx_ufunc->uf_class return the + * class method index. + * If "cl_ret" is not NULL set it to the class. + * Otherwise return -1. + */ + int +cctx_class_method_idx( + cctx_T *cctx, + char_u *name, + size_t len, + class_T **cl_ret) +{ + if (cctx == NULL || cctx->ctx_ufunc == NULL + || cctx->ctx_ufunc->uf_class == NULL) + return -1; + + class_T *cl = cctx->ctx_ufunc->uf_class; + int m_idx = class_method_idx(cl, name, len); + if (m_idx >= 0) + { + if (cl_ret != NULL) + *cl_ret = cl; + } + + return m_idx; +} + +/* + * If "name[len]" is a class member in cctx->ctx_ufunc->uf_class return the + * class member variable index. + * If "cl_ret" is not NULL set it to the class. + * Otherwise return -1; + */ + int +cctx_class_member_idx( + cctx_T *cctx, + char_u *name, + size_t len, + class_T **cl_ret) +{ + if (cctx == NULL || cctx->ctx_ufunc == NULL + || cctx->ctx_ufunc->uf_class == NULL) + return -1; + + class_T *cl = cctx->ctx_ufunc->uf_class; + int m_idx = class_member_idx(cl, name, len); + if (m_idx >= 0) + { + if (cl_ret != NULL) + *cl_ret = cl; + } + + return m_idx; +} + /* * Return TRUE if "name" is a local variable, argument, script variable or * imported. Also if "name" is "this" and in a class method. @@ -346,7 +402,7 @@ variable_exists(char_u *name, size_t len, cctx_T *cctx) && (cctx->ctx_ufunc->uf_flags & (FC_OBJECT|FC_NEW)) && STRNCMP(name, "this", 4) == 0))) || script_var_exists(name, len, cctx, NULL) == OK - || class_member_index(name, len, NULL, cctx) >= 0 + || cctx_class_member_idx(cctx, name, len, NULL) >= 0 || find_imported(name, len, FALSE) != NULL; } @@ -393,7 +449,7 @@ check_defined( return FAIL; } - if (class_member_index(p, len, NULL, cctx) >= 0) + if (cctx_class_member_idx(cctx, p, len, NULL) >= 0) { if (is_arg) semsg(_(e_argument_already_declared_in_class_str), p); @@ -1613,12 +1669,19 @@ compile_lhs( { if (is_decl) { - semsg(_(e_variable_already_declared_str), lhs->lhs_name); + // if we come here with what looks like an assignment like .= + // but which has been reject by assignment_len() from may_compile_assignment + // give a better error message + char_u *p = skipwhite(lhs->lhs_end); + if (p[0] == '.' && p[1] == '=') + emsg(_(e_dot_equal_not_supported_with_script_version_two)); + else + semsg(_(e_variable_already_declared_str), lhs->lhs_name); return FAIL; } } - else if ((lhs->lhs_classmember_idx = class_member_index( - var_start, lhs->lhs_varlen, NULL, cctx)) >= 0) + else if ((lhs->lhs_classmember_idx = cctx_class_member_idx( + cctx, var_start, lhs->lhs_varlen, NULL)) >= 0) { if (is_decl) { diff --git a/src/vim9execute.c b/src/vim9execute.c index 4a1dd1ce20..f8e2676410 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2166,26 +2166,20 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx) class_T *cl = obj->obj_class; char_u *member = tv_idx->vval.v_string; - ocmember_T *m = NULL; - for (int i = 0; i < cl->class_obj_member_count; ++i) + int m_idx; + ocmember_T *m = object_member_lookup(cl, member, 0, &m_idx); + if (m != NULL) { - m = &cl->class_obj_members[i]; - if (STRCMP(member, m->ocm_name) == 0) + if (*member == '_') { - if (*member == '_') - { - semsg(_(e_cannot_access_private_member_str), - m->ocm_name); - status = FAIL; - } - - lidx = i; - break; + semsg(_(e_cannot_access_private_member_str), + m->ocm_name); + status = FAIL; } - m = NULL; - } - if (m == NULL) + lidx = m_idx; + } + else { semsg(_(e_member_not_found_on_object_str_str), cl->class_name, member); diff --git a/src/vim9expr.c b/src/vim9expr.c index f9756c0bba..120a606277 100644 --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -394,57 +394,32 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type) if (type->tt_type == VAR_OBJECT) { - for (int i = 0; i < cl->class_obj_member_count; ++i) + int m_idx; + ocmember_T *m = object_member_lookup(cl, name, len, &m_idx); + if (m_idx >= 0) { - ocmember_T *m = &cl->class_obj_members[i]; - if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL) + if (*name == '_' && !inside_class(cctx, cl)) { - if (*name == '_' && !inside_class(cctx, cl)) - { - semsg(_(e_cannot_access_private_member_str), m->ocm_name); - return FAIL; - } + semsg(_(e_cannot_access_private_member_str), m->ocm_name); + return FAIL; + } - *arg = name_end; - if (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED)) - return generate_GET_ITF_MEMBER(cctx, cl, i, m->ocm_type, + *arg = name_end; + if (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED)) + return generate_GET_ITF_MEMBER(cctx, cl, m_idx, m->ocm_type, FALSE); - return generate_GET_OBJ_MEMBER(cctx, i, m->ocm_type, FALSE); - } - } - - for (int i = 0; i < cl->class_class_member_count; ++i) - { - ocmember_T *m = &cl->class_class_members[i]; - if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL) - { - if (*name == '_' && !inside_class(cctx, cl)) - { - semsg(_(e_cannot_access_private_member_str), m->ocm_name); - return FAIL; - } - *arg = name_end; - if (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED)) - return generate_GET_ITF_MEMBER(cctx, cl, i, m->ocm_type, - TRUE); - return generate_GET_OBJ_MEMBER(cctx, i, m->ocm_type, TRUE); - } + return generate_GET_OBJ_MEMBER(cctx, m_idx, m->ocm_type, FALSE); } // Could be a function reference: "obj.Func". - for (int i = 0; i < cl->class_obj_method_count; ++i) + m_idx = object_method_idx(cl, name, len); + if (m_idx >= 0) { - ufunc_T *fp = cl->class_obj_methods[i]; - // Use a separate pointer to avoid that ASAN complains about - // uf_name[] only being 4 characters. - char_u *ufname = (char_u *)fp->uf_name; - if (STRNCMP(name, ufname, len) == 0 && ufname[len] == NUL) - { - if (type->tt_type == VAR_OBJECT - && (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED))) - return generate_FUNCREF(cctx, fp, cl, i, NULL); - return generate_FUNCREF(cctx, fp, NULL, 0, NULL); - } + ufunc_T *fp = cl->class_obj_methods[m_idx]; + if (type->tt_type == VAR_OBJECT + && (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED))) + return generate_FUNCREF(cctx, fp, cl, m_idx, NULL); + return generate_FUNCREF(cctx, fp, NULL, 0, NULL); } semsg(_(e_member_not_found_on_object_str_str), cl->class_name, name); @@ -453,28 +428,22 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type) { // load class member int idx; - for (idx = 0; idx < cl->class_class_member_count; ++idx) + ocmember_T *m = class_member_lookup(cl, name, len, &idx); + if (m != NULL) { - ocmember_T *m = &cl->class_class_members[idx]; - if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL) + // Note: type->tt_type = VAR_CLASS + if ((cl->class_flags & CLASS_INTERFACE) != 0) { - // Note: type->tt_type = VAR_CLASS - if ((cl->class_flags & CLASS_INTERFACE) != 0) - { - semsg(_(e_interface_static_direct_access_str), - cl->class_name, m->ocm_name); - return FAIL; - } - if (*name == '_' && !inside_class(cctx, cl)) - { - semsg(_(e_cannot_access_private_member_str), m->ocm_name); - return FAIL; - } - break; + semsg(_(e_interface_static_direct_access_str), + cl->class_name, m->ocm_name); + return FAIL; } - } - if (idx < cl->class_class_member_count) - { + if (*name == '_' && !inside_class(cctx, cl)) + { + semsg(_(e_cannot_access_private_member_str), m->ocm_name); + return FAIL; + } + *arg = name_end; return generate_CLASSMEMBER(cctx, TRUE, cl, idx); } @@ -791,8 +760,10 @@ compile_load( else gen_load = TRUE; } - else if ((idx = class_member_index(*arg, len, &cl, cctx)) >= 0) + else if ((idx = cctx_class_member_idx(cctx, *arg, len, &cl)) >= 0) { + // Referencing a class member without the class name. Infer + // the class from the def function context. res = generate_CLASSMEMBER(cctx, TRUE, cl, idx); } else @@ -1136,6 +1107,9 @@ compile_call( if (lookup_local(namebuf, varlen, NULL, cctx) == FAIL && arg_exists(namebuf, varlen, NULL, NULL, NULL, cctx) != OK) { + class_T *cl = NULL; + int mi = 0; + // If we can find the function by name generate the right call. // Skip global functions here, a local funcref takes precedence. ufunc = find_func(name, FALSE); @@ -1154,6 +1128,16 @@ compile_call( goto theend; } } + else if ((mi = cctx_class_method_idx(cctx, name, varlen, &cl)) >= 0) + { + // Class method invocation without the class name. The + // generate_CALL() function expects the class type at the top of + // the stack. So push the class type to the stack. + push_type_stack(cctx, &t_class); + res = generate_CALL(cctx, cl->class_class_functions[mi], NULL, 0, + type, argcount); + goto theend; + } } // If the name is a variable, load it and use PCALL. diff --git a/src/vim9instr.c b/src/vim9instr.c index 68fad25d51..ccec0bcc38 100644 --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -1837,17 +1837,10 @@ generate_CALL( if (class_constructor && expected->tt_type == VAR_ANY) { class_T *clp = mtype->tt_class; - char_u *aname = ((char_u **)ufunc->uf_args.ga_data)[i]; - for (int om = 0; om < clp->class_obj_member_count; ++om) - { - if (STRCMP(aname, clp->class_obj_members[om].ocm_name) - == 0) - { - expected = clp->class_obj_members[om].ocm_type; - break; - } - } - + char_u *aname = ((char_u **)ufunc->uf_args.ga_data)[i]; + ocmember_T *m = object_member_lookup(clp, aname, 0, NULL); + if (m != NULL) + expected = m->ocm_type; } } else if (ufunc->uf_va_type == NULL diff --git a/src/vim9type.c b/src/vim9type.c index 3955ce2f65..2b81c92382 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -722,7 +722,7 @@ check_typval_type(type_T *expected, typval_T *actual_tv, where_T where) { // If a type check is needed that means assigning "any" or // "unknown" to a more specific type, which fails here. - // Execpt when it looks like a lambda, since they have an + // Except when it looks like a lambda, since they have an // incomplete type. type_mismatch_where(expected, actual_type, where); res = FAIL;